• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME;
4 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS;
5 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
6 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
7 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
8 import static android.os.Build.VERSION_CODES.LOLLIPOP;
9 import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
10 import static android.os.Build.VERSION_CODES.M;
11 import static android.os.Build.VERSION_CODES.N;
12 import static android.os.Build.VERSION_CODES.N_MR1;
13 import static android.os.Build.VERSION_CODES.O;
14 import static android.os.Build.VERSION_CODES.P;
15 import static android.os.Build.VERSION_CODES.Q;
16 import static android.os.Build.VERSION_CODES.R;
17 import static android.os.Build.VERSION_CODES.S;
18 import static android.os.Build.VERSION_CODES.S_V2;
19 import static android.os.Build.VERSION_CODES.TIRAMISU;
20 import static org.robolectric.Shadows.shadowOf;
21 import static org.robolectric.shadow.api.Shadow.invokeConstructor;
22 import static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
23 
24 import android.accounts.Account;
25 import android.annotation.NonNull;
26 import android.annotation.Nullable;
27 import android.annotation.RequiresPermission;
28 import android.annotation.SuppressLint;
29 import android.annotation.SystemApi;
30 import android.app.ApplicationPackageManager;
31 import android.app.KeyguardManager;
32 import android.app.admin.DeviceAdminReceiver;
33 import android.app.admin.DevicePolicyManager;
34 import android.app.admin.DevicePolicyManager.NearbyStreamingPolicy;
35 import android.app.admin.DevicePolicyManager.PasswordComplexity;
36 import android.app.admin.DevicePolicyManager.UserProvisioningState;
37 import android.app.admin.IDevicePolicyManager;
38 import android.app.admin.SystemUpdatePolicy;
39 import android.content.ComponentName;
40 import android.content.Context;
41 import android.content.Intent;
42 import android.content.IntentFilter;
43 import android.content.ServiceConnection;
44 import android.content.pm.PackageInfo;
45 import android.content.pm.PackageManager;
46 import android.content.pm.PackageManager.NameNotFoundException;
47 import android.os.Build;
48 import android.os.Build.VERSION_CODES;
49 import android.os.Bundle;
50 import android.os.Handler;
51 import android.os.PersistableBundle;
52 import android.os.Process;
53 import android.os.UserHandle;
54 import android.text.TextUtils;
55 import com.android.internal.util.Preconditions;
56 import com.google.common.collect.ImmutableList;
57 import java.util.ArrayList;
58 import java.util.Arrays;
59 import java.util.Collection;
60 import java.util.Collections;
61 import java.util.HashMap;
62 import java.util.HashSet;
63 import java.util.List;
64 import java.util.Map;
65 import java.util.Objects;
66 import java.util.Set;
67 import org.robolectric.RuntimeEnvironment;
68 import org.robolectric.annotation.Implementation;
69 import org.robolectric.annotation.Implements;
70 import org.robolectric.annotation.RealObject;
71 import org.robolectric.shadow.api.Shadow;
72 
73 @Implements(DevicePolicyManager.class)
74 @SuppressLint("NewApi")
75 public class ShadowDevicePolicyManager {
76   /**
77    * @see
78    *     https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setOrganizationColor(android.content.ComponentName,
79    *     int)
80    */
81   private static final int DEFAULT_ORGANIZATION_COLOR = 0xFF008080; // teal
82 
83   private ComponentName deviceOwner;
84   private ComponentName profileOwner;
85   private List<ComponentName> deviceAdmins = new ArrayList<>();
86   private Map<Integer, String> profileOwnerNamesMap = new HashMap<>();
87   private List<String> permittedAccessibilityServices = new ArrayList<>();
88   private List<String> permittedInputMethods = new ArrayList<>();
89   private Map<String, Bundle> applicationRestrictionsMap = new HashMap<>();
90   private CharSequence organizationName;
91   private int organizationColor;
92   private boolean isAutoTimeEnabled;
93   private boolean isAutoTimeRequired;
94   private boolean isAutoTimeZoneEnabled;
95   private String timeZone;
96   private int keyguardDisabledFeatures;
97   private String lastSetPassword;
98   private int requiredPasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
99 
100   private int passwordMinimumLength;
101   private int passwordMinimumLetters = 1;
102   private int passwordMinimumLowerCase;
103   private int passwordMinimumUpperCase;
104   private int passwordMinimumNonLetter;
105   private int passwordMinimumNumeric = 1;
106   private int passwordMinimumSymbols = 1;
107   private int passwordHistoryLength = 0;
108   private long passwordExpiration = 0;
109   private long passwordExpirationTimeout = 0;
110   private int maximumFailedPasswordsForWipe = 0;
111   private long maximumTimeToLock = 0;
112   private boolean cameraDisabled;
113   private boolean isActivePasswordSufficient;
114   private boolean isUniqueDeviceAttestationSupported;
115   @PasswordComplexity private int passwordComplexity;
116 
117   private int wipeCalled;
118   private int storageEncryptionStatus;
119   private int permissionPolicy;
120   private boolean storageEncryptionRequested;
121   private final Set<String> wasHiddenPackages = new HashSet<>();
122   private final Set<String> accountTypesWithManagementDisabled = new HashSet<>();
123   private final Set<String> systemAppsEnabled = new HashSet<>();
124   private final Set<String> uninstallBlockedPackages = new HashSet<>();
125   private final Set<String> suspendedPackages = new HashSet<>();
126   private final Set<String> affiliationIds = new HashSet<>();
127   private final Map<PackageAndPermission, Boolean> appPermissionGrantedMap = new HashMap<>();
128   private final Map<PackageAndPermission, Integer> appPermissionGrantStateMap = new HashMap<>();
129   private final Map<ComponentName, byte[]> passwordResetTokens = new HashMap<>();
130   private final Map<ComponentName, Set<Integer>> adminPolicyGrantedMap = new HashMap<>();
131   private final Map<ComponentName, CharSequence> shortSupportMessageMap = new HashMap<>();
132   private final Map<ComponentName, CharSequence> longSupportMessageMap = new HashMap<>();
133   private final Set<ComponentName> componentsWithActivatedTokens = new HashSet<>();
134   private Collection<String> packagesToFailForSetApplicationHidden = Collections.emptySet();
135   private int lockTaskFeatures;
136   private final List<String> lockTaskPackages = new ArrayList<>();
137   private Context context;
138   private ApplicationPackageManager applicationPackageManager;
139   private SystemUpdatePolicy policy;
140   private List<UserHandle> bindDeviceAdminTargetUsers = ImmutableList.of();
141   private boolean isDeviceProvisioned;
142   private boolean isDeviceProvisioningConfigApplied;
143   private volatile boolean organizationOwnedDeviceWithManagedProfile = false;
144   private int nearbyNotificationStreamingPolicy =
145       DevicePolicyManager.NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY;
146   private int nearbyAppStreamingPolicy =
147       DevicePolicyManager.NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY;
148   private boolean isUsbDataSignalingEnabled = true;
149   @Nullable private String devicePolicyManagementRoleHolderPackage;
150   private final Map<UserHandle, Account> finalizedWorkProfileProvisioningMap = new HashMap<>();
151   private List<UserHandle> policyManagedProfiles = new ArrayList<>();
152   private final Map<Integer, Integer> userProvisioningStatesMap = new HashMap<>();
153   @Nullable private PersistableBundle lastTransferOwnershipBundle;
154 
155   private @RealObject DevicePolicyManager realObject;
156 
157   private static class PackageAndPermission {
158 
PackageAndPermission(String packageName, String permission)159     public PackageAndPermission(String packageName, String permission) {
160       this.packageName = packageName;
161       this.permission = permission;
162     }
163 
164     private String packageName;
165     private String permission;
166 
167     @Override
equals(Object o)168     public boolean equals(Object o) {
169       if (!(o instanceof PackageAndPermission)) {
170         return false;
171       }
172       PackageAndPermission other = (PackageAndPermission) o;
173       return packageName.equals(other.packageName) && permission.equals(other.permission);
174     }
175 
176     @Override
hashCode()177     public int hashCode() {
178       int result = packageName.hashCode();
179       result = 31 * result + permission.hashCode();
180       return result;
181     }
182   }
183 
184   @Implementation(maxSdk = M)
__constructor__(Context context, Handler handler)185   protected void __constructor__(Context context, Handler handler) {
186     init(context);
187     invokeConstructor(
188         DevicePolicyManager.class,
189         realObject,
190         from(Context.class, context),
191         from(Handler.class, handler));
192   }
193 
194   @Implementation(minSdk = N, maxSdk = N_MR1)
__constructor__(Context context, boolean parentInstance)195   protected void __constructor__(Context context, boolean parentInstance) {
196     init(context);
197   }
198 
199   @Implementation(minSdk = O)
__constructor__(Context context, IDevicePolicyManager service)200   protected void __constructor__(Context context, IDevicePolicyManager service) {
201     init(context);
202   }
203 
init(Context context)204   private void init(Context context) {
205     this.context = context;
206     this.applicationPackageManager =
207         (ApplicationPackageManager) context.getApplicationContext().getPackageManager();
208     organizationColor = DEFAULT_ORGANIZATION_COLOR;
209     storageEncryptionStatus = DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
210   }
211 
212   @Implementation(minSdk = JELLY_BEAN_MR2)
isDeviceOwnerApp(String packageName)213   protected boolean isDeviceOwnerApp(String packageName) {
214     return deviceOwner != null && deviceOwner.getPackageName().equals(packageName);
215   }
216 
217   @Implementation(minSdk = LOLLIPOP)
isProfileOwnerApp(String packageName)218   protected boolean isProfileOwnerApp(String packageName) {
219     return profileOwner != null && profileOwner.getPackageName().equals(packageName);
220   }
221 
222   @Implementation
isAdminActive(ComponentName who)223   protected boolean isAdminActive(ComponentName who) {
224     return who != null && deviceAdmins.contains(who);
225   }
226 
227   @Implementation
getActiveAdmins()228   protected List<ComponentName> getActiveAdmins() {
229     return deviceAdmins;
230   }
231 
232   @Implementation(minSdk = LOLLIPOP)
addUserRestriction(ComponentName admin, String key)233   protected void addUserRestriction(ComponentName admin, String key) {
234     enforceActiveAdmin(admin);
235     getShadowUserManager().setUserRestriction(Process.myUserHandle(), key, true);
236   }
237 
238   @Implementation(minSdk = LOLLIPOP)
clearUserRestriction(ComponentName admin, String key)239   protected void clearUserRestriction(ComponentName admin, String key) {
240     enforceActiveAdmin(admin);
241     getShadowUserManager().setUserRestriction(Process.myUserHandle(), key, false);
242   }
243 
244   @Implementation(minSdk = LOLLIPOP)
setApplicationHidden(ComponentName admin, String packageName, boolean hidden)245   protected boolean setApplicationHidden(ComponentName admin, String packageName, boolean hidden) {
246     enforceActiveAdmin(admin);
247     if (packagesToFailForSetApplicationHidden.contains(packageName)) {
248       return false;
249     }
250     if (hidden) {
251       wasHiddenPackages.add(packageName);
252     }
253     return applicationPackageManager.setApplicationHiddenSettingAsUser(
254         packageName, hidden, Process.myUserHandle());
255   }
256 
257   /**
258    * Set package names for witch {@link DevicePolicyManager#setApplicationHidden} should fail.
259    *
260    * @param packagesToFail collection of package names or {@code null} to clear the packages.
261    */
failSetApplicationHiddenFor(Collection<String> packagesToFail)262   public void failSetApplicationHiddenFor(Collection<String> packagesToFail) {
263     if (packagesToFail == null) {
264       packagesToFail = Collections.emptySet();
265     }
266     packagesToFailForSetApplicationHidden = packagesToFail;
267   }
268 
269   @Implementation(minSdk = LOLLIPOP)
isApplicationHidden(ComponentName admin, String packageName)270   protected boolean isApplicationHidden(ComponentName admin, String packageName) {
271     enforceActiveAdmin(admin);
272     return applicationPackageManager.getApplicationHiddenSettingAsUser(
273         packageName, Process.myUserHandle());
274   }
275 
276   /** Returns {@code true} if the given {@code packageName} was ever hidden. */
wasPackageEverHidden(String packageName)277   public boolean wasPackageEverHidden(String packageName) {
278     return wasHiddenPackages.contains(packageName);
279   }
280 
281   @Implementation(minSdk = LOLLIPOP)
enableSystemApp(ComponentName admin, String packageName)282   protected void enableSystemApp(ComponentName admin, String packageName) {
283     enforceActiveAdmin(admin);
284     systemAppsEnabled.add(packageName);
285   }
286 
287   /** Returns {@code true} if the given {@code packageName} was a system app and was enabled. */
wasSystemAppEnabled(String packageName)288   public boolean wasSystemAppEnabled(String packageName) {
289     return systemAppsEnabled.contains(packageName);
290   }
291 
292   @Implementation(minSdk = LOLLIPOP)
setUninstallBlocked( ComponentName admin, String packageName, boolean uninstallBlocked)293   protected void setUninstallBlocked(
294       ComponentName admin, String packageName, boolean uninstallBlocked) {
295     enforceActiveAdmin(admin);
296     if (uninstallBlocked) {
297       uninstallBlockedPackages.add(packageName);
298     } else {
299       uninstallBlockedPackages.remove(packageName);
300     }
301   }
302 
303   @Implementation(minSdk = LOLLIPOP)
isUninstallBlocked(@ullable ComponentName admin, String packageName)304   protected boolean isUninstallBlocked(@Nullable ComponentName admin, String packageName) {
305     if (admin == null) {
306       // Starting from LOLLIPOP_MR1, the behavior of this API is changed such that passing null as
307       // the admin parameter will return if any admin has blocked the uninstallation. Before L MR1,
308       // passing null will cause a NullPointerException to be raised.
309       if (Build.VERSION.SDK_INT < LOLLIPOP_MR1) {
310         throw new NullPointerException("ComponentName is null");
311       }
312     } else {
313       enforceActiveAdmin(admin);
314     }
315     return uninstallBlockedPackages.contains(packageName);
316   }
317 
setIsUniqueDeviceAttestationSupported(boolean supported)318   public void setIsUniqueDeviceAttestationSupported(boolean supported) {
319     isUniqueDeviceAttestationSupported = supported;
320   }
321 
322   @Implementation(minSdk = R)
isUniqueDeviceAttestationSupported()323   protected boolean isUniqueDeviceAttestationSupported() {
324     return isUniqueDeviceAttestationSupported;
325   }
326 
327   /** Sets USB signaling device restriction. */
setIsUsbDataSignalingEnabled(boolean isEnabled)328   public void setIsUsbDataSignalingEnabled(boolean isEnabled) {
329     isUsbDataSignalingEnabled = isEnabled;
330   }
331 
332   @Implementation(minSdk = S)
isUsbDataSignalingEnabled()333   protected boolean isUsbDataSignalingEnabled() {
334     return isUsbDataSignalingEnabled;
335   }
336 
337   /**
338    * @see #setDeviceOwner(ComponentName)
339    */
340   @Implementation(minSdk = JELLY_BEAN_MR2)
getDeviceOwner()341   protected String getDeviceOwner() {
342     return deviceOwner != null ? deviceOwner.getPackageName() : null;
343   }
344 
345   /**
346    * @see #setDeviceOwner(ComponentName)
347    */
348   @Implementation(minSdk = N)
isDeviceManaged()349   public boolean isDeviceManaged() {
350     return getDeviceOwner() != null;
351   }
352 
353   /**
354    * @see #setProfileOwner(ComponentName)
355    */
356   @Implementation(minSdk = LOLLIPOP)
getProfileOwner()357   protected ComponentName getProfileOwner() {
358     return profileOwner;
359   }
360 
361   /**
362    * Returns the human-readable name of the profile owner for a user if set using {@link
363    * #setProfileOwnerName}, otherwise null.
364    */
365   @Implementation(minSdk = LOLLIPOP)
getProfileOwnerNameAsUser(int userId)366   protected String getProfileOwnerNameAsUser(int userId) {
367     return profileOwnerNamesMap.get(userId);
368   }
369 
370   @Implementation(minSdk = P)
transferOwnership( ComponentName admin, ComponentName target, @Nullable PersistableBundle bundle)371   protected void transferOwnership(
372       ComponentName admin, ComponentName target, @Nullable PersistableBundle bundle) {
373     Objects.requireNonNull(admin, "ComponentName is null");
374     Objects.requireNonNull(target, "Target cannot be null.");
375     Preconditions.checkArgument(
376         !admin.equals(target), "Provided administrator and target are the same object.");
377     Preconditions.checkArgument(
378         !admin.getPackageName().equals(target.getPackageName()),
379         "Provided administrator and target have the same package name.");
380     try {
381       context.getPackageManager().getReceiverInfo(target, 0);
382     } catch (PackageManager.NameNotFoundException e) {
383       throw new IllegalArgumentException("Unknown admin: " + target);
384     }
385     if (admin.equals(deviceOwner)) {
386       deviceOwner = target;
387     } else if (admin.equals(profileOwner)) {
388       profileOwner = target;
389     } else {
390       throw new SecurityException("Calling identity is not authorized");
391     }
392     lastTransferOwnershipBundle = bundle;
393   }
394 
395   @Implementation(minSdk = P)
396   @Nullable
getTransferOwnershipBundle()397   protected PersistableBundle getTransferOwnershipBundle() {
398     return lastTransferOwnershipBundle;
399   }
400 
getShadowUserManager()401   private ShadowUserManager getShadowUserManager() {
402     return Shadow.extract(context.getSystemService(Context.USER_SERVICE));
403   }
404 
405   /**
406    * Sets the admin as active admin and device owner.
407    *
408    * @see DevicePolicyManager#getDeviceOwner()
409    */
410   @Implementation(minSdk = N, maxSdk = S_V2)
setDeviceOwner(ComponentName admin)411   public boolean setDeviceOwner(ComponentName admin) {
412     setActiveAdmin(admin);
413     deviceOwner = admin;
414     return true;
415   }
416 
417   /**
418    * Sets the admin as active admin and profile owner.
419    *
420    * @see DevicePolicyManager#getProfileOwner()
421    */
setProfileOwner(ComponentName admin)422   public void setProfileOwner(ComponentName admin) {
423     setActiveAdmin(admin);
424     profileOwner = admin;
425   }
426 
setProfileOwnerName(int userId, String name)427   public void setProfileOwnerName(int userId, String name) {
428     profileOwnerNamesMap.put(userId, name);
429   }
430 
431   /** Sets the given {@code componentName} as one of the active admins. */
setActiveAdmin(ComponentName componentName)432   public void setActiveAdmin(ComponentName componentName) {
433     deviceAdmins.add(componentName);
434   }
435 
436   @Implementation
removeActiveAdmin(ComponentName admin)437   protected void removeActiveAdmin(ComponentName admin) {
438     deviceAdmins.remove(admin);
439   }
440 
441   @Implementation(minSdk = LOLLIPOP)
clearProfileOwner(ComponentName admin)442   protected void clearProfileOwner(ComponentName admin) {
443     profileOwner = null;
444     lastTransferOwnershipBundle = null;
445     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
446       removeActiveAdmin(admin);
447     }
448   }
449 
450   @Implementation(minSdk = LOLLIPOP)
getApplicationRestrictions(ComponentName admin, String packageName)451   protected Bundle getApplicationRestrictions(ComponentName admin, String packageName) {
452     enforceDeviceOwnerOrProfileOwner(admin);
453     return getApplicationRestrictions(packageName);
454   }
455 
456   /** Returns all application restrictions of the {@code packageName} in a {@link Bundle}. */
getApplicationRestrictions(String packageName)457   public Bundle getApplicationRestrictions(String packageName) {
458     Bundle bundle = applicationRestrictionsMap.get(packageName);
459     // If no restrictions were saved, DPM method should return an empty Bundle as per JavaDoc.
460     return bundle != null ? new Bundle(bundle) : new Bundle();
461   }
462 
463   @Implementation(minSdk = LOLLIPOP)
setApplicationRestrictions( ComponentName admin, String packageName, Bundle applicationRestrictions)464   protected void setApplicationRestrictions(
465       ComponentName admin, String packageName, Bundle applicationRestrictions) {
466     enforceDeviceOwnerOrProfileOwner(admin);
467     setApplicationRestrictions(packageName, applicationRestrictions);
468   }
469 
470   /**
471    * Sets the application restrictions of the {@code packageName}.
472    *
473    * <p>The new {@code applicationRestrictions} always completely overwrites any existing ones.
474    */
setApplicationRestrictions(String packageName, Bundle applicationRestrictions)475   public void setApplicationRestrictions(String packageName, Bundle applicationRestrictions) {
476     applicationRestrictionsMap.put(packageName, new Bundle(applicationRestrictions));
477   }
478 
enforceProfileOwner(ComponentName admin)479   private void enforceProfileOwner(ComponentName admin) {
480     if (!admin.equals(profileOwner)) {
481       throw new SecurityException("[" + admin + "] is not a profile owner");
482     }
483   }
484 
enforceDeviceOwnerOrProfileOwner(ComponentName admin)485   private void enforceDeviceOwnerOrProfileOwner(ComponentName admin) {
486     if (!admin.equals(deviceOwner) && !admin.equals(profileOwner)) {
487       throw new SecurityException("[" + admin + "] is neither a device owner nor a profile owner.");
488     }
489   }
490 
enforceActiveAdmin(ComponentName admin)491   private void enforceActiveAdmin(ComponentName admin) {
492     if (!deviceAdmins.contains(admin)) {
493       throw new SecurityException("[" + admin + "] is not an active device admin");
494     }
495   }
496 
497   @Implementation(minSdk = LOLLIPOP)
setAccountManagementDisabled( ComponentName admin, String accountType, boolean disabled)498   protected void setAccountManagementDisabled(
499       ComponentName admin, String accountType, boolean disabled) {
500     enforceDeviceOwnerOrProfileOwner(admin);
501     if (disabled) {
502       accountTypesWithManagementDisabled.add(accountType);
503     } else {
504       accountTypesWithManagementDisabled.remove(accountType);
505     }
506   }
507 
508   @Implementation(minSdk = LOLLIPOP)
getAccountTypesWithManagementDisabled()509   protected String[] getAccountTypesWithManagementDisabled() {
510     return accountTypesWithManagementDisabled.toArray(new String[0]);
511   }
512 
513   /**
514    * Sets organization name.
515    *
516    * <p>The API can only be called by profile owner since Android N and can be called by both of
517    * profile owner and device owner since Android O.
518    */
519   @Implementation(minSdk = N)
setOrganizationName(ComponentName admin, @Nullable CharSequence name)520   protected void setOrganizationName(ComponentName admin, @Nullable CharSequence name) {
521     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
522       enforceDeviceOwnerOrProfileOwner(admin);
523     } else {
524       enforceProfileOwner(admin);
525     }
526 
527     if (TextUtils.isEmpty(name)) {
528       organizationName = null;
529     } else {
530       organizationName = name;
531     }
532   }
533 
534   @Implementation(minSdk = N)
setPackagesSuspended( ComponentName admin, String[] packageNames, boolean suspended)535   protected String[] setPackagesSuspended(
536       ComponentName admin, String[] packageNames, boolean suspended) {
537     if (admin != null) {
538       enforceDeviceOwnerOrProfileOwner(admin);
539     }
540     if (packageNames == null) {
541       throw new NullPointerException("package names cannot be null");
542     }
543     PackageManager pm = context.getPackageManager();
544     ArrayList<String> packagesFailedToSuspend = new ArrayList<>();
545     for (String packageName : packageNames) {
546       try {
547         // check if it is installed
548         pm.getPackageInfo(packageName, 0);
549         if (suspended) {
550           suspendedPackages.add(packageName);
551         } else {
552           suspendedPackages.remove(packageName);
553         }
554       } catch (NameNotFoundException e) {
555         packagesFailedToSuspend.add(packageName);
556       }
557     }
558     return packagesFailedToSuspend.toArray(new String[0]);
559   }
560 
561   @Implementation(minSdk = N)
isPackageSuspended(ComponentName admin, String packageName)562   protected boolean isPackageSuspended(ComponentName admin, String packageName)
563       throws NameNotFoundException {
564     if (admin != null) {
565       enforceDeviceOwnerOrProfileOwner(admin);
566     }
567     // Throws NameNotFoundException
568     context.getPackageManager().getPackageInfo(packageName, 0);
569     return suspendedPackages.contains(packageName);
570   }
571 
572   @Implementation(minSdk = N)
setOrganizationColor(ComponentName admin, int color)573   protected void setOrganizationColor(ComponentName admin, int color) {
574     enforceProfileOwner(admin);
575     organizationColor = color;
576   }
577 
578   /**
579    * Returns organization name.
580    *
581    * <p>The API can only be called by profile owner since Android N.
582    *
583    * <p>Android framework has a hidden API for getting the organization name for device owner since
584    * Android O. This method, however, is extended to return the organization name for device owners
585    * too to make testing of {@link #setOrganizationName(ComponentName, CharSequence)} easier for
586    * device owner cases.
587    */
588   @Implementation(minSdk = N)
589   @Nullable
getOrganizationName(ComponentName admin)590   protected CharSequence getOrganizationName(ComponentName admin) {
591     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
592       enforceDeviceOwnerOrProfileOwner(admin);
593     } else {
594       enforceProfileOwner(admin);
595     }
596 
597     return organizationName;
598   }
599 
600   @Implementation(minSdk = N)
getOrganizationColor(ComponentName admin)601   protected int getOrganizationColor(ComponentName admin) {
602     enforceProfileOwner(admin);
603     return organizationColor;
604   }
605 
606   @Implementation(minSdk = R)
setAutoTimeEnabled(ComponentName admin, boolean enabled)607   protected void setAutoTimeEnabled(ComponentName admin, boolean enabled) {
608     enforceDeviceOwnerOrProfileOwner(admin);
609     isAutoTimeEnabled = enabled;
610   }
611 
612   @Implementation(minSdk = R)
getAutoTimeEnabled(ComponentName admin)613   protected boolean getAutoTimeEnabled(ComponentName admin) {
614     enforceDeviceOwnerOrProfileOwner(admin);
615     return isAutoTimeEnabled;
616   }
617 
618   @Implementation(minSdk = LOLLIPOP)
setAutoTimeRequired(ComponentName admin, boolean required)619   protected void setAutoTimeRequired(ComponentName admin, boolean required) {
620     enforceDeviceOwnerOrProfileOwner(admin);
621     isAutoTimeRequired = required;
622   }
623 
624   @Implementation(minSdk = LOLLIPOP)
getAutoTimeRequired()625   protected boolean getAutoTimeRequired() {
626     return isAutoTimeRequired;
627   }
628 
629   @Implementation(minSdk = R)
setAutoTimeZoneEnabled(ComponentName admin, boolean enabled)630   protected void setAutoTimeZoneEnabled(ComponentName admin, boolean enabled) {
631     enforceDeviceOwnerOrProfileOwner(admin);
632     isAutoTimeZoneEnabled = enabled;
633   }
634 
635   @Implementation(minSdk = R)
getAutoTimeZoneEnabled(ComponentName admin)636   protected boolean getAutoTimeZoneEnabled(ComponentName admin) {
637     enforceDeviceOwnerOrProfileOwner(admin);
638     return isAutoTimeZoneEnabled;
639   }
640 
641   @Implementation(minSdk = P)
setTimeZone(ComponentName admin, String timeZone)642   protected boolean setTimeZone(ComponentName admin, String timeZone) {
643     enforceDeviceOwnerOrProfileOwner(admin);
644     if (isAutoTimeZoneEnabled) {
645       return false;
646     }
647     this.timeZone = timeZone;
648     return true;
649   }
650 
651   /** Returns the time zone set by setTimeZone. */
getTimeZone()652   public String getTimeZone() {
653     return timeZone;
654   }
655 
656   /**
657    * Sets permitted accessibility services.
658    *
659    * <p>The API can be called by either a profile or device owner.
660    *
661    * <p>This method does not check already enabled non-system accessibility services, so will always
662    * set the restriction and return true.
663    */
664   @Implementation(minSdk = LOLLIPOP)
setPermittedAccessibilityServices( ComponentName admin, List<String> packageNames)665   protected boolean setPermittedAccessibilityServices(
666       ComponentName admin, List<String> packageNames) {
667     enforceDeviceOwnerOrProfileOwner(admin);
668     permittedAccessibilityServices = packageNames;
669     return true;
670   }
671 
672   @Implementation(minSdk = LOLLIPOP)
673   @Nullable
getPermittedAccessibilityServices(ComponentName admin)674   protected List<String> getPermittedAccessibilityServices(ComponentName admin) {
675     enforceDeviceOwnerOrProfileOwner(admin);
676     return permittedAccessibilityServices;
677   }
678 
679   /**
680    * Sets permitted input methods.
681    *
682    * <p>The API can be called by either a profile or device owner.
683    *
684    * <p>This method does not check already enabled non-system input methods, so will always set the
685    * restriction and return true.
686    */
687   @Implementation(minSdk = LOLLIPOP)
setPermittedInputMethods(ComponentName admin, List<String> packageNames)688   protected boolean setPermittedInputMethods(ComponentName admin, List<String> packageNames) {
689     enforceDeviceOwnerOrProfileOwner(admin);
690     permittedInputMethods = packageNames;
691     return true;
692   }
693 
694   @Implementation(minSdk = LOLLIPOP)
695   @Nullable
getPermittedInputMethods(ComponentName admin)696   protected List<String> getPermittedInputMethods(ComponentName admin) {
697     enforceDeviceOwnerOrProfileOwner(admin);
698     return permittedInputMethods;
699   }
700 
701   /**
702    * @return the previously set status; default is {@link
703    *     DevicePolicyManager#ENCRYPTION_STATUS_UNSUPPORTED}
704    * @see #setStorageEncryptionStatus(int)
705    */
706   @Implementation
getStorageEncryptionStatus()707   protected int getStorageEncryptionStatus() {
708     return storageEncryptionStatus;
709   }
710 
711   /** Setter for {@link DevicePolicyManager#getStorageEncryptionStatus()}. */
setStorageEncryptionStatus(int status)712   public void setStorageEncryptionStatus(int status) {
713     switch (status) {
714       case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE:
715       case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE:
716       case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVATING:
717       case DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED:
718         break;
719       case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY:
720         if (RuntimeEnvironment.getApiLevel() < M) {
721           throw new IllegalArgumentException("status " + status + " requires API " + M);
722         }
723         break;
724       case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER:
725         if (RuntimeEnvironment.getApiLevel() < N) {
726           throw new IllegalArgumentException("status " + status + " requires API " + N);
727         }
728         break;
729       default:
730         throw new IllegalArgumentException("Unknown status: " + status);
731     }
732 
733     storageEncryptionStatus = status;
734   }
735 
736   @Implementation
setStorageEncryption(ComponentName admin, boolean encrypt)737   protected int setStorageEncryption(ComponentName admin, boolean encrypt) {
738     enforceActiveAdmin(admin);
739     this.storageEncryptionRequested = encrypt;
740     return storageEncryptionStatus;
741   }
742 
743   @Implementation
getStorageEncryption(ComponentName admin)744   protected boolean getStorageEncryption(ComponentName admin) {
745     return storageEncryptionRequested;
746   }
747 
748   @Implementation(minSdk = VERSION_CODES.M)
getPermissionGrantState( ComponentName admin, String packageName, String permission)749   protected int getPermissionGrantState(
750       ComponentName admin, String packageName, String permission) {
751     enforceDeviceOwnerOrProfileOwner(admin);
752     Integer state =
753         appPermissionGrantStateMap.get(new PackageAndPermission(packageName, permission));
754     return state == null ? DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT : state;
755   }
756 
isPermissionGranted(String packageName, String permission)757   public boolean isPermissionGranted(String packageName, String permission) {
758     Boolean isGranted =
759         appPermissionGrantedMap.get(new PackageAndPermission(packageName, permission));
760     return isGranted == null ? false : isGranted;
761   }
762 
763   @Implementation(minSdk = VERSION_CODES.M)
setPermissionGrantState( ComponentName admin, String packageName, String permission, int grantState)764   protected boolean setPermissionGrantState(
765       ComponentName admin, String packageName, String permission, int grantState) {
766     enforceDeviceOwnerOrProfileOwner(admin);
767 
768     String selfPackageName = context.getPackageName();
769 
770     if (packageName.equals(selfPackageName)) {
771       PackageInfo packageInfo;
772       try {
773         packageInfo =
774             context
775                 .getPackageManager()
776                 .getPackageInfo(selfPackageName, PackageManager.GET_PERMISSIONS);
777       } catch (NameNotFoundException e) {
778         throw new RuntimeException(e);
779       }
780       if (Arrays.asList(packageInfo.requestedPermissions).contains(permission)) {
781         if (grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED) {
782           ShadowApplication.getInstance().grantPermissions(permission);
783         }
784         if (grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED) {
785           ShadowApplication.getInstance().denyPermissions(permission);
786         }
787       } else {
788         // the app does not require this permission
789         return false;
790       }
791     }
792     PackageAndPermission key = new PackageAndPermission(packageName, permission);
793     switch (grantState) {
794       case DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED:
795         appPermissionGrantedMap.put(key, true);
796         break;
797       case DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED:
798         appPermissionGrantedMap.put(key, false);
799         break;
800       default:
801         // no-op
802     }
803     appPermissionGrantStateMap.put(key, grantState);
804     return true;
805   }
806 
807   @Implementation
lockNow()808   protected void lockNow() {
809     KeyguardManager keyguardManager =
810         (KeyguardManager) this.context.getSystemService(Context.KEYGUARD_SERVICE);
811     ShadowKeyguardManager shadowKeyguardManager = Shadow.extract(keyguardManager);
812     shadowKeyguardManager.setKeyguardLocked(true);
813     shadowKeyguardManager.setIsDeviceLocked(true);
814   }
815 
816   @Implementation
wipeData(int flags)817   protected void wipeData(int flags) {
818     wipeCalled++;
819   }
820 
getWipeCalledTimes()821   public long getWipeCalledTimes() {
822     return wipeCalled;
823   }
824 
825   @Implementation
setPasswordQuality(ComponentName admin, int quality)826   protected void setPasswordQuality(ComponentName admin, int quality) {
827     enforceActiveAdmin(admin);
828     requiredPasswordQuality = quality;
829   }
830 
831   @Implementation
getPasswordQuality(ComponentName admin)832   protected int getPasswordQuality(ComponentName admin) {
833     if (admin != null) {
834       enforceActiveAdmin(admin);
835     }
836     return requiredPasswordQuality;
837   }
838 
839   @Implementation
resetPassword(String password, int flags)840   protected boolean resetPassword(String password, int flags) {
841     if (!passwordMeetsRequirements(password)) {
842       return false;
843     }
844     lastSetPassword = password;
845     boolean secure = !password.isEmpty();
846     KeyguardManager keyguardManager =
847         (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
848     shadowOf(keyguardManager).setIsDeviceSecure(secure);
849     shadowOf(keyguardManager).setIsKeyguardSecure(secure);
850     return true;
851   }
852 
853   @Implementation(minSdk = O)
resetPasswordWithToken( ComponentName admin, String password, byte[] token, int flags)854   protected boolean resetPasswordWithToken(
855       ComponentName admin, String password, byte[] token, int flags) {
856     enforceDeviceOwnerOrProfileOwner(admin);
857     if (!Arrays.equals(passwordResetTokens.get(admin), token)
858         || !componentsWithActivatedTokens.contains(admin)) {
859       throw new IllegalStateException("wrong or not activated token");
860     }
861     resetPassword(password, flags);
862     return true;
863   }
864 
865   @Implementation(minSdk = O)
isResetPasswordTokenActive(ComponentName admin)866   protected boolean isResetPasswordTokenActive(ComponentName admin) {
867     enforceDeviceOwnerOrProfileOwner(admin);
868     return componentsWithActivatedTokens.contains(admin);
869   }
870 
871   @Implementation(minSdk = O)
setResetPasswordToken(ComponentName admin, byte[] token)872   protected boolean setResetPasswordToken(ComponentName admin, byte[] token) {
873     if (token.length < 32) {
874       throw new IllegalArgumentException("token too short: " + token.length);
875     }
876     enforceDeviceOwnerOrProfileOwner(admin);
877     passwordResetTokens.put(admin, token);
878     componentsWithActivatedTokens.remove(admin);
879     KeyguardManager keyguardManager =
880         (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
881     if (!keyguardManager.isDeviceSecure()) {
882       activateResetToken(admin);
883     }
884     return true;
885   }
886 
887   @Implementation
setPasswordMinimumLength(ComponentName admin, int length)888   protected void setPasswordMinimumLength(ComponentName admin, int length) {
889     enforceActiveAdmin(admin);
890     passwordMinimumLength = length;
891   }
892 
893   @Implementation
getPasswordMinimumLength(ComponentName admin)894   protected int getPasswordMinimumLength(ComponentName admin) {
895     if (admin != null) {
896       enforceActiveAdmin(admin);
897     }
898     return passwordMinimumLength;
899   }
900 
901   @Implementation
setPasswordMinimumLetters(ComponentName admin, int length)902   protected void setPasswordMinimumLetters(ComponentName admin, int length) {
903     enforceActiveAdmin(admin);
904     passwordMinimumLetters = length;
905   }
906 
907   @Implementation
getPasswordMinimumLetters(ComponentName admin)908   protected int getPasswordMinimumLetters(ComponentName admin) {
909     if (admin != null) {
910       enforceActiveAdmin(admin);
911     }
912     return passwordMinimumLetters;
913   }
914 
915   @Implementation
setPasswordMinimumLowerCase(ComponentName admin, int length)916   protected void setPasswordMinimumLowerCase(ComponentName admin, int length) {
917     enforceActiveAdmin(admin);
918     passwordMinimumLowerCase = length;
919   }
920 
921   @Implementation
getPasswordMinimumLowerCase(ComponentName admin)922   protected int getPasswordMinimumLowerCase(ComponentName admin) {
923     if (admin != null) {
924       enforceActiveAdmin(admin);
925     }
926     return passwordMinimumLowerCase;
927   }
928 
929   @Implementation
setPasswordMinimumUpperCase(ComponentName admin, int length)930   protected void setPasswordMinimumUpperCase(ComponentName admin, int length) {
931     enforceActiveAdmin(admin);
932     passwordMinimumUpperCase = length;
933   }
934 
935   @Implementation
getPasswordMinimumUpperCase(ComponentName admin)936   protected int getPasswordMinimumUpperCase(ComponentName admin) {
937     if (admin != null) {
938       enforceActiveAdmin(admin);
939     }
940     return passwordMinimumUpperCase;
941   }
942 
943   @Implementation
setPasswordMinimumNonLetter(ComponentName admin, int length)944   protected void setPasswordMinimumNonLetter(ComponentName admin, int length) {
945     enforceActiveAdmin(admin);
946     passwordMinimumNonLetter = length;
947   }
948 
949   @Implementation
getPasswordMinimumNonLetter(ComponentName admin)950   protected int getPasswordMinimumNonLetter(ComponentName admin) {
951     if (admin != null) {
952       enforceActiveAdmin(admin);
953     }
954     return passwordMinimumNonLetter;
955   }
956 
957   @Implementation
setPasswordMinimumNumeric(ComponentName admin, int length)958   protected void setPasswordMinimumNumeric(ComponentName admin, int length) {
959     enforceActiveAdmin(admin);
960     passwordMinimumNumeric = length;
961   }
962 
963   @Implementation
getPasswordMinimumNumeric(ComponentName admin)964   protected int getPasswordMinimumNumeric(ComponentName admin) {
965     if (admin != null) {
966       enforceActiveAdmin(admin);
967     }
968     return passwordMinimumNumeric;
969   }
970 
971   @Implementation
setPasswordMinimumSymbols(ComponentName admin, int length)972   protected void setPasswordMinimumSymbols(ComponentName admin, int length) {
973     enforceActiveAdmin(admin);
974     passwordMinimumSymbols = length;
975   }
976 
977   @Implementation
getPasswordMinimumSymbols(ComponentName admin)978   protected int getPasswordMinimumSymbols(ComponentName admin) {
979     if (admin != null) {
980       enforceActiveAdmin(admin);
981     }
982     return passwordMinimumSymbols;
983   }
984 
985   @Implementation
setMaximumFailedPasswordsForWipe(ComponentName admin, int num)986   protected void setMaximumFailedPasswordsForWipe(ComponentName admin, int num) {
987     enforceActiveAdmin(admin);
988     maximumFailedPasswordsForWipe = num;
989   }
990 
991   @Implementation
getMaximumFailedPasswordsForWipe(ComponentName admin)992   protected int getMaximumFailedPasswordsForWipe(ComponentName admin) {
993     if (admin != null) {
994       enforceActiveAdmin(admin);
995     }
996     return maximumFailedPasswordsForWipe;
997   }
998 
999   @Implementation
setCameraDisabled(ComponentName admin, boolean disabled)1000   protected void setCameraDisabled(ComponentName admin, boolean disabled) {
1001     enforceActiveAdmin(admin);
1002     cameraDisabled = disabled;
1003   }
1004 
1005   @Implementation
getCameraDisabled(ComponentName admin)1006   protected boolean getCameraDisabled(ComponentName admin) {
1007     if (admin != null) {
1008       enforceActiveAdmin(admin);
1009     }
1010     return cameraDisabled;
1011   }
1012 
1013   @Implementation
setPasswordExpirationTimeout(ComponentName admin, long timeout)1014   protected void setPasswordExpirationTimeout(ComponentName admin, long timeout) {
1015     enforceActiveAdmin(admin);
1016     passwordExpirationTimeout = timeout;
1017   }
1018 
1019   @Implementation
getPasswordExpirationTimeout(ComponentName admin)1020   protected long getPasswordExpirationTimeout(ComponentName admin) {
1021     if (admin != null) {
1022       enforceActiveAdmin(admin);
1023     }
1024     return passwordExpirationTimeout;
1025   }
1026 
1027   /**
1028    * Sets the password expiration time for a particular admin.
1029    *
1030    * @param admin which DeviceAdminReceiver this request is associated with.
1031    * @param timeout the password expiration time, in milliseconds since epoch.
1032    */
setPasswordExpiration(ComponentName admin, long timeout)1033   public void setPasswordExpiration(ComponentName admin, long timeout) {
1034     enforceActiveAdmin(admin);
1035     passwordExpiration = timeout;
1036   }
1037 
1038   @Implementation
getPasswordExpiration(ComponentName admin)1039   protected long getPasswordExpiration(ComponentName admin) {
1040     if (admin != null) {
1041       enforceActiveAdmin(admin);
1042     }
1043     return passwordExpiration;
1044   }
1045 
1046   @Implementation
setMaximumTimeToLock(ComponentName admin, long timeMs)1047   protected void setMaximumTimeToLock(ComponentName admin, long timeMs) {
1048     enforceActiveAdmin(admin);
1049     maximumTimeToLock = timeMs;
1050   }
1051 
1052   @Implementation
getMaximumTimeToLock(ComponentName admin)1053   protected long getMaximumTimeToLock(ComponentName admin) {
1054     if (admin != null) {
1055       enforceActiveAdmin(admin);
1056     }
1057     return maximumTimeToLock;
1058   }
1059 
1060   @Implementation
setPasswordHistoryLength(ComponentName admin, int length)1061   protected void setPasswordHistoryLength(ComponentName admin, int length) {
1062     enforceActiveAdmin(admin);
1063     passwordHistoryLength = length;
1064   }
1065 
1066   @Implementation
getPasswordHistoryLength(ComponentName admin)1067   protected int getPasswordHistoryLength(ComponentName admin) {
1068     if (admin != null) {
1069       enforceActiveAdmin(admin);
1070     }
1071     return passwordHistoryLength;
1072   }
1073 
1074   /**
1075    * Sets if the password meets the current requirements.
1076    *
1077    * @param sufficient indicates the password meets the current requirements
1078    */
setActivePasswordSufficient(boolean sufficient)1079   public void setActivePasswordSufficient(boolean sufficient) {
1080     isActivePasswordSufficient = sufficient;
1081   }
1082 
1083   @Implementation
isActivePasswordSufficient()1084   protected boolean isActivePasswordSufficient() {
1085     return isActivePasswordSufficient;
1086   }
1087 
1088   /** Sets whether the device is provisioned. */
setDeviceProvisioned(boolean isProvisioned)1089   public void setDeviceProvisioned(boolean isProvisioned) {
1090     isDeviceProvisioned = isProvisioned;
1091   }
1092 
1093   @Implementation(minSdk = O)
1094   @SystemApi
1095   @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
isDeviceProvisioned()1096   protected boolean isDeviceProvisioned() {
1097     return isDeviceProvisioned;
1098   }
1099 
1100   @Implementation(minSdk = O)
1101   @SystemApi
1102   @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
setDeviceProvisioningConfigApplied()1103   protected void setDeviceProvisioningConfigApplied() {
1104     isDeviceProvisioningConfigApplied = true;
1105   }
1106 
1107   @Implementation(minSdk = O)
1108   @SystemApi
1109   @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
isDeviceProvisioningConfigApplied()1110   protected boolean isDeviceProvisioningConfigApplied() {
1111     return isDeviceProvisioningConfigApplied;
1112   }
1113 
1114   /** Sets the password complexity. */
setPasswordComplexity(@asswordComplexity int passwordComplexity)1115   public void setPasswordComplexity(@PasswordComplexity int passwordComplexity) {
1116     this.passwordComplexity = passwordComplexity;
1117   }
1118 
1119   @PasswordComplexity
1120   @Implementation(minSdk = Q)
getPasswordComplexity()1121   protected int getPasswordComplexity() {
1122     return passwordComplexity;
1123   }
1124 
passwordMeetsRequirements(String password)1125   private boolean passwordMeetsRequirements(String password) {
1126     int digit = 0;
1127     int alpha = 0;
1128     int upper = 0;
1129     int lower = 0;
1130     int symbol = 0;
1131     for (int i = 0; i < password.length(); i++) {
1132       char c = password.charAt(i);
1133       if (Character.isDigit(c)) {
1134         digit++;
1135       }
1136       if (Character.isLetter(c)) {
1137         alpha++;
1138       }
1139       if (Character.isUpperCase(c)) {
1140         upper++;
1141       }
1142       if (Character.isLowerCase(c)) {
1143         lower++;
1144       }
1145       if (!Character.isLetterOrDigit(c)) {
1146         symbol++;
1147       }
1148     }
1149     switch (requiredPasswordQuality) {
1150       case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
1151       case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
1152       case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK:
1153         return true;
1154       case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
1155         return password.length() > 0;
1156       case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
1157       case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: // complexity not enforced
1158         return digit > 0 && password.length() >= passwordMinimumLength;
1159       case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
1160         return digit > 0 && alpha > 0 && password.length() >= passwordMinimumLength;
1161       case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
1162         return password.length() >= passwordMinimumLength
1163             && alpha >= passwordMinimumLetters
1164             && lower >= passwordMinimumLowerCase
1165             && upper >= passwordMinimumUpperCase
1166             && digit + symbol >= passwordMinimumNonLetter
1167             && digit >= passwordMinimumNumeric
1168             && symbol >= passwordMinimumSymbols;
1169       default:
1170         return true;
1171     }
1172   }
1173 
1174   /**
1175    * Retrieves last password set through {@link DevicePolicyManager#resetPassword} or {@link
1176    * DevicePolicyManager#resetPasswordWithToken}.
1177    */
getLastSetPassword()1178   public String getLastSetPassword() {
1179     return lastSetPassword;
1180   }
1181 
1182   /**
1183    * Activates reset token for given admin.
1184    *
1185    * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
1186    * @return if the activation state changed.
1187    * @throws IllegalArgumentException if there is no token set for this admin.
1188    */
activateResetToken(ComponentName admin)1189   public boolean activateResetToken(ComponentName admin) {
1190     if (!passwordResetTokens.containsKey(admin)) {
1191       throw new IllegalArgumentException("No token set for comopnent: " + admin);
1192     }
1193     return componentsWithActivatedTokens.add(admin);
1194   }
1195 
1196   @Implementation(minSdk = LOLLIPOP)
addPersistentPreferredActivity( ComponentName admin, IntentFilter filter, ComponentName activity)1197   protected void addPersistentPreferredActivity(
1198       ComponentName admin, IntentFilter filter, ComponentName activity) {
1199     enforceDeviceOwnerOrProfileOwner(admin);
1200 
1201     PackageManager packageManager = context.getPackageManager();
1202     Shadow.<ShadowPackageManager>extract(packageManager)
1203         .addPersistentPreferredActivity(filter, activity);
1204   }
1205 
1206   @Implementation(minSdk = LOLLIPOP)
clearPackagePersistentPreferredActivities( ComponentName admin, String packageName)1207   protected void clearPackagePersistentPreferredActivities(
1208       ComponentName admin, String packageName) {
1209     enforceDeviceOwnerOrProfileOwner(admin);
1210     PackageManager packageManager = context.getPackageManager();
1211     Shadow.<ShadowPackageManager>extract(packageManager)
1212         .clearPackagePersistentPreferredActivities(packageName);
1213   }
1214 
1215   @Implementation(minSdk = JELLY_BEAN_MR1)
setKeyguardDisabledFeatures(ComponentName admin, int which)1216   protected void setKeyguardDisabledFeatures(ComponentName admin, int which) {
1217     enforceActiveAdmin(admin);
1218     keyguardDisabledFeatures = which;
1219   }
1220 
1221   @Implementation(minSdk = JELLY_BEAN_MR1)
getKeyguardDisabledFeatures(ComponentName admin)1222   protected int getKeyguardDisabledFeatures(ComponentName admin) {
1223     return keyguardDisabledFeatures;
1224   }
1225 
1226   /**
1227    * Sets the user provisioning state.
1228    *
1229    * @param state to store provisioning state
1230    */
setUserProvisioningState(int state)1231   public void setUserProvisioningState(int state) {
1232     setUserProvisioningState(state, Process.myUserHandle());
1233   }
1234 
1235   @Implementation(minSdk = TIRAMISU)
setUserProvisioningState(@serProvisioningState int state, UserHandle userHandle)1236   protected void setUserProvisioningState(@UserProvisioningState int state, UserHandle userHandle) {
1237     userProvisioningStatesMap.put(userHandle.getIdentifier(), state);
1238   }
1239 
1240   /**
1241    * Returns the provisioning state set in {@link #setUserProvisioningState(int)}, or {@link
1242    * DevicePolicyManager#STATE_USER_UNMANAGED} if none is set.
1243    */
1244   @Implementation(minSdk = N)
getUserProvisioningState()1245   protected int getUserProvisioningState() {
1246     return getUserProvisioningStateForUser(Process.myUserHandle().getIdentifier());
1247   }
1248 
1249   @Implementation
hasGrantedPolicy(@onNull ComponentName admin, int usesPolicy)1250   protected boolean hasGrantedPolicy(@NonNull ComponentName admin, int usesPolicy) {
1251     enforceActiveAdmin(admin);
1252     Set<Integer> policyGrantedSet = adminPolicyGrantedMap.get(admin);
1253     return policyGrantedSet != null && policyGrantedSet.contains(usesPolicy);
1254   }
1255 
1256   @Implementation(minSdk = P)
getLockTaskFeatures(ComponentName admin)1257   protected int getLockTaskFeatures(ComponentName admin) {
1258     Objects.requireNonNull(admin, "ComponentName is null");
1259     enforceDeviceOwnerOrProfileOwner(admin);
1260     return lockTaskFeatures;
1261   }
1262 
1263   @Implementation(minSdk = P)
setLockTaskFeatures(ComponentName admin, int flags)1264   protected void setLockTaskFeatures(ComponentName admin, int flags) {
1265     Objects.requireNonNull(admin, "ComponentName is null");
1266     enforceDeviceOwnerOrProfileOwner(admin);
1267     // Throw if Overview is used without Home.
1268     boolean hasHome = (flags & LOCK_TASK_FEATURE_HOME) != 0;
1269     boolean hasOverview = (flags & LOCK_TASK_FEATURE_OVERVIEW) != 0;
1270     Preconditions.checkArgument(
1271         hasHome || !hasOverview,
1272         "Cannot use LOCK_TASK_FEATURE_OVERVIEW without LOCK_TASK_FEATURE_HOME");
1273     boolean hasNotification = (flags & LOCK_TASK_FEATURE_NOTIFICATIONS) != 0;
1274     Preconditions.checkArgument(
1275         hasHome || !hasNotification,
1276         "Cannot use LOCK_TASK_FEATURE_NOTIFICATIONS without LOCK_TASK_FEATURE_HOME");
1277 
1278     lockTaskFeatures = flags;
1279   }
1280 
1281   @Implementation(minSdk = LOLLIPOP)
setLockTaskPackages(@onNull ComponentName admin, String[] packages)1282   protected void setLockTaskPackages(@NonNull ComponentName admin, String[] packages) {
1283     enforceDeviceOwnerOrProfileOwner(admin);
1284     lockTaskPackages.clear();
1285     Collections.addAll(lockTaskPackages, packages);
1286   }
1287 
1288   @Implementation(minSdk = LOLLIPOP)
getLockTaskPackages(@onNull ComponentName admin)1289   protected String[] getLockTaskPackages(@NonNull ComponentName admin) {
1290     enforceDeviceOwnerOrProfileOwner(admin);
1291     return lockTaskPackages.toArray(new String[0]);
1292   }
1293 
1294   @Implementation(minSdk = LOLLIPOP)
isLockTaskPermitted(@onNull String pkg)1295   protected boolean isLockTaskPermitted(@NonNull String pkg) {
1296     return lockTaskPackages.contains(pkg);
1297   }
1298 
1299   @Implementation(minSdk = O)
setAffiliationIds(@onNull ComponentName admin, @NonNull Set<String> ids)1300   protected void setAffiliationIds(@NonNull ComponentName admin, @NonNull Set<String> ids) {
1301     enforceDeviceOwnerOrProfileOwner(admin);
1302     affiliationIds.clear();
1303     affiliationIds.addAll(ids);
1304   }
1305 
1306   @Implementation(minSdk = O)
getAffiliationIds(@onNull ComponentName admin)1307   protected Set<String> getAffiliationIds(@NonNull ComponentName admin) {
1308     enforceDeviceOwnerOrProfileOwner(admin);
1309     return affiliationIds;
1310   }
1311 
1312   @Implementation(minSdk = M)
setPermissionPolicy(@onNull ComponentName admin, int policy)1313   protected void setPermissionPolicy(@NonNull ComponentName admin, int policy) {
1314     enforceDeviceOwnerOrProfileOwner(admin);
1315     permissionPolicy = policy;
1316   }
1317 
1318   @Implementation(minSdk = M)
getPermissionPolicy(ComponentName admin)1319   protected int getPermissionPolicy(ComponentName admin) {
1320     enforceDeviceOwnerOrProfileOwner(admin);
1321     return permissionPolicy;
1322   }
1323 
1324   /**
1325    * Grants a particular device policy for an active ComponentName.
1326    *
1327    * @param admin the ComponentName which DeviceAdminReceiver this request is associated with. Must
1328    *     be an active administrator, or an exception will be thrown. This value must never be null.
1329    * @param usesPolicy the uses-policy to check
1330    */
grantPolicy(@onNull ComponentName admin, int usesPolicy)1331   public void grantPolicy(@NonNull ComponentName admin, int usesPolicy) {
1332     enforceActiveAdmin(admin);
1333     Set<Integer> policyGrantedSet = adminPolicyGrantedMap.get(admin);
1334     if (policyGrantedSet == null) {
1335       policyGrantedSet = new HashSet<>();
1336       policyGrantedSet.add(usesPolicy);
1337       adminPolicyGrantedMap.put(admin, policyGrantedSet);
1338     } else {
1339       policyGrantedSet.add(usesPolicy);
1340     }
1341   }
1342 
1343   @Implementation(minSdk = M)
getSystemUpdatePolicy()1344   protected SystemUpdatePolicy getSystemUpdatePolicy() {
1345     return policy;
1346   }
1347 
1348   @Implementation(minSdk = M)
setSystemUpdatePolicy(ComponentName admin, SystemUpdatePolicy policy)1349   protected void setSystemUpdatePolicy(ComponentName admin, SystemUpdatePolicy policy) {
1350     this.policy = policy;
1351   }
1352 
1353   /**
1354    * Sets the system update policy.
1355    *
1356    * @see #setSystemUpdatePolicy(ComponentName, SystemUpdatePolicy)
1357    */
setSystemUpdatePolicy(SystemUpdatePolicy policy)1358   public void setSystemUpdatePolicy(SystemUpdatePolicy policy) {
1359     setSystemUpdatePolicy(null, policy);
1360   }
1361 
1362   /**
1363    * Set the list of target users that the calling device or profile owner can use when calling
1364    * {@link #bindDeviceAdminServiceAsUser}.
1365    *
1366    * @see #getBindDeviceAdminTargetUsers(ComponentName)
1367    */
setBindDeviceAdminTargetUsers(List<UserHandle> bindDeviceAdminTargetUsers)1368   public void setBindDeviceAdminTargetUsers(List<UserHandle> bindDeviceAdminTargetUsers) {
1369     this.bindDeviceAdminTargetUsers = bindDeviceAdminTargetUsers;
1370   }
1371 
1372   /**
1373    * Returns the list of target users that the calling device or profile owner can use when calling
1374    * {@link #bindDeviceAdminServiceAsUser}.
1375    *
1376    * @see #setBindDeviceAdminTargetUsers(List)
1377    */
1378   @Implementation(minSdk = O)
getBindDeviceAdminTargetUsers(ComponentName admin)1379   protected List<UserHandle> getBindDeviceAdminTargetUsers(ComponentName admin) {
1380     return bindDeviceAdminTargetUsers;
1381   }
1382 
1383   /**
1384    * Bind to the same package in another user.
1385    *
1386    * <p>This validates that the targetUser is one from {@link
1387    * #getBindDeviceAdminTargetUsers(ComponentName)} but does not actually bind to a different user,
1388    * instead binding to the same user.
1389    *
1390    * <p>It also does not validate the service being bound to.
1391    */
1392   @Implementation(minSdk = O)
bindDeviceAdminServiceAsUser( ComponentName admin, Intent serviceIntent, ServiceConnection conn, int flags, UserHandle targetUser)1393   protected boolean bindDeviceAdminServiceAsUser(
1394       ComponentName admin,
1395       Intent serviceIntent,
1396       ServiceConnection conn,
1397       int flags,
1398       UserHandle targetUser) {
1399     if (!getBindDeviceAdminTargetUsers(admin).contains(targetUser)) {
1400       throw new SecurityException("Not allowed to bind to target user id");
1401     }
1402 
1403     return context.bindServiceAsUser(serviceIntent, conn, flags, targetUser);
1404   }
1405 
1406   @Implementation(minSdk = N)
setShortSupportMessage(ComponentName admin, @Nullable CharSequence message)1407   protected void setShortSupportMessage(ComponentName admin, @Nullable CharSequence message) {
1408     enforceActiveAdmin(admin);
1409     shortSupportMessageMap.put(admin, message);
1410   }
1411 
1412   @Implementation(minSdk = N)
1413   @Nullable
getShortSupportMessage(ComponentName admin)1414   protected CharSequence getShortSupportMessage(ComponentName admin) {
1415     enforceActiveAdmin(admin);
1416     return shortSupportMessageMap.get(admin);
1417   }
1418 
1419   @Implementation(minSdk = N)
setLongSupportMessage(ComponentName admin, @Nullable CharSequence message)1420   protected void setLongSupportMessage(ComponentName admin, @Nullable CharSequence message) {
1421     enforceActiveAdmin(admin);
1422     longSupportMessageMap.put(admin, message);
1423   }
1424 
1425   @Implementation(minSdk = N)
1426   @Nullable
getLongSupportMessage(ComponentName admin)1427   protected CharSequence getLongSupportMessage(ComponentName admin) {
1428     enforceActiveAdmin(admin);
1429     return longSupportMessageMap.get(admin);
1430   }
1431 
1432   /**
1433    * Sets the return value of the {@link
1434    * DevicePolicyManager#isOrganizationOwnedDeviceWithManagedProfile} method (only for Android R+).
1435    */
setOrganizationOwnedDeviceWithManagedProfile(boolean value)1436   public void setOrganizationOwnedDeviceWithManagedProfile(boolean value) {
1437     organizationOwnedDeviceWithManagedProfile = value;
1438   }
1439 
1440   /**
1441    * Returns the value stored using in the shadow, while the real method returns the value store on
1442    * the device.
1443    *
1444    * <p>The value can be set by {@link #setOrganizationOwnedDeviceWithManagedProfile} and is {@code
1445    * false} by default.
1446    */
1447   @Implementation(minSdk = R)
isOrganizationOwnedDeviceWithManagedProfile()1448   protected boolean isOrganizationOwnedDeviceWithManagedProfile() {
1449     return organizationOwnedDeviceWithManagedProfile;
1450   }
1451 
1452   @Implementation(minSdk = S)
1453   @NearbyStreamingPolicy
getNearbyNotificationStreamingPolicy()1454   protected int getNearbyNotificationStreamingPolicy() {
1455     return nearbyNotificationStreamingPolicy;
1456   }
1457 
1458   @Implementation(minSdk = S)
setNearbyNotificationStreamingPolicy(@earbyStreamingPolicy int policy)1459   protected void setNearbyNotificationStreamingPolicy(@NearbyStreamingPolicy int policy) {
1460     nearbyNotificationStreamingPolicy = policy;
1461   }
1462 
1463   @Implementation(minSdk = S)
1464   @NearbyStreamingPolicy
getNearbyAppStreamingPolicy()1465   protected int getNearbyAppStreamingPolicy() {
1466     return nearbyAppStreamingPolicy;
1467   }
1468 
1469   @Implementation(minSdk = S)
setNearbyAppStreamingPolicy(@earbyStreamingPolicy int policy)1470   protected void setNearbyAppStreamingPolicy(@NearbyStreamingPolicy int policy) {
1471     nearbyAppStreamingPolicy = policy;
1472   }
1473 
1474   @Nullable
1475   @Implementation(minSdk = TIRAMISU)
getDevicePolicyManagementRoleHolderPackage()1476   protected String getDevicePolicyManagementRoleHolderPackage() {
1477     return devicePolicyManagementRoleHolderPackage;
1478   }
1479 
1480   /**
1481    * Sets the package name of the device policy management role holder.
1482    *
1483    * @see #getDevicePolicyManagementRoleHolderPackage()
1484    */
setDevicePolicyManagementRoleHolderPackage(@ullable String packageName)1485   public void setDevicePolicyManagementRoleHolderPackage(@Nullable String packageName) {
1486     devicePolicyManagementRoleHolderPackage = packageName;
1487   }
1488 
1489   @Implementation(minSdk = TIRAMISU)
finalizeWorkProfileProvisioning( UserHandle managedProfileUser, @Nullable Account migratedAccount)1490   protected void finalizeWorkProfileProvisioning(
1491       UserHandle managedProfileUser, @Nullable Account migratedAccount) {
1492     finalizedWorkProfileProvisioningMap.put(managedProfileUser, migratedAccount);
1493   }
1494 
1495   /**
1496    * Returns if {@link #finalizeWorkProfileProvisioning(UserHandle, Account)} was called with the
1497    * provided parameters.
1498    */
isWorkProfileProvisioningFinalized( UserHandle userHandle, @Nullable Account migratedAccount)1499   public boolean isWorkProfileProvisioningFinalized(
1500       UserHandle userHandle, @Nullable Account migratedAccount) {
1501     return finalizedWorkProfileProvisioningMap.containsKey(userHandle)
1502         && Objects.equals(finalizedWorkProfileProvisioningMap.get(userHandle), migratedAccount);
1503   }
1504 
1505   /**
1506    * Returns the managed profiles set in {@link #setPolicyManagedProfiles(List)}. This value does
1507    * not take the user handle parameter into account.
1508    */
1509   @Implementation(minSdk = TIRAMISU)
getPolicyManagedProfiles(UserHandle userHandle)1510   protected List<UserHandle> getPolicyManagedProfiles(UserHandle userHandle) {
1511     return policyManagedProfiles;
1512   }
1513 
1514   /** Sets the value returned by {@link #getPolicyManagedProfiles(UserHandle)}. */
setPolicyManagedProfiles(List<UserHandle> policyManagedProfiles)1515   public void setPolicyManagedProfiles(List<UserHandle> policyManagedProfiles) {
1516     this.policyManagedProfiles = policyManagedProfiles;
1517   }
1518 
1519   /**
1520    * Returns the user provisioning state set by {@link #setUserProvisioningState(int, UserHandle)},
1521    * or {@link DevicePolicyManager#STATE_USER_UNMANAGED} if none is set.
1522    */
1523   @UserProvisioningState
getUserProvisioningStateForUser(int userId)1524   public int getUserProvisioningStateForUser(int userId) {
1525     return userProvisioningStatesMap.getOrDefault(userId, DevicePolicyManager.STATE_USER_UNMANAGED);
1526   }
1527 }
1528