From abe9311d00ec65a47243b6a58822c9dc017f42b6 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 26 Jan 2022 16:29:59 -0800 Subject: New @TestApi: DevicePolicyManager.isNewUserDisclaimerAcknowledged() It also changes acknowledgeNewUserDisclaimer() to allow callers with INTERACT_ACROSS_USERS permissions - that's more consistent with other methods and allows it to be called by tests. Test: atest com.android.cts.devicepolicy.DeviceOwnerTest#testCreateAndManageUser_newUserDisclaimer Test: m update-api Bug: 203822627 Bug: 215375992 Change-Id: I8b98a1af60db65c1b27f19cf3e93b21d33d88278 Merged-In: I8b98a1af60db65c1b27f19cf3e93b21d33d88278 (cherry picked from commit 9a6b808da3f6f614490952b313ce3e5a3b7ba659) --- core/api/test-current.txt | 1 + .../android/app/admin/DevicePolicyManager.java | 22 ++++++++++++++++++- .../android/app/admin/IDevicePolicyManager.aidl | 1 + .../server/devicepolicy/DevicePolicyData.java | 25 +++++++++++++++++++++- .../devicepolicy/DevicePolicyManagerService.java | 17 +++++++++++++-- 5 files changed, 62 insertions(+), 4 deletions(-) diff --git a/core/api/test-current.txt b/core/api/test-current.txt index ebc62f56bc95..a80468b6d980 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -444,6 +444,7 @@ package android.app.admin { method @NonNull @RequiresPermission("android.permission.MANAGE_DEVICE_ADMINS") public java.util.Set getPolicyExemptApps(); method public boolean isCurrentInputMethodSetByOwner(); method public boolean isFactoryResetProtectionPolicySupported(); + method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public boolean isNewUserDisclaimerAcknowledged(); method @RequiresPermission(anyOf={"android.permission.MARK_DEVICE_ORGANIZATION_OWNED", "android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS"}, conditional=true) public void markProfileOwnerOnOrganizationOwnedDevice(@NonNull android.content.ComponentName); method @NonNull public static String operationSafetyReasonToString(int); method @NonNull public static String operationToString(int); diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index b949ed9d6079..e4d17bc32393 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -3110,7 +3110,8 @@ public class DevicePolicyManager { * * @hide */ - @RequiresPermission(android.Manifest.permission.MANAGE_USERS) + @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.INTERACT_ACROSS_USERS}) public void acknowledgeNewUserDisclaimer() { if (mService != null) { try { @@ -3121,6 +3122,25 @@ public class DevicePolicyManager { } } + /** + * Checks whether the new managed user disclaimer was viewed by the current user. + * + * @hide + */ + @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.INTERACT_ACROSS_USERS}) + @TestApi + public boolean isNewUserDisclaimerAcknowledged() { + if (mService != null) { + try { + return mService.isNewUserDisclaimerAcknowledged(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + return false; + } + /** * Return true if the given administrator component is currently active (enabled) in the system. * diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index a2863bdfc35d..701a362b9c31 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -265,6 +265,7 @@ interface IDevicePolicyManager { void clearLogoutUser(); List getSecondaryUsers(in ComponentName who); void acknowledgeNewUserDisclaimer(); + boolean isNewUserDisclaimerAcknowledged(); void enableSystemApp(in ComponentName admin, in String callerPackage, in String packageName); int enableSystemAppWithIntent(in ComponentName admin, in String callerPackage, in Intent intent); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java index 26c442dc1f47..e18e0020407f 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java @@ -23,6 +23,7 @@ import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.os.FileUtils; import android.os.PersistableBundle; +import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; import android.util.DebugUtils; @@ -83,7 +84,7 @@ class DevicePolicyData { private static final String ATTR_NEW_USER_DISCLAIMER = "new-user-disclaimer"; // Values of ATTR_NEW_USER_DISCLAIMER - static final String NEW_USER_DISCLAIMER_SHOWN = "shown"; + static final String NEW_USER_DISCLAIMER_ACKNOWLEDGED = "acked"; static final String NEW_USER_DISCLAIMER_NOT_NEEDED = "not_needed"; static final String NEW_USER_DISCLAIMER_NEEDED = "needed"; @@ -613,6 +614,28 @@ class DevicePolicyData { } } + boolean isNewUserDisclaimerAcknowledged() { + if (mNewUserDisclaimer == null) { + if (mUserId == UserHandle.USER_SYSTEM) { + return true; + } + Slogf.w(TAG, "isNewUserDisclaimerAcknowledged(%d): mNewUserDisclaimer is null", + mUserId); + return false; + } + switch (mNewUserDisclaimer) { + case NEW_USER_DISCLAIMER_ACKNOWLEDGED: + case NEW_USER_DISCLAIMER_NOT_NEEDED: + return true; + case NEW_USER_DISCLAIMER_NEEDED: + return false; + default: + Slogf.w(TAG, "isNewUserDisclaimerAcknowledged(%d): invalid value %d", mUserId, + mNewUserDisclaimer); + return false; + } + } + void dump(IndentingPrintWriter pw) { pw.println(); pw.println("Enabled Device Admins (User " + mUserId + ", provisioningState: " diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index a46ae27ff8d9..88a79f2a3877 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -10765,10 +10765,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void acknowledgeNewUserDisclaimer() { CallerIdentity callerIdentity = getCallerIdentity(); - canManageUsers(callerIdentity); + Preconditions.checkCallAuthorization(canManageUsers(callerIdentity) + || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS)); setShowNewUserDisclaimer(callerIdentity.getUserId(), - DevicePolicyData.NEW_USER_DISCLAIMER_SHOWN); + DevicePolicyData.NEW_USER_DISCLAIMER_ACKNOWLEDGED); } private void setShowNewUserDisclaimer(@UserIdInt int userId, String value) { @@ -10800,6 +10801,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); } + @Override + public boolean isNewUserDisclaimerAcknowledged() { + CallerIdentity callerIdentity = getCallerIdentity(); + Preconditions.checkCallAuthorization(canManageUsers(callerIdentity) + || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS)); + int userId = callerIdentity.getUserId(); + synchronized (getLockObject()) { + DevicePolicyData policyData = getUserData(userId); + return policyData.isNewUserDisclaimerAcknowledged(); + } + } + @Override public boolean removeUser(ComponentName who, UserHandle userHandle) { Objects.requireNonNull(who, "ComponentName is null"); -- cgit v1.2.3-59-g8ed1b