Loading core/java/android/app/admin/DeviceAdminReceiver.java +31 −1 Original line number Diff line number Diff line Loading @@ -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()); } } /** Loading @@ -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; } Loading @@ -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()); } } /** Loading Loading @@ -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()); } } /** Loading Loading @@ -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()); } } /** Loading @@ -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()); } } /** Loading @@ -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()); } } /** Loading @@ -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()); } } /** Loading @@ -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()); } } /** Loading Loading @@ -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)) { Loading services/core/java/com/android/server/pm/UserManagerInternal.java +11 −4 Original line number Diff line number Diff line Loading @@ -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) {} Loading Loading @@ -179,10 +184,12 @@ public abstract class UserManagerInternal { * {@link UserManager#DISALLOW_ADD_USER} and {@link UserManager#DISALLOW_ADD_MANAGED_PROFILE} * * <p>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; /** Loading services/core/java/com/android/server/pm/UserManagerService.java +17 −14 Original line number Diff line number Diff line Loading @@ -3323,7 +3323,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(); } Loading Loading @@ -3356,7 +3356,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(); } Loading @@ -3372,12 +3372,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(); Loading @@ -3386,7 +3387,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); Loading @@ -3397,7 +3398,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); Loading @@ -3423,7 +3425,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; } Loading Loading @@ -3602,7 +3605,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 { Loading Loading @@ -3702,7 +3705,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); Loading Loading @@ -3740,7 +3743,7 @@ public class UserManagerService extends IUserManager.Stub { } updateUserIds(); mPm.onNewUserCreated(preCreatedUser.id, /* convertedFromPreCreated= */ true); dispatchUserAdded(preCreatedUser); dispatchUserAdded(preCreatedUser, token); return preCreatedUser; } Loading Loading @@ -3772,11 +3775,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); } } Loading Loading @@ -5381,10 +5384,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 Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +58 −28 Original line number Diff line number Diff line Loading @@ -715,6 +715,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Nullable private DevicePolicySafetyChecker mSafetyChecker; @GuardedBy("getLockObject()") private final ArrayList<Object> mPendingUserCreatedCallbackTokens = new ArrayList<>(); public static final class Lifecycle extends SystemService { private BaseIDevicePolicyManager mService; Loading Loading @@ -965,8 +968,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { private final class UserLifecycleListener implements UserManagerInternal.UserLifecycleListener { @Override public void onUserCreated(UserInfo user) { mHandler.post(() -> handleNewUserCreated(user)); public void onUserCreated(UserInfo user, Object token) { mHandler.post(() -> handleNewUserCreated(user, token)); } } Loading Loading @@ -3151,11 +3154,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } setActiveAdmin(adminReceiver, refreshing, userHandle, null); } private void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle, Bundle onEnableData) { Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); final CallerIdentity caller = getCallerIdentity(); Loading Loading @@ -3198,7 +3196,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } saveSettingsLocked(userHandle); sendAdminCommandLocked(newAdmin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED, onEnableData, null); /* adminExtras= */ null, /* result= */ null); }); } } Loading Loading @@ -9190,6 +9188,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { pw.println("Encryption Status: " + getEncryptionStatusName(getEncryptionStatus())); pw.println(); if (mPendingUserCreatedCallbackTokens.isEmpty()) { pw.println("no pending user created callback tokens"); } else { int size = mPendingUserCreatedCallbackTokens.size(); pw.printf("%d pending user created callback token%s\n", size, (size == 1 ? "" : "s")); } pw.println(); mPolicyCache.dump(pw); pw.println(); mStateCache.dump(pw); Loading Loading @@ -9946,8 +9954,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { clearInitBundle = sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED, initBundle == null ? null : new Bundle(initBundle), null /* result receiver */, true /* send in foreground */); /* result= */ null , /* inForeground= */ true); } if (clearInitBundle) { // If there's no admin or we've successfully called the admin, clear the init bundle Loading Loading @@ -10020,9 +10028,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { UserHandle.myUserId(), ACTION_PROVISION_MANAGED_USER).toArray( new String[0]); } Object token = new Object(); Slog.d(LOG_TAG, "Adding new pending token: " + token); mPendingUserCreatedCallbackTokens.add(token); try { UserInfo userInfo = mUserManagerInternal.createUserEvenWhenDisallowed(name, userType, userInfoFlags, disallowedPackages); userType, userInfoFlags, disallowedPackages, token); if (userInfo != null) { user = userInfo.getUserHandle(); } Loading @@ -10032,7 +10044,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } finally { mInjector.binderRestoreCallingIdentity(id); } } } // synchronized if (user == null) { if (targetSdkVersion >= Build.VERSION_CODES.P) { throw new ServiceSpecificException(UserManager.USER_OPERATION_ERROR_UNKNOWN, Loading @@ -10054,14 +10067,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final long id = mInjector.binderClearCallingIdentity(); try { if (!mInjector.userManagerIsHeadlessSystemUserMode()) { manageUserUnchecked(admin, profileOwner, userHandle, adminExtras, /* showDisclaimer= */ true); } else if (VERBOSE_LOG) { Slog.v(LOG_TAG, "createAndManageUser(): skipping manageUserUnchecked() on user " + userHandle + " on headless system user as it will be called by " + "handleNewUserCreated()"); } if ((flags & DevicePolicyManager.SKIP_SETUP_WIZARD) != 0) { Settings.Secure.putIntForUser(mContext.getContentResolver(), Loading @@ -10083,7 +10090,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } private void manageUserUnchecked(ComponentName admin, ComponentName profileOwner, @UserIdInt int userId, PersistableBundle adminExtras, boolean showDisclaimer) { @UserIdInt int userId, @Nullable PersistableBundle adminExtras, boolean showDisclaimer) { synchronized (getLockObject()) { if (VERBOSE_LOG) { Slog.v(LOG_TAG, "manageUserUnchecked(): admin=" + admin + ", po=" + profileOwner + ", userId=" + userId + ", hasAdminExtras=" + (adminExtras != null) + ", showDisclaimer=" + showDisclaimer); } } final String adminPkg = admin.getPackageName(); try { // Install the profile owner if not present. Loading Loading @@ -10113,23 +10128,37 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { ? DevicePolicyData.NEW_USER_DISCLAIMER_NEEDED : DevicePolicyData.NEW_USER_DISCLAIMER_NOT_NEEDED; saveSettingsLocked(userId); } } private void handleNewUserCreated(UserInfo user) { if (VERBOSE_LOG) Slog.v(LOG_TAG, "handleNewUserCreated(): " + user.toFullString()); if (!mOwners.hasDeviceOwner() || !user.isFull() || user.isManagedProfile()) return; private void handleNewUserCreated(UserInfo user, @Nullable Object token) { if (VERBOSE_LOG) { Slog.v(LOG_TAG, "handleNewUserCreated(): user=" + user.toFullString() + ", token=" + token); } final int userId = user.id; if (token != null) { synchronized (getLockObject()) { if (mPendingUserCreatedCallbackTokens.contains(token)) { // Ignore because it was triggered by createAndManageUser() Slog.d(LOG_TAG, "handleNewUserCreated(): ignoring for user " + userId + " due to token" + token); mPendingUserCreatedCallbackTokens.remove(token); return; } } } if (!mOwners.hasDeviceOwner() || !user.isFull() || user.isManagedProfile()) return; if (mInjector.userManagerIsHeadlessSystemUserMode()) { ComponentName admin = mOwners.getDeviceOwnerComponent(); Slog.i(LOG_TAG, "Automatically setting profile owner (" + admin + ") on new user " + userId); manageUserUnchecked(/* deviceOwner= */ admin, /* profileOwner= */ admin, /* managedUser= */ userId, /* adminExtras= */ null, /* showDisclaimer= */ true); /* managedUser= */ userId, /* adminExtras= */ null, /* showDisclaimer= */ true); } else { Log.i(LOG_TAG, "User " + userId + " added on DO mode; setting ShowNewUserDisclaimer"); setShowNewUserDisclaimer(userId, DevicePolicyData.NEW_USER_DISCLAIMER_NEEDED); Loading Loading @@ -10250,11 +10279,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final long id = mInjector.binderClearCallingIdentity(); try { if (!mInjector.getActivityManagerInternal().canStartMoreUsers()) { Log.w(LOG_TAG, "Cannot start more users in background"); Log.w(LOG_TAG, "Cannot start user " + userId + ", too many users in background"); return UserManager.USER_OPERATION_ERROR_MAX_RUNNING_USERS; } if (mInjector.getIActivityManager().startUserInBackground(userId)) { Log.i(LOG_TAG, "Started used " + userId + " in background"); return UserManager.USER_OPERATION_SUCCESS; } else { return UserManager.USER_OPERATION_ERROR_UNKNOWN; Loading Loading
core/java/android/app/admin/DeviceAdminReceiver.java +31 −1 Original line number Diff line number Diff line Loading @@ -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()); } } /** Loading @@ -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; } Loading @@ -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()); } } /** Loading Loading @@ -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()); } } /** Loading Loading @@ -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()); } } /** Loading @@ -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()); } } /** Loading @@ -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()); } } /** Loading @@ -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()); } } /** Loading @@ -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()); } } /** Loading Loading @@ -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)) { Loading
services/core/java/com/android/server/pm/UserManagerInternal.java +11 −4 Original line number Diff line number Diff line Loading @@ -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) {} Loading Loading @@ -179,10 +184,12 @@ public abstract class UserManagerInternal { * {@link UserManager#DISALLOW_ADD_USER} and {@link UserManager#DISALLOW_ADD_MANAGED_PROFILE} * * <p>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; /** Loading
services/core/java/com/android/server/pm/UserManagerService.java +17 −14 Original line number Diff line number Diff line Loading @@ -3323,7 +3323,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(); } Loading Loading @@ -3356,7 +3356,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(); } Loading @@ -3372,12 +3372,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(); Loading @@ -3386,7 +3387,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); Loading @@ -3397,7 +3398,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); Loading @@ -3423,7 +3425,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; } Loading Loading @@ -3602,7 +3605,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 { Loading Loading @@ -3702,7 +3705,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); Loading Loading @@ -3740,7 +3743,7 @@ public class UserManagerService extends IUserManager.Stub { } updateUserIds(); mPm.onNewUserCreated(preCreatedUser.id, /* convertedFromPreCreated= */ true); dispatchUserAdded(preCreatedUser); dispatchUserAdded(preCreatedUser, token); return preCreatedUser; } Loading Loading @@ -3772,11 +3775,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); } } Loading Loading @@ -5381,10 +5384,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 Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +58 −28 Original line number Diff line number Diff line Loading @@ -715,6 +715,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Nullable private DevicePolicySafetyChecker mSafetyChecker; @GuardedBy("getLockObject()") private final ArrayList<Object> mPendingUserCreatedCallbackTokens = new ArrayList<>(); public static final class Lifecycle extends SystemService { private BaseIDevicePolicyManager mService; Loading Loading @@ -965,8 +968,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { private final class UserLifecycleListener implements UserManagerInternal.UserLifecycleListener { @Override public void onUserCreated(UserInfo user) { mHandler.post(() -> handleNewUserCreated(user)); public void onUserCreated(UserInfo user, Object token) { mHandler.post(() -> handleNewUserCreated(user, token)); } } Loading Loading @@ -3151,11 +3154,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } setActiveAdmin(adminReceiver, refreshing, userHandle, null); } private void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle, Bundle onEnableData) { Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); final CallerIdentity caller = getCallerIdentity(); Loading Loading @@ -3198,7 +3196,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } saveSettingsLocked(userHandle); sendAdminCommandLocked(newAdmin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED, onEnableData, null); /* adminExtras= */ null, /* result= */ null); }); } } Loading Loading @@ -9190,6 +9188,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { pw.println("Encryption Status: " + getEncryptionStatusName(getEncryptionStatus())); pw.println(); if (mPendingUserCreatedCallbackTokens.isEmpty()) { pw.println("no pending user created callback tokens"); } else { int size = mPendingUserCreatedCallbackTokens.size(); pw.printf("%d pending user created callback token%s\n", size, (size == 1 ? "" : "s")); } pw.println(); mPolicyCache.dump(pw); pw.println(); mStateCache.dump(pw); Loading Loading @@ -9946,8 +9954,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { clearInitBundle = sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED, initBundle == null ? null : new Bundle(initBundle), null /* result receiver */, true /* send in foreground */); /* result= */ null , /* inForeground= */ true); } if (clearInitBundle) { // If there's no admin or we've successfully called the admin, clear the init bundle Loading Loading @@ -10020,9 +10028,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { UserHandle.myUserId(), ACTION_PROVISION_MANAGED_USER).toArray( new String[0]); } Object token = new Object(); Slog.d(LOG_TAG, "Adding new pending token: " + token); mPendingUserCreatedCallbackTokens.add(token); try { UserInfo userInfo = mUserManagerInternal.createUserEvenWhenDisallowed(name, userType, userInfoFlags, disallowedPackages); userType, userInfoFlags, disallowedPackages, token); if (userInfo != null) { user = userInfo.getUserHandle(); } Loading @@ -10032,7 +10044,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } finally { mInjector.binderRestoreCallingIdentity(id); } } } // synchronized if (user == null) { if (targetSdkVersion >= Build.VERSION_CODES.P) { throw new ServiceSpecificException(UserManager.USER_OPERATION_ERROR_UNKNOWN, Loading @@ -10054,14 +10067,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final long id = mInjector.binderClearCallingIdentity(); try { if (!mInjector.userManagerIsHeadlessSystemUserMode()) { manageUserUnchecked(admin, profileOwner, userHandle, adminExtras, /* showDisclaimer= */ true); } else if (VERBOSE_LOG) { Slog.v(LOG_TAG, "createAndManageUser(): skipping manageUserUnchecked() on user " + userHandle + " on headless system user as it will be called by " + "handleNewUserCreated()"); } if ((flags & DevicePolicyManager.SKIP_SETUP_WIZARD) != 0) { Settings.Secure.putIntForUser(mContext.getContentResolver(), Loading @@ -10083,7 +10090,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } private void manageUserUnchecked(ComponentName admin, ComponentName profileOwner, @UserIdInt int userId, PersistableBundle adminExtras, boolean showDisclaimer) { @UserIdInt int userId, @Nullable PersistableBundle adminExtras, boolean showDisclaimer) { synchronized (getLockObject()) { if (VERBOSE_LOG) { Slog.v(LOG_TAG, "manageUserUnchecked(): admin=" + admin + ", po=" + profileOwner + ", userId=" + userId + ", hasAdminExtras=" + (adminExtras != null) + ", showDisclaimer=" + showDisclaimer); } } final String adminPkg = admin.getPackageName(); try { // Install the profile owner if not present. Loading Loading @@ -10113,23 +10128,37 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { ? DevicePolicyData.NEW_USER_DISCLAIMER_NEEDED : DevicePolicyData.NEW_USER_DISCLAIMER_NOT_NEEDED; saveSettingsLocked(userId); } } private void handleNewUserCreated(UserInfo user) { if (VERBOSE_LOG) Slog.v(LOG_TAG, "handleNewUserCreated(): " + user.toFullString()); if (!mOwners.hasDeviceOwner() || !user.isFull() || user.isManagedProfile()) return; private void handleNewUserCreated(UserInfo user, @Nullable Object token) { if (VERBOSE_LOG) { Slog.v(LOG_TAG, "handleNewUserCreated(): user=" + user.toFullString() + ", token=" + token); } final int userId = user.id; if (token != null) { synchronized (getLockObject()) { if (mPendingUserCreatedCallbackTokens.contains(token)) { // Ignore because it was triggered by createAndManageUser() Slog.d(LOG_TAG, "handleNewUserCreated(): ignoring for user " + userId + " due to token" + token); mPendingUserCreatedCallbackTokens.remove(token); return; } } } if (!mOwners.hasDeviceOwner() || !user.isFull() || user.isManagedProfile()) return; if (mInjector.userManagerIsHeadlessSystemUserMode()) { ComponentName admin = mOwners.getDeviceOwnerComponent(); Slog.i(LOG_TAG, "Automatically setting profile owner (" + admin + ") on new user " + userId); manageUserUnchecked(/* deviceOwner= */ admin, /* profileOwner= */ admin, /* managedUser= */ userId, /* adminExtras= */ null, /* showDisclaimer= */ true); /* managedUser= */ userId, /* adminExtras= */ null, /* showDisclaimer= */ true); } else { Log.i(LOG_TAG, "User " + userId + " added on DO mode; setting ShowNewUserDisclaimer"); setShowNewUserDisclaimer(userId, DevicePolicyData.NEW_USER_DISCLAIMER_NEEDED); Loading Loading @@ -10250,11 +10279,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final long id = mInjector.binderClearCallingIdentity(); try { if (!mInjector.getActivityManagerInternal().canStartMoreUsers()) { Log.w(LOG_TAG, "Cannot start more users in background"); Log.w(LOG_TAG, "Cannot start user " + userId + ", too many users in background"); return UserManager.USER_OPERATION_ERROR_MAX_RUNNING_USERS; } if (mInjector.getIActivityManager().startUserInBackground(userId)) { Log.i(LOG_TAG, "Started used " + userId + " in background"); return UserManager.USER_OPERATION_SUCCESS; } else { return UserManager.USER_OPERATION_ERROR_UNKNOWN; Loading