1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app.admin;
18 
19 import static java.util.Objects.requireNonNull;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.SuppressLint;
24 import android.annotation.SystemApi;
25 import android.content.ComponentName;
26 import android.os.Parcel;
27 import android.os.Parcelable;
28 import android.os.PersistableBundle;
29 import android.provider.Settings;
30 import android.stats.devicepolicy.DevicePolicyEnums;
31 
32 import java.util.Locale;
33 
34 /**
35  * Params required to provision a fully managed device, see
36  * {@link DevicePolicyManager#provisionFullyManagedDevice}.
37  *
38  * @hide
39  */
40 @SystemApi
41 public final class FullyManagedDeviceProvisioningParams implements Parcelable {
42     private static final String LEAVE_ALL_SYSTEM_APPS_ENABLED_PARAM =
43             "LEAVE_ALL_SYSTEM_APPS_ENABLED";
44     private static final String CAN_DEVICE_OWNER_GRANT_SENSOR_PERMISSIONS_PARAM =
45             "CAN_DEVICE_OWNER_GRANT_SENSOR_PERMISSIONS";
46     private static final String TIME_ZONE_PROVIDED_PARAM = "TIME_ZONE_PROVIDED";
47     private static final String LOCALE_PROVIDED_PARAM = "LOCALE_PROVIDED";
48     private static final String DEMO_DEVICE = "DEMO_DEVICE";
49 
50     @NonNull private final ComponentName mDeviceAdminComponentName;
51     @NonNull private final String mOwnerName;
52     private final boolean mLeaveAllSystemAppsEnabled;
53     @Nullable private final String mTimeZone;
54     private final long mLocalTime;
55     @SuppressLint("UseIcu")
56     @Nullable private final Locale mLocale;
57     private final boolean mDeviceOwnerCanGrantSensorsPermissions;
58     @NonNull private final PersistableBundle mAdminExtras;
59     private final boolean mDemoDevice;
60 
61 
FullyManagedDeviceProvisioningParams( @onNull ComponentName deviceAdminComponentName, @NonNull String ownerName, boolean leaveAllSystemAppsEnabled, @Nullable String timeZone, long localTime, @Nullable @SuppressLint("UseIcu") Locale locale, boolean deviceOwnerCanGrantSensorsPermissions, @NonNull PersistableBundle adminExtras, boolean demoDevice)62     private FullyManagedDeviceProvisioningParams(
63             @NonNull ComponentName deviceAdminComponentName,
64             @NonNull String ownerName,
65             boolean leaveAllSystemAppsEnabled,
66             @Nullable String timeZone,
67             long localTime,
68             @Nullable @SuppressLint("UseIcu") Locale locale,
69             boolean deviceOwnerCanGrantSensorsPermissions,
70             @NonNull PersistableBundle adminExtras,
71             boolean demoDevice) {
72         this.mDeviceAdminComponentName = requireNonNull(deviceAdminComponentName);
73         this.mOwnerName = requireNonNull(ownerName);
74         this.mLeaveAllSystemAppsEnabled = leaveAllSystemAppsEnabled;
75         this.mTimeZone = timeZone;
76         this.mLocalTime = localTime;
77         this.mLocale = locale;
78         this.mDeviceOwnerCanGrantSensorsPermissions =
79                 deviceOwnerCanGrantSensorsPermissions;
80         this.mAdminExtras = adminExtras;
81         this.mDemoDevice = demoDevice;
82     }
83 
FullyManagedDeviceProvisioningParams( @onNull ComponentName deviceAdminComponentName, @NonNull String ownerName, boolean leaveAllSystemAppsEnabled, @Nullable String timeZone, long localTime, @Nullable String localeStr, boolean deviceOwnerCanGrantSensorsPermissions, @Nullable PersistableBundle adminExtras, boolean demoDevice)84     private FullyManagedDeviceProvisioningParams(
85             @NonNull ComponentName deviceAdminComponentName,
86             @NonNull String ownerName,
87             boolean leaveAllSystemAppsEnabled,
88             @Nullable String timeZone,
89             long localTime,
90             @Nullable String localeStr,
91             boolean deviceOwnerCanGrantSensorsPermissions,
92             @Nullable PersistableBundle adminExtras,
93             boolean demoDevice) {
94         this(deviceAdminComponentName,
95                 ownerName,
96                 leaveAllSystemAppsEnabled,
97                 timeZone,
98                 localTime,
99                 getLocale(localeStr),
100                 deviceOwnerCanGrantSensorsPermissions,
101                 adminExtras,
102                 demoDevice);
103     }
104 
105     @Nullable
getLocale(String localeStr)106     private static Locale getLocale(String localeStr) {
107         return localeStr == null ? null : Locale.forLanguageTag(localeStr);
108     }
109 
110     /**
111      * Returns the device owner's {@link ComponentName}.
112      */
113     @NonNull
getDeviceAdminComponentName()114     public ComponentName getDeviceAdminComponentName() {
115         return mDeviceAdminComponentName;
116     }
117 
118     /**
119      * Returns the device owner's name.
120      */
121     @NonNull
getOwnerName()122     public String getOwnerName() {
123         return mOwnerName;
124     }
125 
126     /**
127      * Returns {@code true} if system apps should be left enabled after provisioning.
128      */
isLeaveAllSystemAppsEnabled()129     public boolean isLeaveAllSystemAppsEnabled() {
130         return mLeaveAllSystemAppsEnabled;
131     }
132 
133     /**
134      * If set, it returns the time zone to set for the device after provisioning, otherwise returns
135      * {@code null};
136      */
137     @Nullable
getTimeZone()138     public String getTimeZone() {
139         return mTimeZone;
140     }
141 
142     /**
143      * If set, it returns the local time to set for the device after provisioning, otherwise returns
144      * 0.
145      */
getLocalTime()146     public long getLocalTime() {
147         return mLocalTime;
148     }
149 
150     /**
151      * If set, it returns the {@link Locale} to set for the device after provisioning, otherwise
152      * returns {@code null}.
153      */
154     @Nullable
getLocale()155     public @SuppressLint("UseIcu") Locale getLocale() {
156         return mLocale;
157     }
158 
159     /**
160      * @return true if the device owner can control sensor-related permission grants, false
161      * if the device owner has opted out of it.
162      */
canDeviceOwnerGrantSensorsPermissions()163     public boolean canDeviceOwnerGrantSensorsPermissions() {
164         return mDeviceOwnerCanGrantSensorsPermissions;
165     }
166 
167     /**
168      * Returns a copy of the admin extras bundle.
169      *
170      * @see DevicePolicyManager#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
171      */
getAdminExtras()172     public @NonNull PersistableBundle getAdminExtras() {
173         return new PersistableBundle(mAdminExtras);
174     }
175 
176     /**
177      * @return true if this device is being setup as a retail demo device, see
178      * {@link Settings.Global#DEVICE_DEMO_MODE}.
179      */
isDemoDevice()180     public boolean isDemoDevice() {
181         return mDemoDevice;
182     }
183 
184     /**
185      * Logs the provisioning params using {@link DevicePolicyEventLogger}.
186      *
187      * @hide
188      */
logParams(@onNull String callerPackage)189     public void logParams(@NonNull String callerPackage) {
190         requireNonNull(callerPackage);
191 
192         logParam(callerPackage, LEAVE_ALL_SYSTEM_APPS_ENABLED_PARAM, mLeaveAllSystemAppsEnabled);
193         logParam(callerPackage, CAN_DEVICE_OWNER_GRANT_SENSOR_PERMISSIONS_PARAM,
194                 mDeviceOwnerCanGrantSensorsPermissions);
195         logParam(callerPackage, TIME_ZONE_PROVIDED_PARAM, /* value= */ mTimeZone != null);
196         logParam(callerPackage, LOCALE_PROVIDED_PARAM, /* value= */ mLocale != null);
197         logParam(callerPackage, DEMO_DEVICE, mDemoDevice);
198     }
199 
logParam(String callerPackage, String param, boolean value)200     private void logParam(String callerPackage, String param, boolean value) {
201         DevicePolicyEventLogger
202                 .createEvent(DevicePolicyEnums.PLATFORM_PROVISIONING_PARAM)
203                 .setStrings(callerPackage)
204                 .setAdmin(mDeviceAdminComponentName)
205                 .setStrings(param)
206                 .setBoolean(value)
207                 .write();
208     }
209 
210     /**
211      * Builder class for {@link FullyManagedDeviceProvisioningParams} objects.
212      */
213     public static final class Builder {
214         @NonNull private final ComponentName mDeviceAdminComponentName;
215         @NonNull private final String mOwnerName;
216         private boolean mLeaveAllSystemAppsEnabled;
217         @Nullable private String mTimeZone;
218         private long mLocalTime;
219         @SuppressLint("UseIcu")
220         @Nullable private Locale mLocale;
221         // Default to allowing control over sensor permission grants.
222         boolean mDeviceOwnerCanGrantSensorsPermissions = true;
223         @NonNull private PersistableBundle mAdminExtras;
224         // Default is normal user devices
225         boolean mDemoDevice = false;
226 
227 
228         /**
229          * Initialize a new {@link Builder} to construct a
230          * {@link FullyManagedDeviceProvisioningParams}.
231          * <p>
232          * See {@link DevicePolicyManager#provisionFullyManagedDevice}
233          *
234          * @param deviceAdminComponentName The admin {@link ComponentName} to be set as the device
235          * owner.
236          * @param ownerName The name of the device owner.
237          *
238          * @throws NullPointerException if {@code deviceAdminComponentName} or
239          * {@code ownerName} are null.
240          */
Builder( @onNull ComponentName deviceAdminComponentName, @NonNull String ownerName)241         public Builder(
242                 @NonNull ComponentName deviceAdminComponentName, @NonNull String ownerName) {
243             this.mDeviceAdminComponentName = requireNonNull(deviceAdminComponentName);
244             this.mOwnerName = requireNonNull(ownerName);
245         }
246 
247         /**
248          * Sets whether non-required system apps should be installed on
249          * the created profile when
250          * {@link DevicePolicyManager#provisionFullyManagedDevice}
251          * is called. Defaults to {@code false} if not set.
252          */
253         @NonNull
setLeaveAllSystemAppsEnabled(boolean leaveAllSystemAppsEnabled)254         public Builder setLeaveAllSystemAppsEnabled(boolean leaveAllSystemAppsEnabled) {
255             this.mLeaveAllSystemAppsEnabled = leaveAllSystemAppsEnabled;
256             return this;
257         }
258 
259         /**
260          * Sets {@code timeZone} on the device. If not set or set to {@code null},
261          * {@link DevicePolicyManager#provisionFullyManagedDevice} will not set a timezone
262          */
263         @NonNull
setTimeZone(@ullable String timeZone)264         public Builder setTimeZone(@Nullable String timeZone) {
265             this.mTimeZone = timeZone;
266             return this;
267         }
268 
269         /**
270          * Sets {@code localTime} on the device, If not set or set to
271          * {@code 0}, {@link DevicePolicyManager#provisionFullyManagedDevice} will not set a
272          * local time.
273          */
274         @NonNull
setLocalTime(long localTime)275         public Builder setLocalTime(long localTime) {
276             this.mLocalTime = localTime;
277             return this;
278         }
279 
280         /**
281          * Sets {@link Locale} on the device, If not set or set to {@code null},
282          * {@link DevicePolicyManager#provisionFullyManagedDevice} will not set a locale.
283          */
284         @NonNull
setLocale(@uppressLint"UseIcu") @ullable Locale locale)285         public Builder setLocale(@SuppressLint("UseIcu") @Nullable Locale locale) {
286             this.mLocale = locale;
287             return this;
288         }
289 
290         /**
291          * Marks that the Device Owner may grant permissions related to device sensors.
292          * See {@link DevicePolicyManager#EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT}.
293          */
294         @NonNull
setCanDeviceOwnerGrantSensorsPermissions(boolean mayGrant)295         public Builder setCanDeviceOwnerGrantSensorsPermissions(boolean mayGrant) {
296             mDeviceOwnerCanGrantSensorsPermissions = mayGrant;
297             return this;
298         }
299 
300         /**
301          * Sets a {@link PersistableBundle} that contains admin-specific extras.
302          */
303         @NonNull
304         //TODO(b/235783053) The adminExtras parameter is actually @Nullable.
setAdminExtras(@onNull PersistableBundle adminExtras)305         public Builder setAdminExtras(@NonNull PersistableBundle adminExtras) {
306             mAdminExtras = adminExtras != null
307                     ? new PersistableBundle(adminExtras)
308                     : new PersistableBundle();
309             return this;
310         }
311 
312         /**
313          * Marks the device as a demo device, see {@link Settings.Global#DEVICE_DEMO_MODE}. The
314          * default value if unset is {@code false}.
315          */
316         @NonNull
setDemoDevice(boolean demoDevice)317         public Builder setDemoDevice(boolean demoDevice) {
318             this.mDemoDevice = demoDevice;
319             return this;
320         }
321 
322         /**
323          * Combines all of the attributes that have been set on this {@code Builder}
324          *
325          * @return a new {@link FullyManagedDeviceProvisioningParams} object.
326          */
327         @NonNull
build()328         public FullyManagedDeviceProvisioningParams build() {
329             return new FullyManagedDeviceProvisioningParams(
330                     mDeviceAdminComponentName,
331                     mOwnerName,
332                     mLeaveAllSystemAppsEnabled,
333                     mTimeZone,
334                     mLocalTime,
335                     mLocale,
336                     mDeviceOwnerCanGrantSensorsPermissions,
337                     mAdminExtras != null ? mAdminExtras : new PersistableBundle(),
338                     mDemoDevice);
339         }
340     }
341 
342     @Override
describeContents()343     public int describeContents() {
344         return 0;
345     }
346 
347     /**
348      * @hide
349      */
350     @Override
toString()351     public String toString() {
352         return "FullyManagedDeviceProvisioningParams{"
353                 + "mDeviceAdminComponentName=" + mDeviceAdminComponentName
354                 + ", mOwnerName=" + mOwnerName
355                 + ", mLeaveAllSystemAppsEnabled=" + mLeaveAllSystemAppsEnabled
356                 + ", mTimeZone=" + (mTimeZone == null ? "null" : mTimeZone)
357                 + ", mLocalTime=" + mLocalTime
358                 + ", mLocale=" + (mLocale == null ? "null" : mLocale)
359                 + ", mDeviceOwnerCanGrantSensorsPermissions="
360                 + mDeviceOwnerCanGrantSensorsPermissions
361                 + ", mAdminExtras=" + mAdminExtras
362                 + ", mDemoDevice=" + mDemoDevice
363                 + '}';
364     }
365 
366     @Override
writeToParcel(@onNull Parcel dest, @Nullable int flags)367     public void writeToParcel(@NonNull Parcel dest, @Nullable int flags) {
368         dest.writeTypedObject(mDeviceAdminComponentName, flags);
369         dest.writeString(mOwnerName);
370         dest.writeBoolean(mLeaveAllSystemAppsEnabled);
371         dest.writeString(mTimeZone);
372         dest.writeLong(mLocalTime);
373         dest.writeString(mLocale == null ? null : mLocale.toLanguageTag());
374         dest.writeBoolean(mDeviceOwnerCanGrantSensorsPermissions);
375         dest.writePersistableBundle(mAdminExtras);
376         dest.writeBoolean(mDemoDevice);
377     }
378 
379     @NonNull
380     public static final Creator<FullyManagedDeviceProvisioningParams> CREATOR =
381             new Creator<FullyManagedDeviceProvisioningParams>() {
382                 @Override
383                 public FullyManagedDeviceProvisioningParams createFromParcel(Parcel in) {
384                     ComponentName componentName = in.readTypedObject(ComponentName.CREATOR);
385                     String ownerName = in.readString();
386                     boolean leaveAllSystemAppsEnabled = in.readBoolean();
387                     String timeZone = in.readString();
388                     long localtime = in.readLong();
389                     String locale = in.readString();
390                     boolean deviceOwnerCanGrantSensorsPermissions = in.readBoolean();
391                     PersistableBundle adminExtras = in.readPersistableBundle();
392                     boolean demoDevice = in.readBoolean();
393 
394                     return new FullyManagedDeviceProvisioningParams(
395                             componentName,
396                             ownerName,
397                             leaveAllSystemAppsEnabled,
398                             timeZone,
399                             localtime,
400                             locale,
401                             deviceOwnerCanGrantSensorsPermissions,
402                             adminExtras,
403                             demoDevice);
404                 }
405 
406                 @Override
407                 public FullyManagedDeviceProvisioningParams[] newArray(int size) {
408                     return new FullyManagedDeviceProvisioningParams[size];
409                 }
410             };
411 }
412