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

Commit 0c123fac authored by Hai Zhang's avatar Hai Zhang
Browse files

Cache permission info before syncing app op mode.

This can help reducing time spent in onStartUser() where we compute
app op mode synchronously for all apps. After this change, we don't
have to query the permission info for every runtime permission
requested by every app every time we encounter it.

Bug: 136503238
Test: presubmit
Change-Id: I64dfd056725b666b83649769a9b551b7b6207b73
parent 57bc312f
Loading
Loading
Loading
Loading
+17 −16
Original line number Diff line number Diff line
@@ -48,12 +48,12 @@ import android.os.UserManagerInternal;
import android.permission.PermissionControllerManager;
import android.provider.Telephony;
import android.telecom.TelecomManager;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.LongSparseLongArray;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsCallback;
@@ -67,6 +67,7 @@ import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.policy.PermissionPolicyInternal.OnInitializedCallback;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
@@ -389,8 +390,7 @@ public final class PermissionPolicyService extends SystemService {
        private final @NonNull PackageManager mPackageManager;
        private final @NonNull AppOpsManager mAppOpsManager;

        /** All uid that need to be synchronized */
        private final @NonNull SparseIntArray mAllUids = new SparseIntArray();
        private final @NonNull ArrayMap<String, PermissionInfo> mRuntimePermissionInfos;

        /**
         * All ops that need to be flipped to allow.
@@ -428,6 +428,18 @@ public final class PermissionPolicyService extends SystemService {
            mContext = context;
            mPackageManager = context.getPackageManager();
            mAppOpsManager = context.getSystemService(AppOpsManager.class);

            mRuntimePermissionInfos = new ArrayMap<>();
            PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
                    PermissionManagerServiceInternal.class);
            List<PermissionInfo> permissionInfos =
                    permissionManagerInternal.getAllPermissionWithProtection(
                            PermissionInfo.PROTECTION_DANGEROUS);
            int permissionInfosSize = permissionInfos.size();
            for (int i = 0; i < permissionInfosSize; i++) {
                PermissionInfo permissionInfo = permissionInfos.get(i);
                mRuntimePermissionInfos.put(permissionInfo.name, permissionInfo);
            }
        }

        /**
@@ -489,7 +501,7 @@ public final class PermissionPolicyService extends SystemService {
         * Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
         */
        private void addAppOps(@NonNull PackageInfo packageInfo, @NonNull String permissionName) {
            PermissionInfo permissionInfo = getPermissionInfo(permissionName);
            PermissionInfo permissionInfo = mRuntimePermissionInfos.get(permissionName);
            if (permissionInfo == null) {
                return;
            }
@@ -525,7 +537,7 @@ public final class PermissionPolicyService extends SystemService {
            boolean shouldGrantAppOp = shouldGrantAppOp(packageInfo, permissionInfo);
            if (shouldGrantAppOp) {
                if (permissionInfo.backgroundPermission != null) {
                    PermissionInfo backgroundPermissionInfo = getPermissionInfo(
                    PermissionInfo backgroundPermissionInfo = mRuntimePermissionInfos.get(
                            permissionInfo.backgroundPermission);
                    boolean shouldGrantBackgroundAppOp = backgroundPermissionInfo != null
                            && shouldGrantAppOp(packageInfo, backgroundPermissionInfo);
@@ -552,15 +564,6 @@ public final class PermissionPolicyService extends SystemService {
            }
        }

        @Nullable
        private PermissionInfo getPermissionInfo(@NonNull String permissionName) {
            try {
                return mPackageManager.getPermissionInfo(permissionName, 0);
            } catch (PackageManager.NameNotFoundException e) {
                return null;
            }
        }

        private boolean shouldGrantAppOp(@NonNull PackageInfo packageInfo,
                @NonNull PermissionInfo permissionInfo) {
            String permissionName = permissionInfo.name;
@@ -638,8 +641,6 @@ public final class PermissionPolicyService extends SystemService {
                return;
            }

            mAllUids.put(pkg.applicationInfo.uid, pkg.applicationInfo.uid);

            if (pkg.requestedPermissions == null) {
                return;
            }