diff options
author | Christine Franks <christyfranks@google.com> | 2017-08-07 14:28:35 -0700 |
---|---|---|
committer | Christine Franks <christyfranks@google.com> | 2017-08-09 19:18:20 -0700 |
commit | 9a18f5fa409d99e09bed57626d5a600142fd7009 (patch) | |
tree | 0a303dd0696e5f54caecbf704f43c08ab8b948ba | |
parent | 0a3684eb451ae226b522d83088653b9f4f06e7bd (diff) | |
download | base-9a18f5fa409d99e09bed57626d5a600142fd7009.tar.gz |
Add settings and reset operations for demo users
- Allow Global settings to be set in demo mode
- Allow Secure settings to be set by demo users
- Allow fully enabling apps for demo users
- Send enable broadcast as foreground broadcast
Bug: 62712426
Test: runtest -c \
com.android.server.devicepolicy.DevicePolicyManagerTest \
frameworks-services
Change-Id: Icd5d1eda12aa6b97bd4770713710a982bb0fc8e5
3 files changed, 33 insertions, 96 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 73bb13a63612..d249b0a9e1c0 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -2384,6 +2384,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { BroadcastReceiver result) { Intent intent = new Intent(action); intent.setComponent(admin.info.getComponent()); + if (UserManager.isDeviceInDemoMode(mContext)) { + intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + } if (action.equals(DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING)) { intent.putExtra("expiration", admin.passwordExpirationDate); } @@ -8183,23 +8186,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } - final UserInfo userInfo = getUserInfo(userHandle); - if (userInfo != null && userInfo.isDemo()) { - try { - final ApplicationInfo ai = mIPackageManager.getApplicationInfo(adminPkg, - PackageManager.MATCH_DISABLED_COMPONENTS, userHandle); - final boolean isSystemApp = - ai != null && (ai.flags & (ApplicationInfo.FLAG_SYSTEM - | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; - if (isSystemApp) { - mIPackageManager.setApplicationEnabledSetting(adminPkg, - PackageManager.COMPONENT_ENABLED_STATE_ENABLED, - PackageManager.DONT_KILL_APP, userHandle, "DevicePolicyManager"); - } - } catch (RemoteException e) { - } - } - setActiveAdmin(profileOwner, true, userHandle); // User is not started yet, the broadcast by setActiveAdmin will not be received. // So we store adminExtras for broadcasting when the user starts for first time. @@ -8493,6 +8479,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, DELEGATION_ENABLE_SYSTEM_APP); + final boolean isDemo = isCurrentUserDemo(); + int userId = UserHandle.getCallingUserId(); long id = mInjector.binderClearCallingIdentity(); @@ -8503,14 +8491,19 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } int parentUserId = getProfileParentId(userId); - if (!isSystemApp(mIPackageManager, packageName, parentUserId)) { + if (!isDemo && !isSystemApp(mIPackageManager, packageName, parentUserId)) { throw new IllegalArgumentException("Only system apps can be enabled this way."); } // Install the app. mIPackageManager.installExistingPackageAsUser(packageName, userId, 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY); - + if (isDemo) { + // Ensure the app is also ENABLED for demo users. + mIPackageManager.setApplicationEnabledSetting(packageName, + PackageManager.COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP, userId, "DevicePolicyManager"); + } } catch (RemoteException re) { // shouldn't happen Slog.wtf(LOG_TAG, "Failed to install " + packageName, re); @@ -8955,7 +8948,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return; } - if (!GLOBAL_SETTINGS_WHITELIST.contains(setting)) { + if (!GLOBAL_SETTINGS_WHITELIST.contains(setting) + && !UserManager.isDeviceInDemoMode(mContext)) { throw new SecurityException(String.format( "Permission denial: device owners cannot update %1$s", setting)); } @@ -8987,11 +8981,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (isDeviceOwner(who, callingUserId)) { - if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting)) { + if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting) + && !isCurrentUserDemo()) { throw new SecurityException(String.format( "Permission denial: Device owners cannot update %1$s", setting)); } - } else if (!SECURE_SETTINGS_WHITELIST.contains(setting)) { + } else if (!SECURE_SETTINGS_WHITELIST.contains(setting) && !isCurrentUserDemo()) { throw new SecurityException(String.format( "Permission denial: Profile owners cannot update %1$s", setting)); } @@ -9442,12 +9437,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public SystemUpdatePolicy getSystemUpdatePolicy() { - if (UserManager.isDeviceInDemoMode(mContext)) { - // Pretending to have an automatic update policy when the device is in retail demo - // mode. This will allow the device to download and install an ota without - // any user interaction. - return SystemUpdatePolicy.createAutomaticInstallPolicy(); - } synchronized (this) { SystemUpdatePolicy policy = mOwners.getSystemUpdatePolicy(); if (policy != null && !policy.isValid()) { @@ -10454,6 +10443,19 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + private boolean isCurrentUserDemo() { + if (UserManager.isDeviceInDemoMode(mContext)) { + final int userId = mInjector.userHandleGetCallingUserId(); + final long callingIdentity = mInjector.binderClearCallingIdentity(); + try { + return mUserManager.getUserInfo(userId).isDemo(); + } finally { + mInjector.binderRestoreCallingIdentity(callingIdentity); + } + } + return false; + } + private void removePackageIfRequired(final String packageName, final int userId) { if (!packageHasActiveAdmins(packageName, userId)) { // Will not do anything if uninstall was not requested or was already started. diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index bad9b5b97e1f..23330f17634a 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -382,74 +382,6 @@ public class DevicePolicyManagerTest extends DpmTestBase { mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL"); } - public void testCreateAndManageUser_demoUserSystemApp() throws Exception { - mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); - - setDeviceOwner(); - - final int id = UserHandle.getUserId(DpmMockContext.CALLER_UID); - - final UserInfo demoUserInfo = mock(UserInfo.class); - demoUserInfo.id = id; - doReturn(UserHandle.of(id)).when(demoUserInfo).getUserHandle(); - doReturn(true).when(demoUserInfo).isDemo(); - final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); - doReturn(demoUserInfo).when(um).getUserInfo(id); - doReturn(demoUserInfo).when(mContext.getUserManagerInternal()) - .createUserEvenWhenDisallowed(anyString(), anyInt()); - - final ApplicationInfo applicationInfo = getServices().ipackageManager.getApplicationInfo( - admin2.getPackageName(), PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, id); - applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; - doReturn(applicationInfo).when(getServices().ipackageManager).getApplicationInfo( - anyString(), anyInt(), anyInt()); - - final UserHandle userHandle = dpm.createAndManageUser(admin1, "", admin2, null, 0); - - verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting( - eq(admin2.getPackageName()), - eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED), - eq(PackageManager.DONT_KILL_APP), - eq(id), - anyString()); - - assertNotNull(userHandle); - } - - public void testCreateAndManageUser_demoUserSystemUpdatedApp() throws Exception { - mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); - - setDeviceOwner(); - - final int id = UserHandle.getUserId(DpmMockContext.CALLER_UID); - - final UserInfo demoUserInfo = mock(UserInfo.class); - demoUserInfo.id = id; - doReturn(UserHandle.of(id)).when(demoUserInfo).getUserHandle(); - doReturn(true).when(demoUserInfo).isDemo(); - final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); - doReturn(demoUserInfo).when(um).getUserInfo(id); - doReturn(demoUserInfo).when(mContext.getUserManagerInternal()) - .createUserEvenWhenDisallowed(anyString(), anyInt()); - - final ApplicationInfo applicationInfo = getServices().ipackageManager.getApplicationInfo( - admin2.getPackageName(), PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, id); - applicationInfo.flags = ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; - doReturn(applicationInfo).when(getServices().ipackageManager).getApplicationInfo( - anyString(), anyInt(), anyInt()); - - final UserHandle userHandle = dpm.createAndManageUser(admin1, "", admin2, null, 0); - - verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting( - eq(admin2.getPackageName()), - eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED), - eq(PackageManager.DONT_KILL_APP), - eq(id), - anyString()); - - assertNotNull(userHandle); - } - public void testSetActiveAdmin_multiUsers() throws Exception { final int ANOTHER_USER_ID = 100; diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java index 8121bcf16c60..99f54ba1a8ee 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java @@ -46,6 +46,7 @@ import android.os.PowerManagerInternal; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; +import android.provider.Settings; import android.security.KeyChain; import android.telephony.TelephonyManager; import android.test.mock.MockContentResolver; @@ -53,6 +54,7 @@ import android.util.ArrayMap; import android.util.Pair; import android.view.IWindowManager; +import com.android.internal.util.test.FakeSettingsProvider; import com.android.internal.widget.LockPatternUtils; import java.io.File; @@ -130,6 +132,7 @@ public class MockSystemServices { packageManager = spy(realContext.getPackageManager()); contentResolver = new MockContentResolver(); + contentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); // Add the system user with a fake profile group already set up (this can happen in the real // world if a managed profile is added and then removed). |