Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2cdcc7d3 authored by Amith Yamasani's avatar Amith Yamasani Committed by Android (Google) Code Review
Browse files

Merge "Make it possible to remove current user" into lmp-dev

parents 17a1b486 1df14730
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -52,4 +52,5 @@ interface IUserManager {
    void removeRestrictions();
    void removeRestrictions();
    void setDefaultGuestRestrictions(in Bundle restrictions);
    void setDefaultGuestRestrictions(in Bundle restrictions);
    Bundle getDefaultGuestRestrictions();
    Bundle getDefaultGuestRestrictions();
    boolean markGuestForDeletion(int userHandle);
}
}
+16 −0
Original line number Original line Diff line number Diff line
@@ -675,6 +675,22 @@ public class UserManager {
        }
        }
    }
    }


    /**
     * @hide
     * Marks the guest user for deletion to allow a new guest to be created before deleting
     * the current user who is a guest.
     * @param userHandle
     * @return
     */
    public boolean markGuestForDeletion(int userHandle) {
        try {
            return mService.markGuestForDeletion(userHandle);
        } catch (RemoteException re) {
            Log.w(TAG, "Could not mark guest for deletion", re);
            return false;
        }
    }

    /**
    /**
     * Sets the user as enabled, if such an user exists.
     * Sets the user as enabled, if such an user exists.
     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+7 −1
Original line number Original line Diff line number Diff line
@@ -112,17 +112,23 @@ public class GuestResumeSessionReceiver extends BroadcastReceiver {
            return;
            return;
        }
        }


        userManager.removeUser(currentUser.id);
        boolean marked = userManager.markGuestForDeletion(currentUser.id);
        if (!marked) {
            Log.w(TAG, "Couldn't mark the guest for deletion for user " + userId);
            return;
        }
        UserInfo newGuest = userManager.createGuest(context, currentUser.name);
        UserInfo newGuest = userManager.createGuest(context, currentUser.name);


        try {
        try {
            if (newGuest == null) {
            if (newGuest == null) {
                Log.e(TAG, "Could not create new guest, switching back to owner");
                Log.e(TAG, "Could not create new guest, switching back to owner");
                ActivityManagerNative.getDefault().switchUser(UserHandle.USER_OWNER);
                ActivityManagerNative.getDefault().switchUser(UserHandle.USER_OWNER);
                userManager.removeUser(currentUser.id);
                WindowManagerGlobal.getWindowManagerService().lockNow(null /* options */);
                WindowManagerGlobal.getWindowManagerService().lockNow(null /* options */);
                return;
                return;
            }
            }
            ActivityManagerNative.getDefault().switchUser(newGuest.id);
            ActivityManagerNative.getDefault().switchUser(newGuest.id);
            userManager.removeUser(currentUser.id);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.e(TAG, "Couldn't wipe session because ActivityManager or WindowManager is dead");
            Log.e(TAG, "Couldn't wipe session because ActivityManager or WindowManager is dead");
            return;
            return;
+11 −3
Original line number Original line Diff line number Diff line
@@ -1107,7 +1107,12 @@ public final class ActivityManagerService extends ActivityManagerNative
    final ActivityThread mSystemThread;
    final ActivityThread mSystemThread;
    // Holds the current foreground user's id
    int mCurrentUserId = 0;
    int mCurrentUserId = 0;
    // Holds the target user's id during a user switch
    int mTargetUserId = UserHandle.USER_NULL;
    // If there are multiple profiles for the current user, their ids are here
    // Currently only the primary user can have managed profiles
    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
    /**
    /**
@@ -17935,6 +17940,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                return false;
                return false;
            }
            }
            userName = userInfo.name;
            userName = userInfo.name;
            mTargetUserId = userId;
        }
        }
        mHandler.removeMessages(START_USER_SWITCH_MSG);
        mHandler.removeMessages(START_USER_SWITCH_MSG);
        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
@@ -18002,6 +18008,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                if (foreground) {
                if (foreground) {
                    mCurrentUserId = userId;
                    mCurrentUserId = userId;
                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
                    updateCurrentProfileIdsLocked();
                    updateCurrentProfileIdsLocked();
                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
                    // Once the internal notion of the active user has switched, we lock the device
                    // Once the internal notion of the active user has switched, we lock the device
@@ -18369,7 +18376,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
        if (mCurrentUserId == userId) {
        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
            return ActivityManager.USER_OP_IS_CURRENT;
            return ActivityManager.USER_OP_IS_CURRENT;
        }
        }
@@ -18509,12 +18516,13 @@ public final class ActivityManagerService extends ActivityManagerNative
            throw new SecurityException(msg);
            throw new SecurityException(msg);
        }
        }
        synchronized (this) {
        synchronized (this) {
            return getUserManagerLocked().getUserInfo(mCurrentUserId);
            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
            return getUserManagerLocked().getUserInfo(userId);
        }
        }
    }
    }
    int getCurrentUserIdLocked() {
    int getCurrentUserIdLocked() {
        return mCurrentUserId;
        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
    }
    }
    @Override
    @Override
+42 −1
Original line number Original line Diff line number Diff line
@@ -519,7 +519,7 @@ public class UserManagerService extends IUserManager.Stub {
        for (int i = 0; i < totalUserCount; i++) {
        for (int i = 0; i < totalUserCount; i++) {
            UserInfo user = mUsers.valueAt(i);
            UserInfo user = mUsers.valueAt(i);
            if (!mRemovingUserIds.get(user.id)
            if (!mRemovingUserIds.get(user.id)
                    && !user.isGuest()) {
                    && !user.isGuest() && !user.partial) {
                aliveUserCount++;
                aliveUserCount++;
            }
            }
        }
        }
@@ -1179,6 +1179,47 @@ public class UserManagerService extends IUserManager.Stub {
        return count;
        return count;
    }
    }


    /**
     * Mark this guest user for deletion to allow us to create another guest
     * and switch to that user before actually removing this guest.
     * @param userHandle the userid of the current guest
     * @return whether the user could be marked for deletion
     */
    public boolean markGuestForDeletion(int userHandle) {
        checkManageUsersPermission("Only the system can remove users");
        if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
                UserManager.DISALLOW_REMOVE_USER, false)) {
            Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");
            return false;
        }

        long ident = Binder.clearCallingIdentity();
        try {
            final UserInfo user;
            synchronized (mPackagesLock) {
                user = mUsers.get(userHandle);
                if (userHandle == 0 || user == null || mRemovingUserIds.get(userHandle)) {
                    return false;
                }
                if (!user.isGuest()) {
                    return false;
                }
                // Set this to a partially created user, so that the user will be purged
                // on next startup, in case the runtime stops now before stopping and
                // removing the user completely.
                user.partial = true;
                // Mark it as disabled, so that it isn't returned any more when
                // profiles are queried.
                user.flags |= UserInfo.FLAG_DISABLED;
                user.flags &= ~UserInfo.FLAG_GUEST;
                writeUserLocked(user);
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        return true;
    }

    /**
    /**
     * Removes a user and all data directories created for that user. This method should be called
     * Removes a user and all data directories created for that user. This method should be called
     * after the user's processes have been terminated.
     * after the user's processes have been terminated.