Loading core/java/android/app/admin/DevicePolicyManager.java +7 −0 Original line number Diff line number Diff line Loading @@ -5981,6 +5981,13 @@ public class DevicePolicyManager { */ public static final int MAKE_USER_EPHEMERAL = 0x0002; /** * Flag used by {@link #createAndManageUser} to specify that the user should be created as a * demo user. * @hide */ public static final int MAKE_USER_DEMO = 0x0004; /** * Called by a device owner to create a user with the specified name and a given component of * the calling package as profile owner. The UserHandle returned by this method should not be Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +29 −7 Original line number Diff line number Diff line Loading @@ -526,7 +526,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // TODO(b/35385311): Keep track of metadata in TrustedCertificateStore instead. Set<String> mOwnerInstalledCaCerts = new ArraySet<>(); // Used for initialization of users created by createAndManageUsers. // Used for initialization of users created by createAndManageUser. boolean mAdminBroadcastPending = false; PersistableBundle mInitBundle = null; Loading Loading @@ -4255,6 +4255,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mInjector.binderRestoreCallingIdentity(token); } } @Override public boolean resetPassword(String passwordOrNull, int flags) throws RemoteException { final int callingUid = mInjector.binderGetCallingUid(); Loading Loading @@ -7375,9 +7376,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private void enableIfNecessary(String packageName, int userId) { try { ApplicationInfo ai = mIPackageManager.getApplicationInfo(packageName, PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, userId); final ApplicationInfo ai = mIPackageManager.getApplicationInfo(packageName, PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, userId); if (ai.enabledSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) { mIPackageManager.setApplicationEnabledSetting(packageName, Loading Loading @@ -8131,8 +8131,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mInjector.binderGetCallingUserHandle().isSystem()) { throw new SecurityException("createAndManageUser was called from non-system user"); } if (!mInjector.userManagerIsSplitSystemUser() && (flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0) { final boolean ephemeral = (flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0; final boolean demo = (flags & DevicePolicyManager.MAKE_USER_DEMO) != 0 && UserManager.isDeviceInDemoMode(mContext); if (ephemeral && !mInjector.userManagerIsSplitSystemUser() && !demo) { throw new IllegalArgumentException( "Ephemeral users are only supported on systems with a split system user."); } Loading @@ -8144,9 +8146,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final long id = mInjector.binderClearCallingIdentity(); try { int userInfoFlags = 0; if ((flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0) { if (ephemeral) { userInfoFlags |= UserInfo.FLAG_EPHEMERAL; } if (demo) { userInfoFlags |= UserInfo.FLAG_DEMO; } UserInfo userInfo = mUserManagerInternal.createUserEvenWhenDisallowed(name, userInfoFlags); if (userInfo != null) { Loading Loading @@ -8178,6 +8183,23 @@ 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 services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +71 −1 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import static org.mockito.Matchers.isNull; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.nullable; import static org.mockito.Mockito.reset; Loading @@ -53,6 +54,7 @@ import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.PasswordMetrics; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; Loading Loading @@ -338,7 +340,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Next, add one more admin. // Before doing so, update the application info, now it's enabled. setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID, PackageManager.COMPONENT_ENABLED_STATE_ENABLED); PackageManager.COMPONENT_ENABLED_STATE_DEFAULT); dpm.setActiveAdmin(admin2, /* replace =*/ false); Loading Loading @@ -380,6 +382,74 @@ 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/DpmMockContext.java +5 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.res.Resources; import android.os.Bundle; import android.os.Handler; import android.os.UserHandle; import android.os.UserManagerInternal; import android.test.mock.MockContext; import android.util.ArrayMap; Loading Loading @@ -196,6 +197,10 @@ public class DpmMockContext extends MockContext { return mMockSystemServices.packageManager; } public UserManagerInternal getUserManagerInternal() { return mMockSystemServices.userManagerInternal; } @Override public void enforceCallingOrSelfPermission(String permission, String message) { if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) { Loading Loading
core/java/android/app/admin/DevicePolicyManager.java +7 −0 Original line number Diff line number Diff line Loading @@ -5981,6 +5981,13 @@ public class DevicePolicyManager { */ public static final int MAKE_USER_EPHEMERAL = 0x0002; /** * Flag used by {@link #createAndManageUser} to specify that the user should be created as a * demo user. * @hide */ public static final int MAKE_USER_DEMO = 0x0004; /** * Called by a device owner to create a user with the specified name and a given component of * the calling package as profile owner. The UserHandle returned by this method should not be Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +29 −7 Original line number Diff line number Diff line Loading @@ -526,7 +526,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // TODO(b/35385311): Keep track of metadata in TrustedCertificateStore instead. Set<String> mOwnerInstalledCaCerts = new ArraySet<>(); // Used for initialization of users created by createAndManageUsers. // Used for initialization of users created by createAndManageUser. boolean mAdminBroadcastPending = false; PersistableBundle mInitBundle = null; Loading Loading @@ -4255,6 +4255,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mInjector.binderRestoreCallingIdentity(token); } } @Override public boolean resetPassword(String passwordOrNull, int flags) throws RemoteException { final int callingUid = mInjector.binderGetCallingUid(); Loading Loading @@ -7375,9 +7376,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private void enableIfNecessary(String packageName, int userId) { try { ApplicationInfo ai = mIPackageManager.getApplicationInfo(packageName, PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, userId); final ApplicationInfo ai = mIPackageManager.getApplicationInfo(packageName, PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, userId); if (ai.enabledSetting == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) { mIPackageManager.setApplicationEnabledSetting(packageName, Loading Loading @@ -8131,8 +8131,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mInjector.binderGetCallingUserHandle().isSystem()) { throw new SecurityException("createAndManageUser was called from non-system user"); } if (!mInjector.userManagerIsSplitSystemUser() && (flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0) { final boolean ephemeral = (flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0; final boolean demo = (flags & DevicePolicyManager.MAKE_USER_DEMO) != 0 && UserManager.isDeviceInDemoMode(mContext); if (ephemeral && !mInjector.userManagerIsSplitSystemUser() && !demo) { throw new IllegalArgumentException( "Ephemeral users are only supported on systems with a split system user."); } Loading @@ -8144,9 +8146,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final long id = mInjector.binderClearCallingIdentity(); try { int userInfoFlags = 0; if ((flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0) { if (ephemeral) { userInfoFlags |= UserInfo.FLAG_EPHEMERAL; } if (demo) { userInfoFlags |= UserInfo.FLAG_DEMO; } UserInfo userInfo = mUserManagerInternal.createUserEvenWhenDisallowed(name, userInfoFlags); if (userInfo != null) { Loading Loading @@ -8178,6 +8183,23 @@ 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
services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +71 −1 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import static org.mockito.Matchers.isNull; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.nullable; import static org.mockito.Mockito.reset; Loading @@ -53,6 +54,7 @@ import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.PasswordMetrics; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; Loading Loading @@ -338,7 +340,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Next, add one more admin. // Before doing so, update the application info, now it's enabled. setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID, PackageManager.COMPONENT_ENABLED_STATE_ENABLED); PackageManager.COMPONENT_ENABLED_STATE_DEFAULT); dpm.setActiveAdmin(admin2, /* replace =*/ false); Loading Loading @@ -380,6 +382,74 @@ 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/DpmMockContext.java +5 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.res.Resources; import android.os.Bundle; import android.os.Handler; import android.os.UserHandle; import android.os.UserManagerInternal; import android.test.mock.MockContext; import android.util.ArrayMap; Loading Loading @@ -196,6 +197,10 @@ public class DpmMockContext extends MockContext { return mMockSystemServices.packageManager; } public UserManagerInternal getUserManagerInternal() { return mMockSystemServices.userManagerInternal; } @Override public void enforceCallingOrSelfPermission(String permission, String message) { if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) { Loading