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

Commit bd30f7e8 authored by Anthony Hugh's avatar Anthony Hugh
Browse files

Update PermissionManagerService to handle pre-created users

Pre-created users are not being returned by the call to
UserManagerService.getUserIds(). This is causing PermissionManager to
ignore recording pre-grants when a new pre-created user is created.

This CL fixes the issue by using a user ID set that contians pre-created
users.  Presumably the call to getUserIds() was previously done for
performance reasons.  I have added some system tracing to see if
performance is a bottle neck here with the new API call.

I ran the test 5 times on an automotive emulator:
[1] Start system trace
[2] adb shell pm -create-user --pre-create-only
[3] Stop system trace

Average time to getUsers() before changes: .389ms
Average time to getUsers() after changes: 1.82ms

Given that this is an infrequent operation and less than 5ms change,
performance hit looks negligible.

Bug: b/160901158
Test: Manually. Run `adb shell pm -create-user --pre-create-only`.
Create a new user and check to see that Assistant has pre-granted
permissions via `adb shell dumpsys package
com.google.android.carassistant`

Change-Id: I52caeb3a71e560d09fcbc167b46becebf779fc3a
(cherry picked from commit 432a0377250246632927252c9d2b92411717be52)
parent 326e3ca1
Loading
Loading
Loading
Loading
+30 −9
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ import android.content.pm.PackageParser;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.UserInfo;
import android.content.pm.parsing.component.ParsedPermission;
import android.content.pm.parsing.component.ParsedPermissionGroup;
import android.content.pm.permission.SplitPermissionInfoParcelable;
@@ -120,6 +121,7 @@ import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.TimingsTraceLog;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -2521,12 +2523,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {

        final PermissionsState permissionsState = ps.getPermissionsState();

        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
        final int[] userIds = getAllUserIds();

        boolean runtimePermissionsRevoked = false;
        int[] updatedUserIds = EMPTY_INT_ARRAY;

        for (int userId : currentUserIds) {
        for (int userId : userIds) {
            if (permissionsState.isMissing(userId)) {
                Collection<String> requestedPermissions;
                int targetSdkVersion;
@@ -2592,7 +2594,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                // runtime and revocation of a runtime from a shared user.
                synchronized (mLock) {
                    updatedUserIds = revokeUnusedSharedUserPermissionsLocked(ps.getSharedUser(),
                            currentUserIds);
                            userIds);
                    if (!ArrayUtils.isEmpty(updatedUserIds)) {
                        runtimePermissionsRevoked = true;
                    }
@@ -2747,7 +2749,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                            // a runtime permission being downgraded to an install one.
                            // Also in permission review mode we keep dangerous permissions
                            // for legacy apps
                            for (int userId : currentUserIds) {
                            for (int userId : userIds) {
                                if (origPermissions.getRuntimePermissionState(
                                        perm, userId) != null) {
                                    // Revoke the runtime permission and clear the flags.
@@ -2770,7 +2772,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                            boolean hardRestricted = bp.isHardRestricted();
                            boolean softRestricted = bp.isSoftRestricted();

                            for (int userId : currentUserIds) {
                            for (int userId : userIds) {
                                // If permission policy is not ready we don't deal with restricted
                                // permissions as the policy may whitelist some permissions. Once
                                // the policy is initialized we would re-evaluate permissions.
@@ -2909,7 +2911,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                            boolean hardRestricted = bp.isHardRestricted();
                            boolean softRestricted = bp.isSoftRestricted();

                            for (int userId : currentUserIds) {
                            for (int userId : userIds) {
                                // If permission policy is not ready we don't deal with restricted
                                // permissions as the policy may whitelist some permissions. Once
                                // the policy is initialized we would re-evaluate permissions.
@@ -3061,10 +3063,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {

        synchronized (mLock) {
            updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
                    currentUserIds, updatedUserIds);
                    userIds, updatedUserIds);
            updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
                    permissionsState, pkg, newImplicitPermissions, currentUserIds, updatedUserIds);
            updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, currentUserIds,
                    permissionsState, pkg, newImplicitPermissions, userIds, updatedUserIds);
            updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, userIds,
                    updatedUserIds);
        }

@@ -3080,6 +3082,25 @@ public class PermissionManagerService extends IPermissionManager.Stub {
        }
    }

    /**
     * Returns all relevant user ids.  This list include the current set of created user ids as well
     * as pre-created user ids.
     * @return user ids for created users and pre-created users
     */
    private int[] getAllUserIds() {
        final TimingsTraceLog t = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
        t.traceBegin("getAllUserIds");
        List<UserInfo> users = UserManagerService.getInstance().getUsers(
                /*excludePartial=*/ true, /*excludeDying=*/ true, /*excludePreCreated=*/ false);
        int size = users.size();
        final int[] userIds = new int[size];
        for (int i = 0; i < size; i++) {
            userIds[i] = users.get(i).id;
        }
        t.traceEnd();
        return userIds;
    }

    /**
     * Revoke permissions that are not implicit anymore and that have
     * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.