diff options
| author | 2017-08-09 14:16:03 +0100 | |
|---|---|---|
| committer | 2017-08-31 16:11:47 +0100 | |
| commit | 77c94a9c03cf92a2325b442c863a19e5fd58f255 (patch) | |
| tree | ea80c815fefb56b8bb314b8f7913268044a18cdf | |
| parent | b1671e0e1affc085e0e196e79ee1185d03a5ae91 (diff) | |
Create a flag to allow starting managed user in background
Currently DPM.createAndManageUser does not start the user in the
background, leading to a potential race between user having access to
the secondary user and admin having time to push policies. To mitigate
this we're adding a flag that allows secondary users to be started in
background as part of the API. The admin can then apply policies before
switching to that user.
Bug: 64382185
Test: cts-tradefed run singleCommand cts -m DevicePolicyManager --test
com.android.cts.devicepolicy.DeviceOwnerTest#testCreateAndManageUser_StartUserInBackground
--abi arm64-v8a
Change-Id: Id6f6ab7584a249680c8554c21977cbb69a220332
| -rw-r--r-- | api/current.txt | 1 | ||||
| -rw-r--r-- | api/system-current.txt | 1 | ||||
| -rw-r--r-- | api/test-current.txt | 1 | ||||
| -rw-r--r-- | core/java/android/app/admin/DevicePolicyManager.java | 22 | ||||
| -rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 28 |
5 files changed, 42 insertions, 11 deletions
diff --git a/api/current.txt b/api/current.txt index 97facecbd681..f1f6fb7532f3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -6538,6 +6538,7 @@ package android.app.admin { field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2 field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1 field public static final int SKIP_SETUP_WIZARD = 1; // 0x1 + field public static final int START_USER_IN_BACKGROUND = 8; // 0x8 field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1 field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2 } diff --git a/api/system-current.txt b/api/system-current.txt index 2212fd0843cd..6c497293e344 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -6780,6 +6780,7 @@ package android.app.admin { field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2 field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1 field public static final int SKIP_SETUP_WIZARD = 1; // 0x1 + field public static final int START_USER_IN_BACKGROUND = 8; // 0x8 field public static final int STATE_USER_PROFILE_COMPLETE = 4; // 0x4 field public static final int STATE_USER_SETUP_COMPLETE = 2; // 0x2 field public static final int STATE_USER_SETUP_FINALIZED = 3; // 0x3 diff --git a/api/test-current.txt b/api/test-current.txt index 36515a555c99..464ec492fdbc 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -6569,6 +6569,7 @@ package android.app.admin { field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2 field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1 field public static final int SKIP_SETUP_WIZARD = 1; // 0x1 + field public static final int START_USER_IN_BACKGROUND = 8; // 0x8 field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1 field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2 } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index d8da8c5bee82..b0c985010830 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -5980,6 +5980,26 @@ public class DevicePolicyManager { public static final int MAKE_USER_DEMO = 0x0004; /** + * Flag used by {@link #createAndManageUser} to specificy that the newly created user should be + * started in the background as part of the user creation. + */ + // TODO: Investigate solutions for the case where reboot happens before setup is completed. + public static final int START_USER_IN_BACKGROUND = 0x0008; + + /** + * @hide + */ + @IntDef( + flag = true, + prefix = {"SKIP_", "MAKE_USER_", "START_"}, + value = {SKIP_SETUP_WIZARD, MAKE_USER_EPHEMERAL, MAKE_USER_DEMO, + START_USER_IN_BACKGROUND} + ) + @Retention(RetentionPolicy.SOURCE) + public @interface CreateAndManageUserFlags {} + + + /** * 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 @@ -6010,7 +6030,7 @@ public class DevicePolicyManager { public @Nullable UserHandle createAndManageUser(@NonNull ComponentName admin, @NonNull String name, @NonNull ComponentName profileOwner, @Nullable PersistableBundle adminExtras, - int flags) { + @CreateAndManageUserFlags int flags) { throwIfParentInstance("createAndManageUser"); try { return mService.createAndManageUser(admin, name, profileOwner, adminExtras, flags); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index ab919a27802e..77ce7e5dd596 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -43,6 +43,7 @@ import static android.app.admin.DevicePolicyManager.DELEGATION_PACKAGE_ACCESS; import static android.app.admin.DevicePolicyManager.DELEGATION_PERMISSION_GRANT; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; import static android.app.admin.DevicePolicyManager.PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER; +import static android.app.admin.DevicePolicyManager.START_USER_IN_BACKGROUND; import static android.app.admin.DevicePolicyManager.WIPE_EUICC; import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE; import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA; @@ -8157,7 +8158,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (user == null) { return null; } - // Set admin. final long id = mInjector.binderClearCallingIdentity(); try { final String adminPkg = admin.getPackageName(); @@ -8170,30 +8170,38 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY); } } catch (RemoteException e) { - Slog.e(LOG_TAG, "Failed to make remote calls for createAndManageUser, " - + "removing created user", e); - mUserManager.removeUser(user.getIdentifier()); - return null; + // Does not happen, same process } + // Set admin. 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. - synchronized(this) { + final String ownerName = getProfileOwnerName(Process.myUserHandle().getIdentifier()); + setProfileOwner(profileOwner, ownerName, userHandle); + + synchronized (this) { DevicePolicyData policyData = getUserData(userHandle); policyData.mInitBundle = adminExtras; policyData.mAdminBroadcastPending = true; saveSettingsLocked(userHandle); } - final String ownerName = getProfileOwnerName(Process.myUserHandle().getIdentifier()); - setProfileOwner(profileOwner, ownerName, userHandle); if ((flags & DevicePolicyManager.SKIP_SETUP_WIZARD) != 0) { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1, userHandle); } + if ((flags & START_USER_IN_BACKGROUND) != 0) { + try { + mInjector.getIActivityManager().startUserInBackground(user.getIdentifier()); + } catch (RemoteException re) { + // Does not happen, same process + } + } + return user; + } catch (Throwable re) { + mUserManager.removeUser(user.getIdentifier()); + return null; } finally { mInjector.binderRestoreCallingIdentity(id); } |