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