Merge "Support demo mode and demo users" into oc-dr1-dev
am: 2f87ca1637
Change-Id: I429ce9d2c273c9b093e2f9fe789d126a0b95f198
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
@@ -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,
|
||||
@@ -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.");
|
||||
}
|
||||
@@ -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) {
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user