Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +30 −28 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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. Loading Loading @@ -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(); Loading @@ -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); Loading Loading @@ -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)); } Loading Loading @@ -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)); } Loading Loading @@ -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()) { Loading Loading @@ -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. Loading services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +0 −68 Original line number Diff line number Diff line Loading @@ -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; Loading services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java +3 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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). Loading Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +30 −28 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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. Loading Loading @@ -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(); Loading @@ -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); Loading Loading @@ -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)); } Loading Loading @@ -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)); } Loading Loading @@ -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()) { Loading Loading @@ -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. Loading
services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +0 −68 Original line number Diff line number Diff line Loading @@ -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; Loading
services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java +3 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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). Loading