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