Merge "Try to work on test flakyness." into oc-dr1-dev
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ea0829f..a749fe70 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -5982,6 +5982,13 @@
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
* persisted as user handles are recycled as users are removed and created. If you need to
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 93a0742..e375a21 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -314,6 +314,7 @@
<style name="LockPatternStyle">
<item name="*android:regularColor">?android:attr/textColorPrimaryInverse</item>
<item name="*android:successColor">?android:attr/textColorPrimaryInverse</item>
+ <item name="*android:errorColor">?android:attr/colorError</item>
</style>
<!-- Overlay manager may replace this theme -->
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 8cac6e0..73bb13a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -526,7 +526,7 @@
// 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 @@
mInjector.binderRestoreCallingIdentity(token);
}
}
+
@Override
public boolean resetPassword(String passwordOrNull, int flags) throws RemoteException {
final int callingUid = mInjector.binderGetCallingUid();
@@ -7375,9 +7376,8 @@
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 @@
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 @@
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 @@
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.
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 c58b733..bad9b5b 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -34,6 +34,7 @@
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.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 @@
// 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 @@
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/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index 408ee9c..9702118 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -29,6 +29,7 @@
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 @@
return mMockSystemServices.packageManager;
}
+ public UserManagerInternal getUserManagerInternal() {
+ return mMockSystemServices.userManagerInternal;
+ }
+
@Override
public void enforceCallingOrSelfPermission(String permission, String message) {
if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) {