diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java index 721a444f0f15b..cccc9294c2d5d 100644 --- a/core/java/android/app/admin/DeviceAdminReceiver.java +++ b/core/java/android/app/admin/DeviceAdminReceiver.java @@ -585,6 +585,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @param intent The received intent as per {@link #onReceive}. */ public void onEnabled(@NonNull Context context, @NonNull Intent intent) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onEnabled() on user " + context.getUserId()); + } } /** @@ -600,6 +603,10 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public @Nullable CharSequence onDisableRequested(@NonNull Context context, @NonNull Intent intent) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onDisableRequested() on user " + + context.getUserId()); + } return null; } @@ -612,6 +619,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @param intent The received intent as per {@link #onReceive}. */ public void onDisabled(@NonNull Context context, @NonNull Intent intent) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onDisabled() on user " + context.getUserId()); + } } /** @@ -786,6 +796,10 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @param intent The received intent as per {@link #onReceive}. */ public void onProfileProvisioningComplete(@NonNull Context context, @NonNull Intent intent) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onProfileProvisioningComplete() on user " + + context.getUserId()); + } } /** @@ -961,6 +975,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onUserAdded(@NonNull Context context, @NonNull Intent intent, @NonNull UserHandle addedUser) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onUserAdded() on user " + context.getUserId()); + } } /** @@ -974,6 +991,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onUserRemoved(@NonNull Context context, @NonNull Intent intent, @NonNull UserHandle removedUser) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onUserRemoved() on user " + context.getUserId()); + } } /** @@ -987,6 +1007,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onUserStarted(@NonNull Context context, @NonNull Intent intent, @NonNull UserHandle startedUser) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onUserStarted() on user " + context.getUserId()); + } } /** @@ -1000,6 +1023,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onUserStopped(@NonNull Context context, @NonNull Intent intent, @NonNull UserHandle stoppedUser) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onUserStopped() on user " + context.getUserId()); + } } /** @@ -1013,6 +1039,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onUserSwitched(@NonNull Context context, @NonNull Intent intent, @NonNull UserHandle switchedUser) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onUserSwitched() on user " + context.getUserId()); + } } /** @@ -1104,7 +1133,8 @@ public class DeviceAdminReceiver extends BroadcastReceiver { public void onReceive(@NonNull Context context, @NonNull Intent intent) { String action = intent.getAction(); if (LOCAL_LOGV) { - Log.v(TAG, "onReceive(): received " + action + " on user " + context.getUserId()); + Log.v(TAG, getClass().getName() + ".onReceive(): received " + action + " on user " + + context.getUserId()); } if (ACTION_PASSWORD_CHANGED.equals(action)) { diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java index c17d2e4b0c62c..eb2de60127451 100644 --- a/services/core/java/com/android/server/pm/UserManagerInternal.java +++ b/services/core/java/com/android/server/pm/UserManagerInternal.java @@ -63,8 +63,13 @@ public abstract class UserManagerInternal { */ public interface UserLifecycleListener { - /** Called when a new user is created. */ - default void onUserCreated(UserInfo user) {} + /** + * Called when a new user is created. + * + * @param user new user. + * @param token token passed to the method that created the user. + */ + default void onUserCreated(UserInfo user, @Nullable Object token) {} /** Called when an existing user is removed. */ default void onUserRemoved(UserInfo user) {} @@ -179,10 +184,12 @@ public abstract class UserManagerInternal { * {@link UserManager#DISALLOW_ADD_USER} and {@link UserManager#DISALLOW_ADD_MANAGED_PROFILE} * *
Called by the {@link com.android.server.devicepolicy.DevicePolicyManagerService} when - * createAndManageUser is called by the device owner. + * createAndManageUser is called by the device owner; it uses {@code token} to block until + * the user is created (as it will be passed back to it through + * {@link UserLifecycleListener#onUserCreated(UserInfo, Object)}); */ public abstract UserInfo createUserEvenWhenDisallowed(String name, String userType, - int flags, String[] disallowedPackages) + int flags, String[] disallowedPackages, @Nullable Object token) throws UserManager.CheckedUserOperationException; /** diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 24c27bedb9f7a..e10b052ece7a3 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -3309,7 +3309,7 @@ public class UserManagerService extends IUserManager.Stub { checkManageOrCreateUsersPermission(flags); try { return createUserInternalUnchecked(name, userType, flags, userId, - /* preCreate= */ false, disallowedPackages); + /* preCreate= */ false, disallowedPackages, /* token= */ null); } catch (UserManager.CheckedUserOperationException e) { throw e.toServiceSpecificException(); } @@ -3342,7 +3342,7 @@ public class UserManagerService extends IUserManager.Stub { try { return createUserInternalUnchecked(/* name= */ null, userType, flags, /* parentId= */ UserHandle.USER_NULL, /* preCreate= */ true, - /* disallowedPackages= */ null); + /* disallowedPackages= */ null, /* token= */ null); } catch (UserManager.CheckedUserOperationException e) { throw e.toServiceSpecificException(); } @@ -3358,12 +3358,13 @@ public class UserManagerService extends IUserManager.Stub { enforceUserRestriction(restriction, UserHandle.getCallingUserId(), "Cannot add user"); return createUserInternalUnchecked(name, userType, flags, parentId, - /* preCreate= */ false, disallowedPackages); + /* preCreate= */ false, disallowedPackages, /* token= */ null); } private UserInfo createUserInternalUnchecked(@Nullable String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, - boolean preCreate, @Nullable String[] disallowedPackages) + boolean preCreate, @Nullable String[] disallowedPackages, + @Nullable Object token) throws UserManager.CheckedUserOperationException { final int nextProbableUserId = getNextAvailableId(); final TimingsTraceAndSlog t = new TimingsTraceAndSlog(); @@ -3372,7 +3373,7 @@ public class UserManagerService extends IUserManager.Stub { UserInfo newUser = null; try { newUser = createUserInternalUncheckedNoTracing(name, userType, flags, parentId, - preCreate, disallowedPackages, t); + preCreate, disallowedPackages, t, token); return newUser; } finally { logUserCreateJourneyFinish(sessionId, nextProbableUserId, newUser != null); @@ -3383,7 +3384,8 @@ public class UserManagerService extends IUserManager.Stub { private UserInfo createUserInternalUncheckedNoTracing(@Nullable String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, boolean preCreate, @Nullable String[] disallowedPackages, - @NonNull TimingsTraceAndSlog t) throws UserManager.CheckedUserOperationException { + @NonNull TimingsTraceAndSlog t, @Nullable Object token) + throws UserManager.CheckedUserOperationException { final UserTypeDetails userTypeDetails = mUserTypes.get(userType); if (userTypeDetails == null) { Slog.e(LOG_TAG, "Cannot create user of invalid user type: " + userType); @@ -3409,7 +3411,8 @@ public class UserManagerService extends IUserManager.Stub { // Try to use a pre-created user (if available). if (!preCreate && parentId < 0 && isUserTypeEligibleForPreCreation(userTypeDetails)) { - final UserInfo preCreatedUser = convertPreCreatedUserIfPossible(userType, flags, name); + final UserInfo preCreatedUser = convertPreCreatedUserIfPossible(userType, flags, name, + token); if (preCreatedUser != null) { return preCreatedUser; } @@ -3588,7 +3591,7 @@ public class UserManagerService extends IUserManager.Stub { Slog.w(LOG_TAG, "could not start pre-created user " + userId, e); } } else { - dispatchUserAdded(userInfo); + dispatchUserAdded(userInfo, token); } } finally { @@ -3688,7 +3691,7 @@ public class UserManagerService extends IUserManager.Stub { * @return the converted user, or {@code null} if no pre-created user could be converted. */ private @Nullable UserInfo convertPreCreatedUserIfPossible(String userType, - @UserInfoFlag int flags, String name) { + @UserInfoFlag int flags, String name, @Nullable Object token) { final UserData preCreatedUserData; synchronized (mUsersLock) { preCreatedUserData = getPreCreatedUserLU(userType); @@ -3726,7 +3729,7 @@ public class UserManagerService extends IUserManager.Stub { } updateUserIds(); mPm.onNewUserCreated(preCreatedUser.id, /* convertedFromPreCreated= */ true); - dispatchUserAdded(preCreatedUser); + dispatchUserAdded(preCreatedUser, token); return preCreatedUser; } @@ -3758,11 +3761,11 @@ public class UserManagerService extends IUserManager.Stub { return (now > EPOCH_PLUS_30_YEARS) ? now : 0; } - private void dispatchUserAdded(@NonNull UserInfo userInfo) { + private void dispatchUserAdded(@NonNull UserInfo userInfo, @Nullable Object token) { // Notify internal listeners first... synchronized (mUserLifecycleListeners) { for (int i = 0; i < mUserLifecycleListeners.size(); i++) { - mUserLifecycleListeners.get(i).onUserCreated(userInfo); + mUserLifecycleListeners.get(i).onUserCreated(userInfo, token); } } @@ -5367,10 +5370,10 @@ public class UserManagerService extends IUserManager.Stub { @Override public UserInfo createUserEvenWhenDisallowed(String name, @NonNull String userType, - @UserInfoFlag int flags, String[] disallowedPackages) + @UserInfoFlag int flags, String[] disallowedPackages, @Nullable Object token) throws UserManager.CheckedUserOperationException { return createUserInternalUnchecked(name, userType, flags, - UserHandle.USER_NULL, /* preCreated= */ false, disallowedPackages); + UserHandle.USER_NULL, /* preCreated= */ false, disallowedPackages, token); } @Override diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 524892b2ec4bc..aabe65030bf0d 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -715,6 +715,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Nullable private DevicePolicySafetyChecker mSafetyChecker; + @GuardedBy("getLockObject()") + private final ArrayList