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

Commit 97a79bdb authored by Hai Zhang's avatar Hai Zhang
Browse files

Make all permissions per-user.

This affects how we do APIs and persistence, so it has to be
accomplished first.

Although both install and runtime permissions are per-user now, we
still need to record whether a permission was granted as an install
permission or a runtime permission, so that we can act accordingly
upon install <-> runtime permission type change.

This change also moves the areInstallPermissionsFixed state into
permission, which is a per-package state.

Bug: 158736025
Test: atest CtsPermissionTestCases
Change-Id: I4aad998cddee13ff0c19c84d6d473abc7a6e7019
parent 056630f1
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -239,7 +239,9 @@
        <!-- Old synonym for "privileged". Deprecated in API level 23. -->
        <flag name="system" value="0x10" />
        <!-- Additional flag from base permission type: this permission can also
             (optionally) be granted to development applications. -->
             (optionally) be granted to development applications. Although undocumented, the
              permission state used to be shared by all users (including future users), but it is
              managed per-user since API level 31. -->
        <flag name="development" value="0x20" />
        <!-- Additional flag from base permission type: this permission is closely
             associated with an app op for controlling access. -->
+8 −8
Original line number Diff line number Diff line
@@ -1848,7 +1848,7 @@ public class PackageManagerService extends IPackageManager.Stub
                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
                    synchronized (mLock) {
                        removeMessages(WRITE_PACKAGE_LIST);
                        mPermissionManager.writePermissionsStateToPackageSettingsTEMP();
                        mPermissionManager.writeStateToPackageSettingsTEMP();
                        mSettings.writePackageListLPr(msg.arg1);
                    }
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
@@ -3518,7 +3518,7 @@ public class PackageManagerService extends IPackageManager.Stub
                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
                    + " seconds");
            mPermissionManager.readPermissionsStateFromPackageSettingsTEMP();
            mPermissionManager.readStateFromPackageSettingsTEMP();
            // If the platform SDK has changed since the last time we booted,
            // we need to re-grant app permission to catch any new ones that
            // appear.  This is really a hack, and means that apps can in some
@@ -21846,7 +21846,7 @@ public class PackageManagerService extends IPackageManager.Stub
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
        mPermissionManager.writePermissionsStateToPackageSettingsTEMP();
        mPermissionManager.writeStateToPackageSettingsTEMP();
        DumpState dumpState = new DumpState();
        boolean fullPreferred = false;
@@ -23725,7 +23725,7 @@ public class PackageManagerService extends IPackageManager.Stub
            mDirtyUsers.remove(userId);
            mUserNeedsBadging.delete(userId);
            mPermissionManager.onUserRemoved(userId);
            mPermissionManager.writePermissionsStateToPackageSettingsTEMP();
            mPermissionManager.writeStateToPackageSettingsTEMP();
            mSettings.removeUserLPw(userId);
            mPendingBroadcasts.remove(userId);
            mInstantAppRegistry.onUserRemovedLPw(userId);
@@ -23826,9 +23826,9 @@ public class PackageManagerService extends IPackageManager.Stub
    boolean readPermissionStateForUser(@UserIdInt int userId) {
        synchronized (mPackages) {
            mPermissionManager.writePermissionsStateToPackageSettingsTEMP();
            mPermissionManager.writeStateToPackageSettingsTEMP();
            mSettings.readPermissionStateForUserSyncLPr(userId);
            mPermissionManager.readPermissionsStateFromPackageSettingsTEMP();
            mPermissionManager.readStateFromPackageSettingsTEMP();
            return mPmInternal.isPermissionUpgradeNeeded(userId);
        }
    }
@@ -25842,12 +25842,12 @@ public class PackageManagerService extends IPackageManager.Stub
    /**
     * Temporary method that wraps mSettings.writeLPr() and calls
     * mPermissionManager.writePermissionsStateToPackageSettingsTEMP() beforehand.
     * mPermissionManager.writeStateToPackageSettingsTEMP() beforehand.
     *
     * TODO(zhanghai): This should be removed once we finish migration of permission storage.
     */
    private void writeSettingsLPrTEMP() {
        mPermissionManager.writePermissionsStateToPackageSettingsTEMP();
        mPermissionManager.writeStateToPackageSettingsTEMP();
        mSettings.writeLPr();
    }
}
+7 −2
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;

import com.android.internal.util.ArrayUtils;
import com.android.server.pm.DumpState;
import com.android.server.pm.PackageManagerService;
import com.android.server.pm.PackageSettingBase;
@@ -139,6 +140,10 @@ public final class BasePermission {
        this.perm = perm;
    }

    public boolean hasGids() {
        return !ArrayUtils.isEmpty(gids);
    }

    public int[] computeGids(int userId) {
        if (perUser) {
            final int[] userGids = new int[gids.length];
@@ -419,9 +424,9 @@ public final class BasePermission {
    }

    public void enforceDeclaredUsedAndRuntimeOrDevelopment(AndroidPackage pkg,
            PermissionsState permsState) {
            UidPermissionState uidState) {
        int index = pkg.getRequestedPermissions().indexOf(name);
        if (!permsState.hasRequestedPermission(name) && index == -1) {
        if (!uidState.hasRequestedPermission(name) && index == -1) {
            throw new SecurityException("Package " + pkg.getPackageName()
                    + " has not requested permission " + name);
        }
+77 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.pm.permission;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;

/**
 * Permission state for this device.
 */
public final class DevicePermissionState {
    @GuardedBy("mLock")
    @NonNull
    private final SparseArray<UserPermissionState> mUserStates = new SparseArray<>();

    @NonNull
    private final Object mLock;

    public DevicePermissionState(@NonNull Object lock) {
        mLock = lock;
    }

    @Nullable
    public UserPermissionState getUserState(@UserIdInt int userId) {
        synchronized (mLock) {
            return mUserStates.get(userId);
        }
    }

    @NonNull
    public UserPermissionState getOrCreateUserState(@UserIdInt int userId) {
        synchronized (mLock) {
            UserPermissionState userState = mUserStates.get(userId);
            if (userState == null) {
                userState = new UserPermissionState(mLock);
                mUserStates.put(userId, userState);
            }
            return userState;
        }
    }

    public void removeUserState(@UserIdInt int userId) {
        synchronized (mLock) {
            mUserStates.delete(userId);
        }
    }

    public int[] getUserIds() {
        synchronized (mLock) {
            final int userStatesSize = mUserStates.size();
            final int[] userIds = new int[userStatesSize];
            for (int i = 0; i < userStatesSize; i++) {
                final int userId = mUserStates.keyAt(i);
                userIds[i] = userId;
            }
            return userIds;
        }
    }
}
+549 −528

File changed.

Preview size limit exceeded, changes collapsed.

Loading