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

Commit ffa04d25 authored by felipeal's avatar felipeal Committed by Felipe Leme
Browse files

Optimized ActivityManager.getCurrentUser()

That method returns the userId of the current foreground user, but its
implementation fetches a UserInfo then extracts id.

This CL shortcuts the process by returning the user id directly, which
improves the performance in 2 ways:

- Avoids a map lookup.
- Decrease data pased through the IPC.

Test: adb shell am get-current-user
Fixes: 151322436

Change-Id: I028a54a1918bd2226ed3bd903bbe98c6ef4811b2
parent d2ff4867
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -4176,10 +4176,8 @@ public class ActivityManager {
            "android.permission.INTERACT_ACROSS_USERS_FULL"
    })
    public static int getCurrentUser() {
        UserInfo ui;
        try {
            ui = getService().getCurrentUser();
            return ui != null ? ui.id : 0;
            return getService().getCurrentUserId();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+1 −0
Original line number Diff line number Diff line
@@ -363,6 +363,7 @@ interface IActivityManager {
    boolean killProcessesBelowForeground(in String reason);
    @UnsupportedAppUsage
    UserInfo getCurrentUser();
    int getCurrentUserId();
    // This is not public because you need to be very careful in how you
    // manage your activity to make sure it is always the uid you expect.
    @UnsupportedAppUsage
+5 −0
Original line number Diff line number Diff line
@@ -15670,6 +15670,11 @@ public class ActivityManagerService extends IActivityManager.Stub
        return mUserController.getCurrentUser();
    }
    @Override
    public @UserIdInt int getCurrentUserId() {
        return mUserController.getCurrentUserIdChecked();
    }
    String getStartedUserState(int userId) {
        final UserState userState = mUserController.getStartedUserState(userId);
        return UserState.stateToString(userState.state);
+5 −4
Original line number Diff line number Diff line
@@ -118,7 +118,6 @@ import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -1842,9 +1841,11 @@ final class ActivityManagerShellCommand extends ShellCommand {
    }

    int runGetCurrentUser(PrintWriter pw) throws RemoteException {
        UserInfo currentUser = Objects.requireNonNull(mInterface.getCurrentUser(),
                "Current user not set");
        pw.println(currentUser.id);
        int userId = mInterface.getCurrentUserId();
        if (userId == UserHandle.USER_NULL) {
            throw new IllegalStateException("Current user not set");
        }
        pw.println(userId);
        return 0;
    }

+21 −4
Original line number Diff line number Diff line
@@ -2173,7 +2173,7 @@ class UserController implements Handler.Callback {
        }
    }

    UserInfo getCurrentUser() {
    private void checkGetCurrentUserPermissions() {
        if ((mInjector.checkCallingPermission(INTERACT_ACROSS_USERS)
                != PackageManager.PERMISSION_GRANTED) && (
                mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
@@ -2185,8 +2185,12 @@ class UserController implements Handler.Callback {
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }
    }

        // Optimization - if there is no pending user switch, return current id
    UserInfo getCurrentUser() {
        checkGetCurrentUserPermissions();

        // Optimization - if there is no pending user switch, return user for current id
        // (no need to acquire lock because mTargetUserId and mCurrentUserId are volatile)
        if (mTargetUserId == UserHandle.USER_NULL) {
            return getUserInfo(mCurrentUserId);
@@ -2196,9 +2200,23 @@ class UserController implements Handler.Callback {
        }
    }

    /**
     * Gets the current user id, but checking that caller has the proper permissions.
     */
    int getCurrentUserIdChecked() {
        checkGetCurrentUserPermissions();

        // Optimization - if there is no pending user switch, return current id
        // (no need to acquire lock because mTargetUserId and mCurrentUserId are volatile)
        if (mTargetUserId == UserHandle.USER_NULL) {
            return mCurrentUserId;
        }
        return getCurrentOrTargetUserId();
    }

    @GuardedBy("mLock")
    UserInfo getCurrentUserLU() {
        int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
        int userId = getCurrentOrTargetUserIdLU();
        return getUserInfo(userId);
    }

@@ -2213,7 +2231,6 @@ class UserController implements Handler.Callback {
        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
    }


    @GuardedBy("mLock")
    int getCurrentUserIdLU() {
        return mCurrentUserId;