/*
 * Copyright (C) 2021 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 static android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY;
import static android.Manifest.permission.POST_NOTIFICATIONS;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_ERRORED;
import static android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_DEFAULT;
import static android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED;
import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
import static android.content.pm.PackageManager.FLAG_PERMISSION_AUTO_REVOKED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE;
import static android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME;
import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY;
import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Process.INVALID_UID;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;

import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;

import static java.util.concurrent.TimeUnit.SECONDS;

import android.Manifest;
import android.annotation.AppIdInt;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.companion.virtual.VirtualDeviceManager;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.SigningDetails;
import android.content.pm.permission.SplitPermissionInfoParcelable;
import android.metrics.LogMaker;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Build;
import android.os.Debug;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.permission.IOnPermissionsChangeListener;
import android.permission.PermissionControllerManager;
import android.permission.PermissionManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
import android.util.EventLog;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.os.RoSystemProperties;
import com.android.internal.pm.permission.CompatibilityPermissionInfo;
import com.android.internal.pm.pkg.component.ComponentMutateUtils;
import com.android.internal.pm.pkg.component.ParsedPermission;
import com.android.internal.pm.pkg.component.ParsedPermissionGroup;
import com.android.internal.pm.pkg.component.ParsedPermissionUtils;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
import com.android.internal.util.IntPair;
import com.android.internal.util.Preconditions;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.PermissionThread;
import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
import com.android.server.Watchdog;
import com.android.server.pm.ApexManager;
import com.android.server.pm.KnownPackages;
import com.android.server.pm.PackageInstallerService;
import com.android.server.pm.PackageManagerTracedLock;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.UserManagerService;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.SharedUserApi;
import com.android.server.policy.PermissionPolicyInternal;
import com.android.server.policy.SoftRestrictedPermissionPolicy;

import libcore.util.EmptyArray;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * PermissionManagerServiceImpl.
 */
public class PermissionManagerServiceImpl implements PermissionManagerServiceInterface {

    private static final String TAG = "PermissionManager";
    private static final String LOG_TAG = PermissionManagerServiceImpl.class.getSimpleName();

    private static final String SKIP_KILL_APP_REASON_NOTIFICATION_TEST = "skip permission revoke "
            + "app kill for notification test";


    private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);

    /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
    /** Empty array to avoid allocations */
    private static final int[] EMPTY_INT_ARRAY = new int[0];

    /**
     * When these flags are set, the system should not automatically modify the permission grant
     * state.
     */
    private static final int BLOCKING_PERMISSION_FLAGS = FLAG_PERMISSION_SYSTEM_FIXED
            | FLAG_PERMISSION_POLICY_FIXED
            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;

    /** Permission flags set by the user */
    private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET
            | FLAG_PERMISSION_USER_FIXED;

    /** All storage permissions */
    private static final List<String> STORAGE_PERMISSIONS = new ArrayList<>();

    private static final Set<String> READ_MEDIA_AURAL_PERMISSIONS = new ArraySet<>();

    private static final Set<String> READ_MEDIA_VISUAL_PERMISSIONS = new ArraySet<>();

    /** All nearby devices permissions */
    private static final List<String> NEARBY_DEVICES_PERMISSIONS = new ArrayList<>();

    /**
     * All notification permissions.
     * Notification permission state is treated differently from other permissions. Notification
     * permission get the REVIEW_REQUIRED flag set for S- apps, or for T+ apps on updating to T or
     * restoring a pre-T backup. The permission and app op remain denied. The flag will be read by
     * the notification system, and allow apps to send notifications, until cleared.
     * The flag is cleared for S- apps by the system showing a permission request prompt, and the
     * user clicking "allow" or "deny" in the dialog. For T+ apps, the flag is cleared upon the
     * first activity launch.
     *
     * @see PermissionPolicyInternal#showNotificationPromptIfNeeded(String, int, int)
     */
    private static final List<String> NOTIFICATION_PERMISSIONS = new ArrayList<>();

    /** If the permission of the value is granted, so is the key */
    private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();

    static {
        FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION);
        FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
                Manifest.permission.INTERACT_ACROSS_USERS_FULL);
        STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        READ_MEDIA_AURAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_AUDIO);
        READ_MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_VIDEO);
        READ_MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_IMAGES);
        READ_MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION);
        READ_MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED);
        NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_ADVERTISE);
        NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_CONNECT);
        NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_SCAN);
        NOTIFICATION_PERMISSIONS.add(Manifest.permission.POST_NOTIFICATIONS);
    }

    @NonNull private final ApexManager mApexManager;

    /** Set of source package names for Privileged Permission Allowlist */
    private final ArraySet<String> mPrivilegedPermissionAllowlistSourcePackageNames =
            new ArraySet<>();

    /** Lock to protect internal data access */
    private final PackageManagerTracedLock mLock = new PackageManagerTracedLock();

    /** Internal connection to the package manager */
    private final PackageManagerInternal mPackageManagerInt;

    /** Internal connection to the user manager */
    private final UserManagerInternal mUserManagerInt;

    @GuardedBy("mLock")
    @NonNull
    private final DevicePermissionState mState = new DevicePermissionState();

    /** Permission controller: User space permission management */
    private PermissionControllerManager mPermissionControllerManager;

    /**
     * Built-in permissions. Read from system configuration files. Mapping is from
     * UID to permission name.
     */
    private final SparseArray<ArraySet<String>> mSystemPermissions;

    /** Built-in group IDs given to all packages. Read from system configuration files. */
    @NonNull
    private final int[] mGlobalGids;

    private final HandlerThread mHandlerThread;
    private final Handler mHandler;
    private final Context mContext;
    private final MetricsLogger mMetricsLogger = new MetricsLogger();
    private final IPlatformCompat mPlatformCompat = IPlatformCompat.Stub.asInterface(
            ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));

    /** Internal storage for permissions and related settings */
    @GuardedBy("mLock")
    @NonNull
    private final PermissionRegistry mRegistry = new PermissionRegistry();

    @GuardedBy("mLock")
    @Nullable
    private ArraySet<String> mPrivappPermissionsViolations;

    @GuardedBy("mLock")
    private boolean mSystemReady;

    @GuardedBy("mLock")
    private PermissionPolicyInternal mPermissionPolicyInternal;

    /**
     * A permission backup might contain apps that are not installed. In this case we delay the
     * restoration until the app is installed.
     *
     * <p>This array ({@code userId -> noDelayedBackupLeft}) is {@code true} for all the users where
     * there is <u>no more</u> delayed backup left.
     */
    @GuardedBy("mLock")
    private final SparseBooleanArray mHasNoDelayedPermBackup = new SparseBooleanArray();

    private final boolean mIsLeanback;

    @NonNull
    private final OnPermissionChangeListeners mOnPermissionChangeListeners;

    // TODO: Take a look at the methods defined in the callback.
    // The callback was initially created to support the split between permission
    // manager and the package manager. However, it's started to be used for other
    // purposes. It may make sense to keep as an abstraction, but, the methods
    // necessary to be overridden may be different than what was initially needed
    // for the split.
    private final PermissionCallback mDefaultPermissionCallback = new PermissionCallback() {
        @Override
        public void onGidsChanged(int appId, int userId) {
            mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED));
        }
        @Override
        public void onPermissionGranted(int uid, int userId) {
            mOnPermissionChangeListeners.onPermissionsChanged(uid);

            // Not critical; if this is lost, the application has to request again.
            mPackageManagerInt.writeSettings(true);
        }
        @Override
        public void onInstallPermissionGranted() {
            mPackageManagerInt.writeSettings(true);
        }
        @Override
        public void onPermissionRevoked(int uid, int userId, String reason, boolean overrideKill,
                @Nullable String permissionName) {
            mOnPermissionChangeListeners.onPermissionsChanged(uid);

            // Critical; after this call the application should never have the permission
            mPackageManagerInt.writeSettings(false);
            if (overrideKill) {
                return;
            }

            mHandler.post(() -> {
                if (POST_NOTIFICATIONS.equals(permissionName)
                        && isAppBackupAndRestoreRunning(uid)) {
                    return;
                }

                final int appId = UserHandle.getAppId(uid);
                if (reason == null) {
                    killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
                } else {
                    killUid(appId, userId, reason);
                }
            });
        }

        private boolean isAppBackupAndRestoreRunning(int uid) {
            if (checkUidPermission(uid, Manifest.permission.BACKUP) != PERMISSION_GRANTED) {
                return false;
            }

            try {
                int userId = UserHandle.getUserId(uid);
                boolean isInSetup = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                        Settings.Secure.USER_SETUP_COMPLETE, userId) == 0;
                boolean isInDeferredSetup = Settings.Secure.getIntForUser(
                        mContext.getContentResolver(),
                        Settings.Secure.USER_SETUP_PERSONALIZATION_STATE, userId)
                        == Settings.Secure.USER_SETUP_PERSONALIZATION_STARTED;
                return isInSetup || isInDeferredSetup;
            } catch (Settings.SettingNotFoundException e) {
                Slog.w(LOG_TAG, "Failed to check if the user is in restore: " + e);
                return false;
            }
        }

        @Override
        public void onInstallPermissionRevoked() {
            mPackageManagerInt.writeSettings(true);
        }
        @Override
        public void onPermissionUpdated(int[] userIds, boolean sync, int appId) {
            for (int i = 0; i < userIds.length; i++) {
                int uid = UserHandle.getUid(userIds[i], appId);
                mOnPermissionChangeListeners.onPermissionsChanged(uid);
            }
            mPackageManagerInt.writePermissionSettings(userIds, !sync);
        }
        @Override
        public void onInstallPermissionUpdated() {
            mPackageManagerInt.writeSettings(true);
        }
        @Override
        public void onPermissionRemoved() {
            mPackageManagerInt.writeSettings(false);
        }
    };

    public PermissionManagerServiceImpl(@NonNull Context context,
            @NonNull ArrayMap<String, FeatureInfo> availableFeatures) {
        // The package info cache is the cache for package and permission information.
        // Disable the package info and package permission caches locally but leave the
        // checkPermission cache active.
        PackageManager.invalidatePackageInfoCache();
        PermissionManager.disablePackageNamePermissionCache();

        mContext = context;
        mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
        mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
        mIsLeanback = availableFeatures.containsKey(PackageManager.FEATURE_LEANBACK);
        mApexManager = ApexManager.getInstance();

        mPrivilegedPermissionAllowlistSourcePackageNames.add(PLATFORM_PACKAGE_NAME);
        // PackageManager.hasSystemFeature() is not used here because PackageManagerService
        // isn't ready yet.
        if (availableFeatures.containsKey(PackageManager.FEATURE_AUTOMOTIVE)) {
            // The property defined in car api surface, so use the string directly.
            String carServicePackage = SystemProperties.get("ro.android.car.carservice.package",
                    null);
            if (carServicePackage != null) {
                mPrivilegedPermissionAllowlistSourcePackageNames.add(carServicePackage);
            }
        }

        mHandlerThread = new ServiceThread(TAG,
                Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
        mHandlerThread.start();
        mHandler = new Handler(mHandlerThread.getLooper());
        Watchdog.getInstance().addThread(mHandler);

        SystemConfig systemConfig = SystemConfig.getInstance();
        mSystemPermissions = systemConfig.getSystemPermissions();
        mGlobalGids = systemConfig.getGlobalGids();
        mOnPermissionChangeListeners = new OnPermissionChangeListeners(FgThread.get().getLooper());

        // propagate permission configuration
        final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
                SystemConfig.getInstance().getPermissions();
        synchronized (mLock) {
            for (int i = 0; i < permConfig.size(); i++) {
                final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
                Permission bp = mRegistry.getPermission(perm.name);
                if (bp == null) {
                    bp = new Permission(perm.name, "android", Permission.TYPE_CONFIG);
                    mRegistry.addPermission(bp);
                }
                if (perm.gids != null) {
                    bp.setGids(perm.gids, perm.perUser);
                }
            }
        }
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {}

    /**
     * This method should typically only be used when granting or revoking
     * permissions, since the app may immediately restart after this call.
     * <p>
     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
     * guard your work against the app being relaunched.
     */
    private static void killUid(int appId, int userId, String reason) {
        final long identity = Binder.clearCallingIdentity();
        try {
            IActivityManager am = ActivityManager.getService();
            if (am != null) {
                try {
                    am.killUidForPermissionChange(appId, userId, reason);
                } catch (RemoteException e) {
                    /* ignore - same process */
                }
            }
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    @NonNull
    private String[] getAppOpPermissionPackagesInternal(@NonNull String permissionName) {
        synchronized (mLock) {
            final ArraySet<String> packageNames = mRegistry.getAppOpPermissionPackages(
                    permissionName);
            if (packageNames == null) {
                return EmptyArray.STRING;
            }
            return packageNames.toArray(new String[0]);
        }
    }

    @Override
    @NonNull
    public List<PermissionGroupInfo> getAllPermissionGroups(
            @PackageManager.PermissionGroupInfoFlags int flags) {
        final int callingUid = Binder.getCallingUid();
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            return Collections.emptyList();
        }

        final List<PermissionGroupInfo> out = new ArrayList<>();
        synchronized (mLock) {
            for (ParsedPermissionGroup pg : mRegistry.getPermissionGroups()) {
                out.add(PackageInfoUtils.generatePermissionGroupInfo(pg, flags));
            }
        }

        final int callingUserId = UserHandle.getUserId(callingUid);
        out.removeIf(it -> mPackageManagerInt.filterAppAccess(it.packageName, callingUid,
                callingUserId, false /* filterUninstalled */));
        return out;
    }

    @Override
    @Nullable
    public PermissionGroupInfo getPermissionGroupInfo(String groupName,
            @PackageManager.PermissionGroupInfoFlags int flags) {
        final int callingUid = Binder.getCallingUid();
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            return null;
        }

        final PermissionGroupInfo permissionGroupInfo;
        synchronized (mLock) {
            final ParsedPermissionGroup permissionGroup = mRegistry.getPermissionGroup(groupName);
            if (permissionGroup == null) {
                return null;
            }
            permissionGroupInfo = PackageInfoUtils.generatePermissionGroupInfo(permissionGroup,
                    flags);
        }

        final int callingUserId = UserHandle.getUserId(callingUid);
        if (mPackageManagerInt.filterAppAccess(permissionGroupInfo.packageName, callingUid,
                callingUserId, false /* filterUninstalled */)) {
            EventLog.writeEvent(0x534e4554, "186113473", callingUid, groupName);
            return null;
        }
        return permissionGroupInfo;
    }

    @Override
    @Nullable
    public PermissionInfo getPermissionInfo(@NonNull String permName,
            @PackageManager.PermissionInfoFlags int flags, @NonNull String opPackageName) {
        final int callingUid = Binder.getCallingUid();
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            return null;
        }

        final AndroidPackage opPackage = mPackageManagerInt.getPackage(opPackageName);
        final int targetSdkVersion = getPermissionInfoCallingTargetSdkVersion(opPackage,
                callingUid);
        final PermissionInfo permissionInfo;
        synchronized (mLock) {
            final Permission bp = mRegistry.getPermission(permName);
            if (bp == null) {
                return null;
            }
            permissionInfo = bp.generatePermissionInfo(flags, targetSdkVersion);
        }

        final int callingUserId = UserHandle.getUserId(callingUid);
        if (mPackageManagerInt.filterAppAccess(permissionInfo.packageName, callingUid,
                callingUserId, false /* filterUninstalled */)) {
            EventLog.writeEvent(0x534e4554, "183122164", callingUid, permName);
            return null;
        }
        return permissionInfo;
    }

    private int getPermissionInfoCallingTargetSdkVersion(@Nullable AndroidPackage pkg, int uid) {
        final int appId = UserHandle.getAppId(uid);
        if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID
                || appId == Process.SHELL_UID) {
            // System sees all flags.
            return Build.VERSION_CODES.CUR_DEVELOPMENT;
        }
        if (pkg == null) {
            return Build.VERSION_CODES.CUR_DEVELOPMENT;
        }
        return pkg.getTargetSdkVersion();
    }

    @Override
    @Nullable
    public List<PermissionInfo> queryPermissionsByGroup(String groupName,
            @PackageManager.PermissionInfoFlags int flags) {
        final int callingUid = Binder.getCallingUid();
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            return null;
        }

        final ParsedPermissionGroup permissionGroup;
        final List<PermissionInfo> out = new ArrayList<>(10);
        synchronized (mLock) {
            permissionGroup = mRegistry.getPermissionGroup(groupName);
            if (groupName != null && permissionGroup == null) {
                return null;
            }
            for (Permission bp : mRegistry.getPermissions()) {
                if (Objects.equals(bp.getGroup(), groupName)) {
                    out.add(bp.generatePermissionInfo(flags));
                }
            }
        }

        final int callingUserId = UserHandle.getUserId(callingUid);
        if (permissionGroup != null && mPackageManagerInt.filterAppAccess(
                permissionGroup.getPackageName(), callingUid, callingUserId,
                false /* filterUninstalled */)) {
            return null;
        }
        out.removeIf(it -> mPackageManagerInt.filterAppAccess(it.packageName, callingUid,
                callingUserId, false /* filterUninstalled */));
        return out;
    }

    @Override
    public boolean addPermission(PermissionInfo info, boolean async) {
        final int callingUid = Binder.getCallingUid();
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            throw new SecurityException("Instant apps can't add permissions");
        }
        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
            throw new SecurityException("Label must be specified in permission");
        }
        final boolean added;
        final boolean changed;
        synchronized (mLock) {
            final Permission tree = mRegistry.enforcePermissionTree(info.name, callingUid);
            Permission bp = mRegistry.getPermission(info.name);
            added = bp == null;
            int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
            enforcePermissionCapLocked(info, tree);
            if (added) {
                bp = new Permission(info.name, tree.getPackageName(), Permission.TYPE_DYNAMIC);
            } else if (!bp.isDynamic()) {
                throw new SecurityException("Not allowed to modify non-dynamic permission "
                        + info.name);
            }
            changed = bp.addToTree(fixedLevel, info, tree);
            if (added) {
                mRegistry.addPermission(bp);
            }
        }
        if (changed) {
            mPackageManagerInt.writeSettings(async);
        }
        return added;
    }

    @Override
    public void removePermission(String permName) {
        final int callingUid = Binder.getCallingUid();
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            throw new SecurityException("Instant applications don't have access to this method");
        }
        synchronized (mLock) {
            mRegistry.enforcePermissionTree(permName, callingUid);
            final Permission bp = mRegistry.getPermission(permName);
            if (bp == null) {
                return;
            }
            if (!bp.isDynamic()) {
                // TODO: switch this back to SecurityException
                Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
                        + permName);
            }
            mRegistry.removePermission(permName);
        }
        mPackageManagerInt.writeSettings(false);
    }

    @Override
    public int getPermissionFlags(String packageName, String permName, int deviceId, int userId) {
        final int callingUid = Binder.getCallingUid();
        return getPermissionFlagsInternal(packageName, permName, callingUid, userId);
    }

    private int getPermissionFlagsInternal(
            String packageName, String permName, int callingUid, int userId) {
        if (!mUserManagerInt.exists(userId)) {
            return 0;
        }

        enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
        enforceCrossUserPermission(callingUid, userId,
                true,  // requireFullPermission
                false, // checkShell
                "getPermissionFlags");

        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        if (pkg == null) {
            return 0;
        }
        if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId,
                false /* filterUninstalled */)) {
            return 0;
        }

        synchronized (mLock) {
            if (mRegistry.getPermission(permName) == null) {
                return 0;
            }

            final UidPermissionState uidState = getUidStateLocked(pkg, userId);
            if (uidState == null) {
                Slog.e(TAG, "Missing permissions state for " + packageName + " and user " + userId);
                return 0;
            }

            return uidState.getPermissionFlags(permName);
        }
    }

    @Override
    public void updatePermissionFlags(String packageName, String permName, int flagMask,
            int flagValues, boolean checkAdjustPolicyFlagPermission, int deviceId, int userId) {
        final int callingUid = Binder.getCallingUid();
        boolean overridePolicy = false;

        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
            if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0) {
                if (checkAdjustPolicyFlagPermission) {
                    mContext.enforceCallingOrSelfPermission(
                            Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
                            "Need " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY
                                    + " to change policy flags");
                } else if (mPackageManagerInt.getUidTargetSdkVersion(callingUid)
                        >= Build.VERSION_CODES.Q) {
                    throw new IllegalArgumentException(
                            Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " needs "
                                    + " to be checked for packages targeting "
                                    + Build.VERSION_CODES.Q + " or later when changing policy "
                                    + "flags");
                }
                overridePolicy = true;
            }
        }

        updatePermissionFlagsInternal(
                packageName, permName, flagMask, flagValues, callingUid, userId,
                overridePolicy, mDefaultPermissionCallback);
    }

    private void updatePermissionFlagsInternal(String packageName, String permName, int flagMask,
            int flagValues, int callingUid, int userId, boolean overridePolicy,
            PermissionCallback callback) {
        if (PermissionManager.DEBUG_TRACE_PERMISSION_UPDATES
                && PermissionManager.shouldTraceGrant(packageName, permName, userId)) {
            Log.i(TAG, "System is updating flags for " + packageName + " "
                            + permName + " for user " + userId  + " "
                            + DebugUtils.flagsToString(
                                    PackageManager.class, "FLAG_PERMISSION_", flagMask)
                            + " := "
                            + DebugUtils.flagsToString(
                                    PackageManager.class, "FLAG_PERMISSION_", flagValues)
                            + " on behalf of uid " + callingUid
                            + " " + mPackageManagerInt.getNameForUid(callingUid),
                    new RuntimeException());
        }

        if (!mUserManagerInt.exists(userId)) {
            return;
        }

        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");

        enforceCrossUserPermission(callingUid, userId,
                true,  // requireFullPermission
                true,  // checkShell
                "updatePermissionFlags");

        if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
            throw new SecurityException("updatePermissionFlags requires "
                    + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
        }

        // Only the system can change these flags and nothing else.
        if (callingUid != Process.SYSTEM_UID) {
            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
            flagValues &= ~FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
            flagValues &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
            flagValues &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
            flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
        }

        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        if (pkg == null) {
            Log.e(TAG, "Unknown package: " + packageName);
            return;
        }
        if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId,
                false /* filterUninstalled */)) {
            throw new IllegalArgumentException("Unknown package: " + packageName);
        }

        boolean isRequested = false;
        // Fast path, the current package has requested the permission.
        if (pkg.getRequestedPermissions().contains(permName)) {
            isRequested = true;
        }
        if (!isRequested) {
            // Slow path, go through all shared user packages.
            String[] sharedUserPackageNames =
                    mPackageManagerInt.getSharedUserPackagesForPackage(packageName, userId);
            for (String sharedUserPackageName : sharedUserPackageNames) {
                AndroidPackage sharedUserPkg = mPackageManagerInt.getPackage(
                        sharedUserPackageName);
                if (sharedUserPkg != null
                        && sharedUserPkg.getRequestedPermissions().contains(permName)) {
                    isRequested = true;
                    break;
                }
            }
        }

        final boolean isRuntimePermission;
        final boolean permissionUpdated;
        synchronized (mLock) {
            final Permission bp = mRegistry.getPermission(permName);
            if (bp == null) {
                throw new IllegalArgumentException("Unknown permission: " + permName);
            }

            isRuntimePermission = bp.isRuntime();

            final UidPermissionState uidState = getUidStateLocked(pkg, userId);
            if (uidState == null) {
                Slog.e(TAG, "Missing permissions state for " + packageName + " and user " + userId);
                return;
            }

            if (!uidState.hasPermissionState(permName) && !isRequested) {
                Log.e(TAG, "Permission " + permName + " isn't requested by package " + packageName);
                return;
            }

            permissionUpdated = uidState.updatePermissionFlags(bp, flagMask, flagValues);
        }

        if (permissionUpdated && callback != null) {
            // Install and runtime permissions are stored in different places,
            // so figure out what permission changed and persist the change.
            if (!isRuntimePermission) {
                callback.onInstallPermissionUpdated();
            } else {
                callback.onPermissionUpdated(new int[]{ userId }, false, pkg.getUid());
            }
        }
    }

    /**
     * Update the permission flags for all packages and runtime permissions of a user in order
     * to allow device or profile owner to remove POLICY_FIXED.
     */
    @Override
    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues,
            final int userId) {
        final int callingUid = Binder.getCallingUid();
        if (!mUserManagerInt.exists(userId)) {
            return;
        }

        enforceGrantRevokeRuntimePermissionPermissions(
                "updatePermissionFlagsForAllApps");
        enforceCrossUserPermission(callingUid, userId,
                true,  // requireFullPermission
                true,  // checkShell
                "updatePermissionFlagsForAllApps");

        // Only the system can change system fixed flags.
        final int effectiveFlagMask = (callingUid != Process.SYSTEM_UID)
                ? flagMask : flagMask & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
        final int effectiveFlagValues = (callingUid != Process.SYSTEM_UID)
                ? flagValues : flagValues & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;

        final boolean[] changed = new boolean[1];
        mPackageManagerInt.forEachPackage(pkg -> {
            synchronized (mLock) {
                final UidPermissionState uidState = getUidStateLocked(pkg, userId);
                if (uidState == null) {
                    Slog.e(TAG,
                            "Missing permissions state for " + pkg.getPackageName() + " and user "
                                    + userId);
                    return;
                }
                changed[0] |= uidState.updatePermissionFlagsForAllPermissions(
                        effectiveFlagMask, effectiveFlagValues);
            }
            mOnPermissionChangeListeners.onPermissionsChanged(pkg.getUid());
        });

        if (changed[0]) {
            mPackageManagerInt.writePermissionSettings(new int[] { userId }, true);
        }
    }

    private int checkPermission(String pkgName, String permName, int userId) {
        return checkPermission(pkgName, permName, Context.DEVICE_ID_DEFAULT, userId);
    }

    @Override
    public int checkPermission(String pkgName, String permName, int deviceId, int userId) {
        if (!mUserManagerInt.exists(userId)) {
            return PackageManager.PERMISSION_DENIED;
        }

        final AndroidPackage pkg = mPackageManagerInt.getPackage(pkgName);
        if (pkg == null) {
            return PackageManager.PERMISSION_DENIED;
        }
        return checkPermissionInternal(pkg, true, permName, userId);
    }

    private int checkPermissionInternal(@NonNull AndroidPackage pkg, boolean isPackageExplicit,
            @NonNull String permissionName, @UserIdInt int userId) {
        final int callingUid = Binder.getCallingUid();
        if (isPackageExplicit || pkg.getSharedUserId() == null) {
            if (mPackageManagerInt.filterAppAccess(pkg.getPackageName(), callingUid, userId,
                    false /* filterUninstalled */)) {
                return PackageManager.PERMISSION_DENIED;
            }
        } else {
            if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
                return PackageManager.PERMISSION_DENIED;
            }
        }

        final int uid = UserHandle.getUid(userId, pkg.getUid());
        final boolean isInstantApp = mPackageManagerInt.getInstantAppPackageName(uid) != null;

        synchronized (mLock) {
            final UidPermissionState uidState = getUidStateLocked(pkg, userId);
            if (uidState == null) {
                Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user "
                        + userId);
                return PackageManager.PERMISSION_DENIED;
            }

            if (checkSinglePermissionInternalLocked(uidState, permissionName, isInstantApp)) {
                return PackageManager.PERMISSION_GRANTED;
            }

            final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
            if (fullerPermissionName != null && checkSinglePermissionInternalLocked(uidState,
                    fullerPermissionName, isInstantApp)) {
                return PackageManager.PERMISSION_GRANTED;
            }
        }

        return PackageManager.PERMISSION_DENIED;
    }

    @GuardedBy("mLock")
    private boolean checkSinglePermissionInternalLocked(@NonNull UidPermissionState uidState,
            @NonNull String permissionName, boolean isInstantApp) {
        if (!uidState.isPermissionGranted(permissionName)) {
            return false;
        }

        if (isInstantApp) {
            final Permission permission = mRegistry.getPermission(permissionName);
            return permission != null && permission.isInstant();
        }

        return true;
    }

    private int checkUidPermission(int uid, String permName) {
        return checkUidPermission(uid, permName, Context.DEVICE_ID_DEFAULT);
    }

    @Override
    public int checkUidPermission(int uid, String permName, int deviceId) {
        final int userId = UserHandle.getUserId(uid);
        if (!mUserManagerInt.exists(userId)) {
            return PackageManager.PERMISSION_DENIED;
        }

        final AndroidPackage pkg = mPackageManagerInt.getPackage(uid);
        return checkUidPermissionInternal(pkg, uid, permName);
    }

    /**
     * Checks whether or not the given package has been granted the specified
     * permission. If the given package is {@code null}, we instead check the
     * system permissions for the given UID.
     *
     * @see SystemConfig#getSystemPermissions()
     */
    private int checkUidPermissionInternal(@Nullable AndroidPackage pkg, int uid,
            @NonNull String permissionName) {
        if (pkg != null) {
            final int userId = UserHandle.getUserId(uid);
            return checkPermissionInternal(pkg, false, permissionName, userId);
        }

        synchronized (mLock) {
            if (checkSingleUidPermissionInternalLocked(uid, permissionName)) {
                return PackageManager.PERMISSION_GRANTED;
            }

            final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
            if (fullerPermissionName != null
                    && checkSingleUidPermissionInternalLocked(uid, fullerPermissionName)) {
                return PackageManager.PERMISSION_GRANTED;
            }
        }

        return PackageManager.PERMISSION_DENIED;
    }

    @GuardedBy("mLock")
    private boolean checkSingleUidPermissionInternalLocked(int uid,
            @NonNull String permissionName) {
        ArraySet<String> permissions = mSystemPermissions.get(uid);
        return permissions != null && permissions.contains(permissionName);
    }

    @Override
    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
        mContext.enforceCallingOrSelfPermission(
                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
                "addOnPermissionsChangeListener");

        mOnPermissionChangeListeners.addListener(listener);
    }

    @Override
    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
        if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
            throw new SecurityException("Instant applications don't have access to this method");
        }
        mOnPermissionChangeListeners.removeListener(listener);
    }

    @Nullable
    @Override
    public List<String> getAllowlistedRestrictedPermissions(@NonNull String packageName,
            @PackageManager.PermissionWhitelistFlags int flags, @UserIdInt int userId) {
        Objects.requireNonNull(packageName);
        Preconditions.checkFlagsArgument(flags,
                PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
                        | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
                        | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
        Preconditions.checkArgumentNonNegative(userId, null);

        if (UserHandle.getCallingUserId() != userId) {
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS,
                    "getAllowlistedRestrictedPermissions for user " + userId);
        }

        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        if (pkg == null) {
            return null;
        }

        final int callingUid = Binder.getCallingUid();
        if (mPackageManagerInt.filterAppAccess(packageName, callingUid,
                UserHandle.getCallingUserId(), false /* filterUninstalled */)) {
            return null;
        }
        final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
                Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
                        == PackageManager.PERMISSION_GRANTED;
        final boolean isCallerInstallerOnRecord =
                mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);

        if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
                && !isCallerPrivileged) {
            throw new SecurityException("Querying system allowlist requires "
                    + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
        }

        if ((flags & (PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
                | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) != 0) {
            if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
                throw new SecurityException("Querying upgrade or installer allowlist"
                        + " requires being installer on record or "
                        + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
            }
        }

        final long identity = Binder.clearCallingIdentity();
        try {
            return getAllowlistedRestrictedPermissionsInternal(pkg, flags, userId);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    @Nullable
    private List<String> getAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg,
            @PackageManager.PermissionWhitelistFlags int flags, @UserIdInt int userId) {
        synchronized (mLock) {
            final UidPermissionState uidState = getUidStateLocked(pkg, userId);
            if (uidState == null) {
                Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user "
                        + userId);
                return null;
            }

            int queryFlags = 0;
            if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
                queryFlags |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
            }
            if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
                queryFlags |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
            }
            if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
                queryFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
            }

            ArrayList<String> allowlistedPermissions = null;

            for (final String permissionName : pkg.getRequestedPermissions()) {
                final int currentFlags =
                        uidState.getPermissionFlags(permissionName);
                if ((currentFlags & queryFlags) != 0) {
                    if (allowlistedPermissions == null) {
                        allowlistedPermissions = new ArrayList<>();
                    }
                    allowlistedPermissions.add(permissionName);
                }
            }

            return allowlistedPermissions;
        }
    }

    @Override
    public boolean addAllowlistedRestrictedPermission(@NonNull String packageName,
            @NonNull String permName, @PackageManager.PermissionWhitelistFlags int flags,
            @UserIdInt int userId) {
        // Other argument checks are done in get/setAllowlistedRestrictedPermissions
        Objects.requireNonNull(permName);

        if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
            return false;
        }

        List<String> permissions =
                getAllowlistedRestrictedPermissions(packageName, flags, userId);
        if (permissions == null) {
            permissions = new ArrayList<>(1);
        }
        if (permissions.indexOf(permName) < 0) {
            permissions.add(permName);
            return setAllowlistedRestrictedPermissions(packageName, permissions,
                    flags, userId);
        }
        return false;
    }

    private boolean checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(
            @NonNull String permName) {
        final String permissionPackageName;
        final boolean isImmutablyRestrictedPermission;
        synchronized (mLock) {
            final Permission bp = mRegistry.getPermission(permName);
            if (bp == null) {
                Slog.w(TAG, "No such permissions: " + permName);
                return false;
            }
            permissionPackageName = bp.getPackageName();
            isImmutablyRestrictedPermission = bp.isHardOrSoftRestricted()
                    && bp.isImmutablyRestricted();
        }

        final int callingUid = Binder.getCallingUid();
        final int callingUserId = UserHandle.getUserId(callingUid);
        if (mPackageManagerInt.filterAppAccess(permissionPackageName, callingUid, callingUserId,
                false /* filterUninstalled */)) {
            EventLog.writeEvent(0x534e4554, "186404356", callingUid, permName);
            return false;
        }

        if (isImmutablyRestrictedPermission && mContext.checkCallingOrSelfPermission(
                Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Cannot modify allowlisting of an immutably "
                    + "restricted permission: " + permName);
        }

        return true;
    }

    @Override
    public boolean removeAllowlistedRestrictedPermission(@NonNull String packageName,
            @NonNull String permName, @PackageManager.PermissionWhitelistFlags int flags,
            @UserIdInt int userId) {
        // Other argument checks are done in get/setAllowlistedRestrictedPermissions
        Objects.requireNonNull(permName);

        if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
            return false;
        }

        final List<String> permissions =
                getAllowlistedRestrictedPermissions(packageName, flags, userId);
        if (permissions != null && permissions.remove(permName)) {
            return setAllowlistedRestrictedPermissions(packageName, permissions,
                    flags, userId);
        }
        return false;
    }

    private boolean setAllowlistedRestrictedPermissions(@NonNull String packageName,
            @Nullable List<String> permissions, @PackageManager.PermissionWhitelistFlags int flags,
            @UserIdInt int userId) {
        Objects.requireNonNull(packageName);
        Preconditions.checkFlagsArgument(flags,
                PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
                        | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
                        | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
        Preconditions.checkArgument(Integer.bitCount(flags) == 1);
        Preconditions.checkArgumentNonNegative(userId, null);

        if (UserHandle.getCallingUserId() != userId) {
            mContext.enforceCallingOrSelfPermission(
                    Manifest.permission.INTERACT_ACROSS_USERS,
                    "setAllowlistedRestrictedPermissions for user " + userId);
        }

        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        if (pkg == null) {
            return false;
        }

        final int callingUid = Binder.getCallingUid();
        if (mPackageManagerInt.filterAppAccess(packageName, callingUid,
                UserHandle.getCallingUserId(), false /* filterUninstalled */)) {
            return false;
        }

        final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
                Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
                        == PackageManager.PERMISSION_GRANTED;
        final boolean isCallerInstallerOnRecord =
                mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);

        if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0 && !isCallerPrivileged) {
            throw new SecurityException("Modifying system allowlist requires "
                    + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
        }

        if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
            if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
                throw new SecurityException("Modifying upgrade allowlist requires"
                        + " being installer on record or "
                        + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
            }
            final List<String> allowlistedPermissions =
                    getAllowlistedRestrictedPermissions(pkg.getPackageName(), flags, userId);
            if (permissions == null || permissions.isEmpty()) {
                if (allowlistedPermissions == null || allowlistedPermissions.isEmpty()) {
                    return true;
                }
            } else {
                // Only the system can add and remove while the installer can only remove.
                final int permissionCount = permissions.size();
                for (int i = 0; i < permissionCount; i++) {
                    if ((allowlistedPermissions == null
                            || !allowlistedPermissions.contains(permissions.get(i)))
                            && !isCallerPrivileged) {
                        throw new SecurityException("Adding to upgrade allowlist requires"
                                + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
                    }
                }
            }
        }

        if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
            if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
                throw new SecurityException("Modifying installer allowlist requires"
                        + " being installer on record or "
                        + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
            }
        }

        final long identity = Binder.clearCallingIdentity();
        try {
            setAllowlistedRestrictedPermissionsInternal(pkg, permissions, flags, userId);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }

        return true;
    }

    @Override
    public void grantRuntimePermission(String packageName, String permName, int deviceId,
            int userId) {
        final int callingUid = Binder.getCallingUid();
        final boolean overridePolicy =
                checkUidPermission(callingUid, ADJUST_RUNTIME_PERMISSIONS_POLICY)
                        == PackageManager.PERMISSION_GRANTED;

        grantRuntimePermissionInternal(packageName, permName, overridePolicy,
                callingUid, userId, mDefaultPermissionCallback);
    }

    private void grantRuntimePermissionInternal(String packageName, String permName,
            boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
        if (PermissionManager.DEBUG_TRACE_GRANTS
                && PermissionManager.shouldTraceGrant(packageName, permName, userId)) {
            Log.i(PermissionManager.LOG_TAG_TRACE_GRANTS, "System is granting " + packageName + " "
                    + permName + " for user " + userId + " on behalf of uid " + callingUid
                    + " " + mPackageManagerInt.getNameForUid(callingUid),
                    new RuntimeException());
        }
        if (!mUserManagerInt.exists(userId)) {
            Log.e(TAG, "No such user:" + userId);
            return;
        }

        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
                "grantRuntimePermission");

        enforceCrossUserPermission(callingUid, userId,
                true,  // requireFullPermission
                true,  // checkShell
                "grantRuntimePermission");

        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        final PackageStateInternal ps = mPackageManagerInt.getPackageStateInternal(packageName);
        if (pkg == null || ps == null) {
            Log.e(TAG, "Unknown package: " + packageName);
            return;
        }
        if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId,
                false /* filterUninstalled */)) {
            throw new IllegalArgumentException("Unknown package: " + packageName);
        }

        final boolean isRolePermission;
        final boolean isSoftRestrictedPermission;
        synchronized (mLock) {
            final Permission permission = mRegistry.getPermission(permName);
            if (permission == null) {
                throw new IllegalArgumentException("Unknown permission: " + permName);
            }
            isRolePermission = permission.isRole();
            isSoftRestrictedPermission = permission.isSoftRestricted();
        }
        final boolean mayGrantRolePermission = isRolePermission
                && mayManageRolePermission(callingUid);
        final boolean mayGrantSoftRestrictedPermission = isSoftRestrictedPermission
                && SoftRestrictedPermissionPolicy.forPermission(mContext,
                        AndroidPackageUtils.generateAppInfoWithoutState(pkg), pkg,
                        UserHandle.of(userId), permName)
                        .mayGrantPermission();

        final boolean isRuntimePermission;
        final boolean permissionHasGids;
        synchronized (mLock) {
            final Permission bp = mRegistry.getPermission(permName);
            if (bp == null) {
                throw new IllegalArgumentException("Unknown permission: " + permName);
            }

            isRuntimePermission = bp.isRuntime();
            permissionHasGids = bp.hasGids();
            if (isRuntimePermission || bp.isDevelopment()) {
                // Good.
            } else if (bp.isRole()) {
                if (!mayGrantRolePermission) {
                    throw new SecurityException("Permission " + permName + " is managed by role");
                }
            } else {
                throw new SecurityException("Permission " + permName + " requested by "
                        + pkg.getPackageName() + " is not a changeable permission type");
            }

            final UidPermissionState uidState = getUidStateLocked(pkg, userId);
            if (uidState == null) {
                Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user "
                        + userId);
                return;
            }

            if (!(uidState.hasPermissionState(permName)
                    || pkg.getRequestedPermissions().contains(permName))) {
                throw new SecurityException("Package " + pkg.getPackageName()
                        + " has not requested permission " + permName);
            }

            // If a permission review is required for legacy apps we represent
            // their permissions as always granted runtime ones since we need
            // to keep the review required permission flag per user while an
            // install permission's state is shared across all users.
            if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime()) {
                return;
            }

            final int flags = uidState.getPermissionFlags(permName);
            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
                Log.e(TAG, "Cannot grant system fixed permission "
                        + permName + " for package " + packageName);
                return;
            }
            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
                Log.e(TAG, "Cannot grant policy fixed permission "
                        + permName + " for package " + packageName);
                return;
            }

            if (bp.isHardRestricted()
                    && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
                Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
                        + permName + " for package " + packageName);
                return;
            }

            if (bp.isSoftRestricted() && !mayGrantSoftRestrictedPermission) {
                Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
                        + packageName);
                return;
            }

            if (bp.isDevelopment() || bp.isRole()) {
                // Development permissions must be handled specially, since they are not
                // normal runtime permissions.  For now they apply to all users.
                // TODO(zhanghai): We are breaking the behavior above by making all permission state
                //  per-user. It isn't documented behavior and relatively rarely used anyway.
                if (!uidState.grantPermission(bp)) {
                    return;
                }
            } else {
                if (ps.getUserStateOrDefault(userId).isInstantApp() && !bp.isInstant()) {
                    throw new SecurityException("Cannot grant non-ephemeral permission " + permName
                            + " for package " + packageName);
                }

                if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
                    Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
                    return;
                }

                if (!uidState.grantPermission(bp)) {
                    return;
                }
            }
        }

        if (isRuntimePermission) {
            logPermission(MetricsProto.MetricsEvent.ACTION_PERMISSION_GRANTED,
                    permName, packageName);
        }

        final int uid = UserHandle.getUid(userId, pkg.getUid());
        if (callback != null) {
            if (isRuntimePermission) {
                callback.onPermissionGranted(uid, userId);
            } else {
                callback.onInstallPermissionGranted();
            }
            if (permissionHasGids) {
                callback.onGidsChanged(UserHandle.getAppId(pkg.getUid()), userId);
            }
        }
    }

    @Override
    public void revokeRuntimePermission(String packageName, String permName, int deviceId,
            int userId, String reason) {
        final int callingUid = Binder.getCallingUid();
        final boolean overridePolicy =
                checkUidPermission(callingUid, ADJUST_RUNTIME_PERMISSIONS_POLICY, deviceId)
                        == PackageManager.PERMISSION_GRANTED;

        revokeRuntimePermissionInternal(packageName, permName, overridePolicy, callingUid, userId,
                reason, mDefaultPermissionCallback);
    }

    @Override
    public void revokePostNotificationPermissionWithoutKillForTest(String packageName, int userId) {
        final int callingUid = Binder.getCallingUid();
        final boolean overridePolicy =
                checkUidPermission(callingUid, ADJUST_RUNTIME_PERMISSIONS_POLICY)
                        == PackageManager.PERMISSION_GRANTED;
        mContext.enforceCallingPermission(
                android.Manifest.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL, "");
        revokeRuntimePermissionInternal(packageName, Manifest.permission.POST_NOTIFICATIONS,
                overridePolicy, true, callingUid, userId,
                SKIP_KILL_APP_REASON_NOTIFICATION_TEST, mDefaultPermissionCallback);
    }

    private void revokeRuntimePermissionInternal(String packageName, String permName,
            boolean overridePolicy, int callingUid, final int userId,
            String reason, PermissionCallback callback) {
        revokeRuntimePermissionInternal(packageName, permName, overridePolicy, false, callingUid,
                userId, reason, callback);
    }

    private void revokeRuntimePermissionInternal(String packageName, String permName,
            boolean overridePolicy, boolean overrideKill, int callingUid, final int userId,
            String reason, PermissionCallback callback) {
        if (PermissionManager.DEBUG_TRACE_PERMISSION_UPDATES
                && PermissionManager.shouldTraceGrant(packageName, permName, userId)) {
            Log.i(TAG, "System is revoking " + packageName + " "
                            + permName + " for user " + userId + " on behalf of uid " + callingUid
                            + " " + mPackageManagerInt.getNameForUid(callingUid),
                    new RuntimeException());
        }
        if (!mUserManagerInt.exists(userId)) {
            Log.e(TAG, "No such user:" + userId);
            return;
        }

        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
                "revokeRuntimePermission");

        enforceCrossUserPermission(callingUid, userId,
                true,  // requireFullPermission
                true,  // checkShell
                "revokeRuntimePermission");

        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        if (pkg == null) {
            Log.e(TAG, "Unknown package: " + packageName);
            return;
        }
        if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId,
                false /* filterUninstalled */)) {
            throw new IllegalArgumentException("Unknown package: " + packageName);
        }

        final boolean isRolePermission;
        synchronized (mLock) {
            final Permission permission = mRegistry.getPermission(permName);
            if (permission == null) {
                throw new IllegalArgumentException("Unknown permission: " + permName);
            }
            isRolePermission = permission.isRole();
        }
        final boolean mayRevokeRolePermission = isRolePermission
                // Allow ourselves to revoke role permissions due to definition changes.
                && (callingUid == Process.myUid() || mayManageRolePermission(callingUid));

        final boolean isRuntimePermission;
        synchronized (mLock) {
            final Permission bp = mRegistry.getPermission(permName);
            if (bp == null) {
                throw new IllegalArgumentException("Unknown permission: " + permName);
            }

            isRuntimePermission = bp.isRuntime();
            if (isRuntimePermission || bp.isDevelopment()) {
                // Good.
            } else if (bp.isRole()) {
                if (!mayRevokeRolePermission) {
                    throw new SecurityException("Permission " + permName + " is managed by role");
                }
            } else {
                throw new SecurityException("Permission " + permName + " requested by "
                        + pkg.getPackageName() + " is not a changeable permission type");
            }

            final UidPermissionState uidState = getUidStateLocked(pkg, userId);
            if (uidState == null) {
                Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user "
                        + userId);
                return;
            }

            if (!(uidState.hasPermissionState(permName)
                    || pkg.getRequestedPermissions().contains(permName))) {
                throw new SecurityException("Package " + pkg.getPackageName()
                        + " has not requested permission " + permName);
            }

            // If a permission review is required for legacy apps we represent
            // their permissions as always granted runtime ones since we need
            // to keep the review required permission flag per user while an
            // install permission's state is shared across all users.
            if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime()) {
                return;
            }

            final int flags = uidState.getPermissionFlags(permName);
            // Only the system may revoke SYSTEM_FIXED permissions.
            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
                    && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
                throw new SecurityException("Non-System UID cannot revoke system fixed permission "
                        + permName + " for package " + packageName);
            }
            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
                throw new SecurityException("Cannot revoke policy fixed permission "
                        + permName + " for package " + packageName);
            }

            // Development permissions must be handled specially, since they are not
            // normal runtime permissions.  For now they apply to all users.
            // TODO(zhanghai): We are breaking the behavior above by making all permission state
            //  per-user. It isn't documented behavior and relatively rarely used anyway.
            if (!uidState.revokePermission(bp)) {
                return;
            }
        }

        if (isRuntimePermission) {
            logPermission(MetricsProto.MetricsEvent.ACTION_PERMISSION_REVOKED,
                    permName, packageName);
        }

        if (callback != null) {
            if (isRuntimePermission) {
                callback.onPermissionRevoked(UserHandle.getUid(userId, pkg.getUid()), userId,
                        reason, overrideKill, permName);
            } else {
                mDefaultPermissionCallback.onInstallPermissionRevoked();
            }
        }
    }

    private boolean mayManageRolePermission(int uid) {
        final PackageManager packageManager = mContext.getPackageManager();
        final String[] packageNames = packageManager.getPackagesForUid(uid);
        if (packageNames == null) {
            return false;
        }
        final String permissionControllerPackageName =
                packageManager.getPermissionControllerPackageName();
        return Arrays.asList(packageNames).contains(permissionControllerPackageName);
    }

    /**
     * Reverts user permission state changes (permissions and flags).
     *
     * @param filterPkg The package for which to reset, or {@code null} for all packages.
     * @param userId The device user for which to do a reset.
     */
    private void resetRuntimePermissionsInternal(@Nullable AndroidPackage filterPkg,
            @UserIdInt int userId) {
        // Delay and combine non-async permission callbacks
        final boolean[] permissionRemoved = new boolean[1];
        final ArraySet<Long> revokedPermissions = new ArraySet<>();
        final ArraySet<Integer> syncUpdatedUsers = new ArraySet<>();
        final ArraySet<Integer> asyncUpdatedUsers = new ArraySet<>();

        PermissionCallback delayingPermCallback = new PermissionCallback() {
            public void onGidsChanged(int appId, int userId) {
                mDefaultPermissionCallback.onGidsChanged(appId, userId);
            }

            public void onPermissionChanged() {
                mDefaultPermissionCallback.onPermissionChanged();
            }

            public void onPermissionGranted(int uid, int userId) {
                mDefaultPermissionCallback.onPermissionGranted(uid, userId);
            }

            public void onInstallPermissionGranted() {
                mDefaultPermissionCallback.onInstallPermissionGranted();
            }

            public void onPermissionRevoked(int uid, int userId, String reason,
                    boolean overrideKill, @Nullable String permissionName) {
                revokedPermissions.add(IntPair.of(uid, userId));

                syncUpdatedUsers.add(userId);
            }

            public void onInstallPermissionRevoked() {
                mDefaultPermissionCallback.onInstallPermissionRevoked();
            }

            public void onPermissionUpdated(int[] userIds, boolean sync, int appId) {
                mOnPermissionChangeListeners.onPermissionsChanged(appId);
                for (int userId : userIds) {
                    if (sync) {
                        syncUpdatedUsers.add(userId);
                        asyncUpdatedUsers.remove(userId);
                    } else {
                        // Don't override sync=true by sync=false
                        if (syncUpdatedUsers.indexOf(userId) == -1) {
                            asyncUpdatedUsers.add(userId);
                        }
                    }
                }
            }

            public void onPermissionRemoved() {
                permissionRemoved[0] = true;
            }

            public void onInstallPermissionUpdated() {
                mDefaultPermissionCallback.onInstallPermissionUpdated();
            }
        };

        if (filterPkg != null) {
            resetRuntimePermissionsInternal(filterPkg, userId, delayingPermCallback);
        } else {
            mPackageManagerInt.forEachPackage(pkg ->
                    resetRuntimePermissionsInternal(pkg, userId, delayingPermCallback));
        }

        // Execute delayed callbacks
        if (permissionRemoved[0]) {
            mDefaultPermissionCallback.onPermissionRemoved();
        }

        // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
        // kill uid while holding mPackages-lock
        if (!revokedPermissions.isEmpty()) {
            int numRevokedPermissions = revokedPermissions.size();
            for (int i = 0; i < numRevokedPermissions; i++) {
                int revocationUID = IntPair.first(revokedPermissions.valueAt(i));
                int revocationUserId = IntPair.second(revokedPermissions.valueAt(i));

                mOnPermissionChangeListeners.onPermissionsChanged(revocationUID);

                // Kill app later as we are holding mPackages
                mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId,
                        KILL_APP_REASON_PERMISSIONS_REVOKED));
            }
        }

        mPackageManagerInt.writePermissionSettings(ArrayUtils.convertToIntArray(syncUpdatedUsers),
                false);
        mPackageManagerInt.writePermissionSettings(ArrayUtils.convertToIntArray(asyncUpdatedUsers),
                true);
    }

    private void resetRuntimePermissionsInternal(@NonNull AndroidPackage pkg,
            @UserIdInt int userId, @NonNull PermissionCallback delayingPermCallback) {
        // These are flags that can change base on user actions.
        final int userSettableMask = FLAG_PERMISSION_USER_SET
                | FLAG_PERMISSION_USER_FIXED
                | FLAG_PERMISSION_REVOKED_COMPAT
                | FLAG_PERMISSION_REVIEW_REQUIRED
                | FLAG_PERMISSION_ONE_TIME
                | FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY;

        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
                | FLAG_PERMISSION_POLICY_FIXED;

        final String packageName = pkg.getPackageName();
        for (final String permName : pkg.getRequestedPermissions()) {
            if (mIsLeanback && NOTIFICATION_PERMISSIONS.contains(permName)) {
                // Do not reset the Notification permissions on TV
                continue;
            }
            final boolean isRuntimePermission;
            synchronized (mLock) {
                final Permission permission = mRegistry.getPermission(permName);
                if (permission == null) {
                    continue;
                }

                if (permission.isRemoved()) {
                    continue;
                }
                isRuntimePermission = permission.isRuntime();
            }

            // If shared user we just reset the state to which only this app contributed.
            final String[] pkgNames = mPackageManagerInt.getSharedUserPackagesForPackage(
                    pkg.getPackageName(), userId);
            if (pkgNames.length > 0) {
                boolean used = false;
                for (String sharedPkgName : pkgNames) {
                    final AndroidPackage sharedPkg =
                            mPackageManagerInt.getPackage(sharedPkgName);
                    if (sharedPkg != null && !sharedPkg.getPackageName().equals(packageName)
                            && sharedPkg.getRequestedPermissions().contains(permName)) {
                        used = true;
                        break;
                    }
                }
                if (used) {
                    continue;
                }
            }

            final int oldFlags =
                    getPermissionFlagsInternal(packageName, permName, Process.SYSTEM_UID, userId);

            // Always clear the user settable flags.
            // If permission review is enabled and this is a legacy app, mark the
            // permission as requiring a review as this is the initial state.
            final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId);
            final int targetSdk = mPackageManagerInt.getUidTargetSdkVersion(uid);
            final int flags = (targetSdk < Build.VERSION_CODES.M && isRuntimePermission)
                    ? FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKED_COMPAT
                    : 0;

            updatePermissionFlagsInternal(
                    packageName, permName, userSettableMask, flags, Process.SYSTEM_UID, userId,
                    false, delayingPermCallback);

            // Below is only runtime permission handling.
            if (!isRuntimePermission) {
                continue;
            }

            // Never clobber system or policy.
            if ((oldFlags & policyOrSystemFlags) != 0) {
                continue;
            }

            // If this permission was granted by default or role, make sure it is.
            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0
                    || (oldFlags & FLAG_PERMISSION_GRANTED_BY_ROLE) != 0) {
                // PermissionPolicyService will handle the app op for runtime permissions later.
                grantRuntimePermissionInternal(packageName, permName, false,
                        Process.SYSTEM_UID, userId, delayingPermCallback);
            // In certain cases we should leave the state unchanged:
            // -- If permission review is enabled the permissions for a legacy apps
            // are represented as constantly granted runtime ones
            // -- If the permission was split from a non-runtime permission
            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0
                    && !isPermissionSplitFromNonRuntime(permName, targetSdk)) {
                // Otherwise, reset the permission.
                revokeRuntimePermissionInternal(packageName, permName, false, Process.SYSTEM_UID,
                        userId, null, delayingPermCallback);
            }
        }
    }

    /**
     * Determine if the given permission should be treated as split from a
     * non-runtime permission for an application targeting the given SDK level.
     */
    private boolean isPermissionSplitFromNonRuntime(String permName, int targetSdk) {
        final List<PermissionManager.SplitPermissionInfo> splitPerms = getSplitPermissionInfos();
        final int size = splitPerms.size();
        for (int i = 0; i < size; i++) {
            final PermissionManager.SplitPermissionInfo splitPerm = splitPerms.get(i);
            if (targetSdk < splitPerm.getTargetSdk()
                    && splitPerm.getNewPermissions().contains(permName)) {
                synchronized (mLock) {
                    final Permission perm =
                            mRegistry.getPermission(splitPerm.getSplitPermission());
                    return perm != null && !perm.isRuntime();
                }
            }
        }
        return false;
    }

    /**
     * This change makes it so that apps are told to show rationale for asking for background
     * location access every time they request.
     */
    @ChangeId
    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
    private static final long BACKGROUND_RATIONALE_CHANGE_ID = 147316723L;

    @Override
    public boolean shouldShowRequestPermissionRationale(String packageName, String permName,
            int deviceId, @UserIdInt int userId) {
        final int callingUid = Binder.getCallingUid();
        if (UserHandle.getCallingUserId() != userId) {
            mContext.enforceCallingPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                    "canShowRequestPermissionRationale for user " + userId);
        }

        final int uid =
                mPackageManagerInt.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
        if (UserHandle.getAppId(callingUid) != UserHandle.getAppId(uid)) {
            return false;
        }

        if (checkPermission(packageName, permName, userId) == PackageManager.PERMISSION_GRANTED) {
            return false;
        }

        final int flags;

        final long identity = Binder.clearCallingIdentity();
        try {
            flags = getPermissionFlagsInternal(packageName, permName, callingUid, userId);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }

        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
                | PackageManager.FLAG_PERMISSION_USER_FIXED;

        if ((flags & fixedFlags) != 0) {
            return false;
        }

        synchronized (mLock) {
            final Permission permission = mRegistry.getPermission(permName);
            if (permission == null) {
                return false;
            }
            if (permission.isHardRestricted()
                    && (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
                return false;
            }
        }

        final long token = Binder.clearCallingIdentity();
        try {
            if (permName.equals(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
                    && mPlatformCompat.isChangeEnabledByPackageName(BACKGROUND_RATIONALE_CHANGE_ID,
                    packageName, userId)) {
                return true;
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Unable to check if compatibility change is enabled.", e);
        } finally {
            Binder.restoreCallingIdentity(token);
        }

        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
    }

    @Override
    public boolean isPermissionRevokedByPolicy(String packageName, String permName, int deviceId,
            int userId) {
        if (UserHandle.getCallingUserId() != userId) {
            mContext.enforceCallingPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                    "isPermissionRevokedByPolicy for user " + userId);
        }

        if (checkPermission(packageName, permName, userId) == PackageManager.PERMISSION_GRANTED) {
            return false;
        }

        final int callingUid = Binder.getCallingUid();
        if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId,
                false /* filterUninstalled */)) {
            return false;
        }

        final long identity = Binder.clearCallingIdentity();
        try {
            final int flags = getPermissionFlagsInternal(packageName, permName, callingUid, userId);
            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    /**
     * Get the state of the runtime permissions as xml file.
     *
     * <p>Can not be called on main thread.
     *
     * @param userId The user ID the data should be extracted for
     *
     * @return The state as a xml file
     */
    @Nullable
    @Override
    public byte[] backupRuntimePermissions(@UserIdInt int userId) {
        Preconditions.checkArgumentNonNegative(userId, "userId");
        CompletableFuture<byte[]> backup = new CompletableFuture<>();
        mPermissionControllerManager.getRuntimePermissionBackup(UserHandle.of(userId),
                PermissionThread.getExecutor(), backup::complete);

        try {
            return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            Slog.e(TAG, "Cannot create permission backup for user " + userId, e);
            return null;
        }
    }

    /**
     * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
     *
     * <p>If not all state can be restored, the un-appliable state will be delayed and can be
     * applied via {@link #restoreDelayedRuntimePermissions}.
     *
     * @param backup The state as an xml file
     * @param userId The user ID the data should be restored for
     */
    @Override
    public void restoreRuntimePermissions(@NonNull byte[] backup, @UserIdInt int userId) {
        Objects.requireNonNull(backup, "backup");
        Preconditions.checkArgumentNonNegative(userId, "userId");
        synchronized (mLock) {
            mHasNoDelayedPermBackup.delete(userId);
        }
        mPermissionControllerManager.stageAndApplyRuntimePermissionsBackup(backup,
                UserHandle.of(userId));
    }

    /**
     * Try to apply permission backup that was previously not applied.
     *
     * <p>Can not be called on main thread.
     *
     * @param packageName The package that is newly installed
     * @param userId The user ID the package is installed for
     *
     * @see #restoreRuntimePermissions
     */
    @Override
    public void restoreDelayedRuntimePermissions(@NonNull String packageName,
            @UserIdInt int userId) {
        Objects.requireNonNull(packageName, "packageName");
        Preconditions.checkArgumentNonNegative(userId, "userId");
        synchronized (mLock) {
            if (mHasNoDelayedPermBackup.get(userId, false)) {
                return;
            }
        }
        mPermissionControllerManager.applyStagedRuntimePermissionBackup(packageName,
                UserHandle.of(userId), PermissionThread.getExecutor(), (hasMoreBackup) -> {
                    if (hasMoreBackup) {
                        return;
                    }
                    synchronized (mLock) {
                        mHasNoDelayedPermBackup.put(userId, true);
                    }
                });
    }

    /**
     * If the app is updated, and has scoped storage permissions, then it is possible that the
     * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions.
     * @param newPackage The new package that was installed
     * @param oldPackage The old package that was updated
     */
    private void revokeStoragePermissionsIfScopeExpandedInternal(
            @NonNull AndroidPackage newPackage,
            @NonNull AndroidPackage oldPackage) {
        boolean downgradedSdk = oldPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q
                && newPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q;
        boolean upgradedSdk = oldPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q
                && newPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q;
        boolean newlyRequestsLegacy = !upgradedSdk && !oldPackage.isRequestLegacyExternalStorage()
                && newPackage.isRequestLegacyExternalStorage();

        if (!newlyRequestsLegacy && !downgradedSdk) {
            return;
        }

        final int callingUid = Binder.getCallingUid();
        for (int userId: getAllUserIds()) {
            for (final String permName : newPackage.getRequestedPermissions()) {
                PermissionInfo permInfo = getPermissionInfo(permName, 0,
                        newPackage.getPackageName());
                if (permInfo == null) {
                    continue;
                }
                boolean isStorageOrMedia = STORAGE_PERMISSIONS.contains(permInfo.name)
                        || READ_MEDIA_AURAL_PERMISSIONS.contains(permInfo.name)
                        || READ_MEDIA_VISUAL_PERMISSIONS.contains(permInfo.name);
                if (!isStorageOrMedia) {
                    continue;
                }
                boolean isSystemOrPolicyFixed = (getPermissionFlags(newPackage.getPackageName(),
                        permInfo.name, Context.DEVICE_ID_DEFAULT, userId) & (
                        FLAG_PERMISSION_SYSTEM_FIXED | FLAG_PERMISSION_POLICY_FIXED)) != 0;
                if (isSystemOrPolicyFixed) {
                    continue;
                }

                EventLog.writeEvent(0x534e4554, "171430330", newPackage.getUid(),
                        "Revoking permission " + permInfo.name + " from package "
                                + newPackage.getPackageName() + " as either the sdk downgraded "
                                + downgradedSdk + " or newly requested legacy full storage "
                                + newlyRequestsLegacy);

                try {
                    revokeRuntimePermissionInternal(newPackage.getPackageName(), permInfo.name,
                            false, callingUid, userId, null, mDefaultPermissionCallback);
                } catch (IllegalStateException | SecurityException e) {
                    Log.e(TAG, "unable to revoke " + permInfo.name + " for "
                            + newPackage.getPackageName() + " user " + userId, e);
                }
            }
        }

    }

    /**
     * If the package was below api 23, got the SYSTEM_ALERT_WINDOW permission automatically, and
     * then updated past api 23, and the app does not satisfy any of the other SAW permission flags,
     * the permission should be revoked.
     *
     * @param newPackage The new package that was installed
     * @param oldPackage The old package that was updated
     */
    private void revokeSystemAlertWindowIfUpgradedPast23(
            @NonNull AndroidPackage newPackage,
            @NonNull AndroidPackage oldPackage) {
        if (oldPackage.getTargetSdkVersion() >= Build.VERSION_CODES.M
                || newPackage.getTargetSdkVersion() < Build.VERSION_CODES.M
                || !newPackage.getRequestedPermissions()
                .contains(Manifest.permission.SYSTEM_ALERT_WINDOW)) {
            return;
        }

        Permission saw;
        synchronized (mLock) {
            saw = mRegistry.getPermission(Manifest.permission.SYSTEM_ALERT_WINDOW);
        }
        final PackageStateInternal ps =
                mPackageManagerInt.getPackageStateInternal(newPackage.getPackageName());
        if (shouldGrantPermissionByProtectionFlags(newPackage, ps, saw, new ArraySet<>())
                || shouldGrantPermissionBySignature(newPackage, saw)) {
            return;
        }
        for (int userId : getAllUserIds()) {
            try {
                revokePermissionFromPackageForUser(newPackage.getPackageName(),
                        Manifest.permission.SYSTEM_ALERT_WINDOW, false, userId,
                        mDefaultPermissionCallback);
            } catch (IllegalStateException | SecurityException e) {
                Log.e(TAG, "unable to revoke SYSTEM_ALERT_WINDOW for "
                        + newPackage.getPackageName() + " user " + userId, e);
            }
        }
    }

    /**
     * We might auto-grant permissions if any permission of the group is already granted. Hence if
     * the group of a granted permission changes we need to revoke it to avoid having permissions of
     * the new group auto-granted.
     *
     * @param newPackage The new package that was installed
     * @param oldPackage The old package that was updated
     */
    private void revokeRuntimePermissionsIfGroupChangedInternal(@NonNull AndroidPackage newPackage,
            @NonNull AndroidPackage oldPackage) {
        final int numOldPackagePermissions = ArrayUtils.size(oldPackage.getPermissions());
        final ArrayMap<String, String> oldPermissionNameToGroupName =
                new ArrayMap<>(numOldPackagePermissions);

        for (int i = 0; i < numOldPackagePermissions; i++) {
            final ParsedPermission permission = oldPackage.getPermissions().get(i);

            if (permission.getParsedPermissionGroup() != null) {
                oldPermissionNameToGroupName.put(permission.getName(),
                        permission.getParsedPermissionGroup().getName());
            }
        }

        final int callingUid = Binder.getCallingUid();
        final int numNewPackagePermissions = ArrayUtils.size(newPackage.getPermissions());
        for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
                newPermissionNum++) {
            final ParsedPermission newPermission =
                    newPackage.getPermissions().get(newPermissionNum);
            final int newProtection = ParsedPermissionUtils.getProtection(newPermission);

            if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
                final String permissionName = newPermission.getName();
                final String newPermissionGroupName =
                        newPermission.getParsedPermissionGroup() == null
                                ? null : newPermission.getParsedPermissionGroup().getName();
                final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
                        permissionName);

                if (newPermissionGroupName != null
                        && !newPermissionGroupName.equals(oldPermissionGroupName)) {
                    final int[] userIds = mUserManagerInt.getUserIds();
                    mPackageManagerInt.forEachPackage(pkg -> {
                        final String packageName = pkg.getPackageName();
                        for (final int userId : userIds) {
                            final int permissionState =
                                    checkPermission(packageName, permissionName, userId);
                            if (permissionState == PackageManager.PERMISSION_GRANTED) {
                                EventLog.writeEvent(0x534e4554, "72710897",
                                        newPackage.getUid(),
                                        "Revoking permission " + permissionName +
                                        " from package " + packageName +
                                        " as the group changed from " + oldPermissionGroupName +
                                        " to " + newPermissionGroupName);

                                try {
                                    revokeRuntimePermissionInternal(packageName, permissionName,
                                            false, callingUid, userId, null,
                                            mDefaultPermissionCallback);
                                } catch (IllegalArgumentException e) {
                                    Slog.e(TAG, "Could not revoke " + permissionName + " from "
                                            + packageName, e);
                                }
                            }
                        }
                    });
                }
            }
        }
    }

    /**
     * If permissions are upgraded to runtime, or their owner changes to the system, then any
     * granted permissions must be revoked.
     *
     * @param permissionsToRevoke A list of permission names to revoke
     */
    private void revokeRuntimePermissionsIfPermissionDefinitionChangedInternal(
            @NonNull List<String> permissionsToRevoke) {
        final int[] userIds = mUserManagerInt.getUserIds();
        final int numPermissions = permissionsToRevoke.size();
        final int callingUid = Binder.getCallingUid();

        for (int permNum = 0; permNum < numPermissions; permNum++) {
            final String permName = permissionsToRevoke.get(permNum);
            final boolean isInternalPermission;
            synchronized (mLock) {
                final Permission bp = mRegistry.getPermission(permName);
                if (bp == null || !(bp.isInternal() || bp.isRuntime())) {
                    continue;
                }
                isInternalPermission = bp.isInternal();
            }
            mPackageManagerInt.forEachPackage(pkg -> {
                final String packageName = pkg.getPackageName();
                final int appId = pkg.getUid();
                if (appId < Process.FIRST_APPLICATION_UID) {
                    // do not revoke from system apps
                    return;
                }
                for (final int userId : userIds) {
                    final int permissionState = checkPermission(packageName, permName,
                            userId);
                    final int flags = getPermissionFlags(packageName, permName,
                            Context.DEVICE_ID_DEFAULT, userId);
                    final int flagMask = FLAG_PERMISSION_SYSTEM_FIXED
                            | FLAG_PERMISSION_POLICY_FIXED
                            | FLAG_PERMISSION_GRANTED_BY_DEFAULT
                            | FLAG_PERMISSION_GRANTED_BY_ROLE;
                    if (permissionState == PackageManager.PERMISSION_GRANTED
                            && (flags & flagMask) == 0) {
                        final int uid = UserHandle.getUid(userId, appId);
                        if (isInternalPermission) {
                            EventLog.writeEvent(0x534e4554, "195338390", uid,
                                    "Revoking permission " + permName + " from package "
                                            + packageName + " due to definition change");
                        } else {
                            EventLog.writeEvent(0x534e4554, "154505240", uid,
                                    "Revoking permission " + permName + " from package "
                                            + packageName + " due to definition change");
                            EventLog.writeEvent(0x534e4554, "168319670", uid,
                                    "Revoking permission " + permName + " from package "
                                            + packageName + " due to definition change");
                        }
                        Slog.e(TAG, "Revoking permission " + permName + " from package "
                                + packageName + " due to definition change");
                        try {
                            revokeRuntimePermissionInternal(packageName, permName,
                                    false, callingUid, userId, null, mDefaultPermissionCallback);
                        } catch (Exception e) {
                            Slog.e(TAG, "Could not revoke " + permName + " from "
                                    + packageName, e);
                        }
                    }
                }
            });
        }
    }

    private List<String> addAllPermissionsInternal(@NonNull PackageState packageState,
                    @NonNull AndroidPackage pkg) {
        final int N = ArrayUtils.size(pkg.getPermissions());
        ArrayList<String> definitionChangedPermissions = new ArrayList<>();
        for (int i=0; i<N; i++) {
            ParsedPermission p = pkg.getPermissions().get(i);

            final PermissionInfo permissionInfo;
            final Permission oldPermission;
            synchronized (mLock) {
                // Now that permission groups have a special meaning, we ignore permission
                // groups for legacy apps to prevent unexpected behavior. In particular,
                // permissions for one app being granted to someone just because they happen
                // to be in a group defined by another app (before this had no implications).
                if (pkg.getTargetSdkVersion() > Build.VERSION_CODES.LOLLIPOP_MR1) {
                    ComponentMutateUtils.setParsedPermissionGroup(p,
                            mRegistry.getPermissionGroup(p.getGroup()));
                    // Warn for a permission in an unknown group.
                    if (DEBUG_PERMISSIONS
                            && p.getGroup() != null && p.getParsedPermissionGroup() == null) {
                        Slog.i(TAG, "Permission " + p.getName() + " from package "
                                + p.getPackageName() + " in an unknown group " + p.getGroup());
                    }
                }

                permissionInfo = PackageInfoUtils.generatePermissionInfo(p,
                        PackageManager.GET_META_DATA);
                oldPermission = p.isTree() ? mRegistry.getPermissionTree(p.getName())
                        : mRegistry.getPermission(p.getName());
            }
            // TODO(zhanghai): Maybe we should store whether a permission is owned by system inside
            //  itself.
            final boolean isOverridingSystemPermission = Permission.isOverridingSystemPermission(
                    oldPermission, permissionInfo, mPackageManagerInt);
            synchronized (mLock) {
                final Permission permission = Permission.createOrUpdate(oldPermission,
                        permissionInfo, packageState, mRegistry.getPermissionTrees(),
                        isOverridingSystemPermission);
                if (p.isTree()) {
                    mRegistry.addPermissionTree(permission);
                } else {
                    mRegistry.addPermission(permission);
                }
                if (permission.isDefinitionChanged()) {
                    definitionChangedPermissions.add(p.getName());
                    permission.setDefinitionChanged(false);
                }
            }
        }
        return definitionChangedPermissions;
    }

    private void addAllPermissionGroupsInternal(@NonNull AndroidPackage pkg) {
        synchronized (mLock) {
            final int N = ArrayUtils.size(pkg.getPermissionGroups());
            StringBuilder r = null;
            for (int i = 0; i < N; i++) {
                final ParsedPermissionGroup pg = pkg.getPermissionGroups().get(i);
                final ParsedPermissionGroup cur = mRegistry.getPermissionGroup(pg.getName());
                final String curPackageName = (cur == null) ? null : cur.getPackageName();
                final boolean isPackageUpdate = pg.getPackageName().equals(curPackageName);
                if (cur == null || isPackageUpdate) {
                    mRegistry.addPermissionGroup(pg);
                    if (DEBUG_PACKAGE_SCANNING) {
                        if (r == null) {
                            r = new StringBuilder(256);
                        } else {
                            r.append(' ');
                        }
                        if (isPackageUpdate) {
                            r.append("UPD:");
                        }
                        r.append(pg.getName());
                    }
                } else {
                    Slog.w(TAG, "Permission group " + pg.getName() + " from package "
                            + pg.getPackageName() + " ignored: original from "
                            + cur.getPackageName());
                    if (DEBUG_PACKAGE_SCANNING) {
                        if (r == null) {
                            r = new StringBuilder(256);
                        } else {
                            r.append(' ');
                        }
                        r.append("DUP:");
                        r.append(pg.getName());
                    }
                }
            }
            if (r != null && DEBUG_PACKAGE_SCANNING) {
                Log.d(TAG, "  Permission Groups: " + r);
            }
        }
    }

    private void removeAllPermissionsInternal(@NonNull AndroidPackage pkg) {
        synchronized (mLock) {
            int n = ArrayUtils.size(pkg.getPermissions());
            StringBuilder r = null;
            for (int i = 0; i < n; i++) {
                ParsedPermission p = pkg.getPermissions().get(i);
                Permission bp = mRegistry.getPermission(p.getName());
                if (bp == null) {
                    bp = mRegistry.getPermissionTree(p.getName());
                }
                if (bp != null && bp.isPermission(p)) {
                    bp.setPermissionInfo(null);
                    if (DEBUG_REMOVE) {
                        if (r == null) {
                            r = new StringBuilder(256);
                        } else {
                            r.append(' ');
                        }
                        r.append(p.getName());
                    }
                }
                if (ParsedPermissionUtils.isAppOp(p)) {
                    // TODO(zhanghai): Should we just remove the entry for this permission directly?
                    mRegistry.removeAppOpPermissionPackage(p.getName(), pkg.getPackageName());
                }
            }
            if (r != null) {
                if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
            }

            r = null;
            for (final String permissionName : pkg.getRequestedPermissions()) {
                final Permission permission = mRegistry.getPermission(permissionName);
                if (permission != null && permission.isAppOp()) {
                    mRegistry.removeAppOpPermissionPackage(permissionName,
                            pkg.getPackageName());
                }
            }
            if (r != null) {
                if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
            }
        }
    }

    @Override
    public void onUserRemoved(@UserIdInt int userId) {
        Preconditions.checkArgumentNonNegative(userId, "userId");
        synchronized (mLock) {
            mState.removeUserState(userId);
        }
    }

    @NonNull
    private Set<String> getGrantedPermissionsInternal(@NonNull String packageName,
            @UserIdInt int userId) {
        final PackageStateInternal ps = mPackageManagerInt.getPackageStateInternal(packageName);
        if (ps == null) {
            return Collections.emptySet();
        }

        synchronized (mLock) {
            final UidPermissionState uidState = getUidStateLocked(ps, userId);
            if (uidState == null) {
                Slog.e(TAG, "Missing permissions state for " + packageName + " and user " + userId);
                return Collections.emptySet();
            }
            if (!ps.getUserStateOrDefault(userId).isInstantApp()) {
                return uidState.getGrantedPermissions();
            } else {
                // Install permission state is shared among all users, but instant app state is
                // per-user, so we can only filter it here unless we make install permission state
                // per-user as well.
                final Set<String> instantPermissions =
                        new ArraySet<>(uidState.getGrantedPermissions());
                instantPermissions.removeIf(permissionName -> {
                    Permission permission = mRegistry.getPermission(permissionName);
                    if (permission == null) {
                        return true;
                    }
                    if (!permission.isInstant()) {
                        EventLog.writeEvent(0x534e4554, "140256621", UserHandle.getUid(userId,
                                ps.getAppId()), permissionName);
                        return true;
                    }
                    return false;
                });
                return instantPermissions;
            }
        }
    }

    @NonNull
    private int[] getPermissionGidsInternal(@NonNull String permissionName, @UserIdInt int userId) {
        synchronized (mLock) {
            Permission permission = mRegistry.getPermission(permissionName);
            if (permission == null) {
                return EmptyArray.INT;
            }
            return permission.computeGids(userId);
        }
    }

    /**
     * Restore the permission state for a package.
     *
     * <ul>
     *     <li>During boot the state gets restored from the disk</li>
     *     <li>During app update the state gets restored from the last version of the app</li>
     * </ul>
     *
     * @param pkg the package the permissions belong to
     * @param replace if the package is getting replaced (this might change the requested
     *                permissions of this package)
     * @param changingPackageName the name of the package that is changing
     * @param callback Result call back
     * @param filterUserId If not {@link UserHandle.USER_ALL}, only restore the permission state for
     *                     this particular user
     */
    private void restorePermissionState(@NonNull AndroidPackage pkg, boolean replace,
            @Nullable String changingPackageName, @Nullable PermissionCallback callback,
            @UserIdInt int filterUserId) {
        // IMPORTANT: There are two types of permissions: install and runtime.
        // Install time permissions are granted when the app is installed to
        // all device users and users added in the future. Runtime permissions
        // are granted at runtime explicitly to specific users. Normal and signature
        // protected permissions are install time permissions. Dangerous permissions
        // are install permissions if the app's target SDK is Lollipop MR1 or older,
        // otherwise they are runtime permissions. This function does not manage
        // runtime permissions except for the case an app targeting Lollipop MR1
        // being upgraded to target a newer SDK, in which case dangerous permissions
        // are transformed from install time to runtime ones.

        final PackageStateInternal ps =
                mPackageManagerInt.getPackageStateInternal(pkg.getPackageName());
        if (ps == null) {
            return;
        }

        final int[] userIds = filterUserId == UserHandle.USER_ALL ? getAllUserIds()
                : new int[] { filterUserId };

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

        ArraySet<String> isPrivilegedPermissionAllowlisted = null;
        ArraySet<String> shouldGrantSignaturePermission = null;
        ArraySet<String> shouldGrantInternalPermission = null;
        ArraySet<String> shouldGrantPrivilegedPermissionIfWasGranted = new ArraySet<>();
        final Set<String> requestedPermissions = pkg.getRequestedPermissions();
        for (final String permissionName : pkg.getRequestedPermissions()) {
            final Permission permission;
            synchronized (mLock) {
                permission = mRegistry.getPermission(permissionName);
            }
            if (permission == null) {
                continue;
            }
            if (permission.isPrivileged()
                    && checkPrivilegedPermissionAllowlist(pkg, ps, permission)) {
                if (isPrivilegedPermissionAllowlisted == null) {
                    isPrivilegedPermissionAllowlisted = new ArraySet<>();
                }
                isPrivilegedPermissionAllowlisted.add(permissionName);
            }
            if (permission.isSignature() && (shouldGrantPermissionBySignature(pkg, permission)
                    || shouldGrantPermissionByProtectionFlags(pkg, ps, permission,
                            shouldGrantPrivilegedPermissionIfWasGranted))) {
                if (shouldGrantSignaturePermission == null) {
                    shouldGrantSignaturePermission = new ArraySet<>();
                }
                shouldGrantSignaturePermission.add(permissionName);
            }
            if (permission.isInternal()
                    && shouldGrantPermissionByProtectionFlags(pkg, ps, permission,
                            shouldGrantPrivilegedPermissionIfWasGranted)) {
                if (shouldGrantInternalPermission == null) {
                    shouldGrantInternalPermission = new ArraySet<>();
                }
                shouldGrantInternalPermission.add(permissionName);
            }
        }

        final SparseBooleanArray isPermissionPolicyInitialized = new SparseBooleanArray();
        if (mPermissionPolicyInternal != null) {
            for (final int userId : userIds) {
                if (mPermissionPolicyInternal.isInitialized(userId)) {
                    isPermissionPolicyInitialized.put(userId, true);
                }
            }
        }

        Collection<String> uidRequestedPermissions;
        Collection<String> uidImplicitPermissions;
        int uidTargetSdkVersion;
        if (!ps.hasSharedUser()) {
            uidRequestedPermissions = pkg.getRequestedPermissions();
            uidImplicitPermissions = pkg.getImplicitPermissions();
            uidTargetSdkVersion = pkg.getTargetSdkVersion();
        } else {
            uidRequestedPermissions = new ArraySet<>();
            uidImplicitPermissions = new ArraySet<>();
            uidTargetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
            final ArraySet<PackageStateInternal> packages =
                    mPackageManagerInt.getSharedUserPackages(ps.getSharedUserAppId());
            int packagesSize = packages.size();
            for (int i = 0; i < packagesSize; i++) {
                AndroidPackage sharedUserPackage =
                        packages.valueAt(i).getAndroidPackage();
                if (sharedUserPackage == null) {
                    continue;
                }
                uidRequestedPermissions.addAll(
                        sharedUserPackage.getRequestedPermissions());
                uidImplicitPermissions.addAll(
                        sharedUserPackage.getImplicitPermissions());
                uidTargetSdkVersion = Math.min(uidTargetSdkVersion,
                        sharedUserPackage.getTargetSdkVersion());
            }
        }

        synchronized (mLock) {
            for (final int userId : userIds) {
                final UserPermissionState userState = mState.getOrCreateUserState(userId);
                final UidPermissionState uidState = userState.getOrCreateUidState(ps.getAppId());

                if (uidState.isMissing()) {
                    for (String permissionName : uidRequestedPermissions) {
                        Permission permission = mRegistry.getPermission(permissionName);
                        if (permission == null) {
                            continue;
                        }
                        if (Objects.equals(permission.getPackageName(), PLATFORM_PACKAGE_NAME)
                                && permission.isRuntime() && !permission.isRemoved()) {
                            if (permission.isHardOrSoftRestricted()
                                    || permission.isImmutablyRestricted()) {
                                uidState.updatePermissionFlags(permission,
                                        FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
                                        FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
                            }
                            if (uidTargetSdkVersion < Build.VERSION_CODES.M) {
                                uidState.updatePermissionFlags(permission,
                                        PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
                                                | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT,
                                        PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
                                                | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT);
                                uidState.grantPermission(permission);
                            }
                        }
                    }

                    uidState.setMissing(false);
                    updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
                }

                UidPermissionState origState = uidState;

                boolean installPermissionsChangedForUser = false;

                if (replace) {
                    userState.setInstallPermissionsFixed(ps.getPackageName(), false);
                    if (!ps.hasSharedUser()) {
                        origState = new UidPermissionState(uidState);
                        uidState.reset();
                    } else {
                        // We need to know only about runtime permission changes since the
                        // calling code always writes the install permissions state but
                        // the runtime ones are written only if changed. The only cases of
                        // changed runtime permissions here are promotion of an install to
                        // runtime and revocation of a runtime from a shared user.
                        if (revokeUnusedSharedUserPermissionsLocked(uidRequestedPermissions,
                                uidState)) {
                            updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
                            runtimePermissionsRevoked = true;
                        }
                    }
                }

                ArraySet<String> newImplicitPermissions = new ArraySet<>();
                final String friendlyName = pkg.getPackageName() + "(" + pkg.getUid() + ")";

                for (final String permName : requestedPermissions) {
                    final Permission bp = mRegistry.getPermission(permName);
                    final boolean appSupportsRuntimePermissions =
                            pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M;

                    if (DEBUG_INSTALL && bp != null) {
                        Log.i(TAG, "Package " + friendlyName
                                + " checking " + permName + ": " + bp);
                    }

                    // TODO(zhanghai): I don't think we need to check source package setting if
                    //  permission is present, because otherwise the permission should have been
                    //  removed.
                    if (bp == null /*|| getSourcePackageSetting(bp) == null*/) {
                        if (changingPackageName == null || changingPackageName.equals(
                                pkg.getPackageName())) {
                            if (DEBUG_PERMISSIONS) {
                                Slog.i(TAG, "Unknown permission " + permName
                                        + " in package " + friendlyName);
                            }
                        }
                        continue;
                    }

                    // Cache newImplicitPermissions before modifing permissionsState as for the
                    // shared uids the original and new state are the same object
                    if (!origState.hasPermissionState(permName)
                            && (pkg.getImplicitPermissions().contains(permName))) {
                            // If permName is an implicit permission, try to auto-grant
                            newImplicitPermissions.add(permName);
                            if (DEBUG_PERMISSIONS) {
                                Slog.i(TAG, permName + " is newly added for " + friendlyName);
                            }
                    }

                    // TODO(b/140256621): The package instant app method has been removed
                    //  as part of work in b/135203078, so this has been commented out in the
                    //  meantime
                    // Limit ephemeral apps to ephemeral allowed permissions.
        //            if (/*pkg.isInstantApp()*/ false && !bp.isInstant()) {
        //                if (DEBUG_PERMISSIONS) {
        //                    Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
        //                            + " for package " + pkg.getPackageName());
        //                }
        //                continue;
        //            }

                    if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
                        if (DEBUG_PERMISSIONS) {
                            Log.i(TAG, "Denying runtime-only permission " + bp.getName()
                                    + " for package " + friendlyName);
                        }
                        continue;
                    }

                    final String perm = bp.getName();

                    // Keep track of app op permissions.
                    if (bp.isAppOp()) {
                        mRegistry.addAppOpPermissionPackage(perm, pkg.getPackageName());
                    }

                    boolean shouldGrantNormalPermission = true;
                    if (bp.isNormal() && !origState.isPermissionGranted(perm)) {
                        // If this is an existing, non-system package, then
                        // we can't add any new permissions to it. Runtime
                        // permissions can be added any time - they are dynamic.
                        if (!ps.isSystem() && userState.areInstallPermissionsFixed(
                                ps.getPackageName())) {
                            // Except...  if this is a permission that was added
                            // to the platform (note: need to only do this when
                            // updating the platform).
                            if (!isCompatPlatformPermissionForPackage(perm, pkg)) {
                                shouldGrantNormalPermission = false;
                            }
                        }
                    }

                    if (DEBUG_PERMISSIONS) {
                        Slog.i(TAG, "Considering granting permission " + perm + " to package "
                                + pkg.getPackageName());
                    }

                    if (bp.isNormal() || bp.isSignature() || bp.isInternal()) {
                        if ((bp.isNormal() && shouldGrantNormalPermission)
                                || (bp.isSignature()
                                        && (!bp.isPrivileged() || CollectionUtils.contains(
                                                isPrivilegedPermissionAllowlisted, permName))
                                        && (CollectionUtils.contains(shouldGrantSignaturePermission,
                                                permName)
                                                || (((bp.isPrivileged() && CollectionUtils.contains(
                                                        shouldGrantPrivilegedPermissionIfWasGranted,
                                                        permName)) || bp.isDevelopment()
                                                                || bp.isRole())
                                                        && origState.isPermissionGranted(
                                                                permName))))
                                || (bp.isInternal()
                                        && (!bp.isPrivileged() || CollectionUtils.contains(
                                                isPrivilegedPermissionAllowlisted, permName))
                                        && (CollectionUtils.contains(shouldGrantInternalPermission,
                                                permName)
                                                || (((bp.isPrivileged() && CollectionUtils.contains(
                                                        shouldGrantPrivilegedPermissionIfWasGranted,
                                                        permName)) || bp.isDevelopment()
                                                                || bp.isRole())
                                                        && origState.isPermissionGranted(
                                                                permName))))) {
                            // Grant an install permission.
                            if (uidState.grantPermission(bp)) {
                                installPermissionsChangedForUser = true;
                            }
                        } else {
                            if (DEBUG_PERMISSIONS) {
                                boolean wasGranted = uidState.isPermissionGranted(bp.getName());
                                if (wasGranted || bp.isAppOp()) {
                                    Slog.i(TAG, (wasGranted ? "Un-granting" : "Not granting")
                                            + " permission " + perm
                                            + " from package " + friendlyName
                                            + " (protectionLevel=" + bp.getProtectionLevel()
                                            + " flags=0x"
                                            + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg,
                                            ps))
                                            + ")");
                                }
                            }
                            if (uidState.revokePermission(bp)) {
                                installPermissionsChangedForUser = true;
                            }
                        }
                        PermissionState origPermState = origState.getPermissionState(perm);
                        int flags = origPermState != null ? origPermState.getFlags() : 0;
                        uidState.updatePermissionFlags(bp, MASK_PERMISSION_FLAGS_ALL, flags);
                    } else if (bp.isRuntime()) {
                        boolean hardRestricted = bp.isHardRestricted();
                        boolean softRestricted = bp.isSoftRestricted();

                        // If permission policy is not ready we don't deal with restricted
                        // permissions as the policy may allowlist some permissions. Once
                        // the policy is initialized we would re-evaluate permissions.
                        final boolean permissionPolicyInitialized =
                                isPermissionPolicyInitialized.get(userId);

                        PermissionState origPermState = origState.getPermissionState(perm);
                        int flags = origPermState != null ? origPermState.getFlags() : 0;

                        boolean wasChanged = false;

                        boolean restrictionExempt =
                                (origState.getPermissionFlags(bp.getName())
                                        & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
                        boolean restrictionApplied = (origState.getPermissionFlags(
                                bp.getName()) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;

                        if (appSupportsRuntimePermissions) {
                            // If hard restricted we don't allow holding it
                            if (permissionPolicyInitialized && hardRestricted) {
                                if (!restrictionExempt) {
                                    if (origPermState != null && origPermState.isGranted()
                                            && uidState.revokePermission(bp)) {
                                        wasChanged = true;
                                    }
                                    if (!restrictionApplied) {
                                        flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
                                        wasChanged = true;
                                    }
                                }
                            // If soft restricted we allow holding in a restricted form
                            } else if (permissionPolicyInitialized && softRestricted) {
                                // Regardless if granted set the restriction flag as it
                                // may affect app treatment based on this permission.
                                if (!restrictionExempt && !restrictionApplied) {
                                    flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
                                    wasChanged = true;
                                }
                            }

                            // Remove review flag as it is not necessary anymore
                            if (!NOTIFICATION_PERMISSIONS.contains(perm)) {
                                if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
                                    flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
                                    wasChanged = true;
                                }
                            }

                            if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0
                                    && !isPermissionSplitFromNonRuntime(permName,
                                    pkg.getTargetSdkVersion())) {
                                flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;
                                wasChanged = true;
                            // Hard restricted permissions cannot be held.
                            } else if (!permissionPolicyInitialized
                                    || (!hardRestricted || restrictionExempt)) {
                                if ((origPermState != null && origPermState.isGranted())) {
                                    if (!uidState.grantPermission(bp)) {
                                        wasChanged = true;
                                    }
                                }
                            }
                            if (mIsLeanback && NOTIFICATION_PERMISSIONS.contains(permName)) {
                                uidState.grantPermission(bp);
                                if (origPermState == null || !origPermState.isGranted()) {
                                    if (uidState.grantPermission(bp)) {
                                        wasChanged = true;
                                    }
                                }
                            }
                        } else {
                            if (origPermState == null) {
                                // New permission
                                if (PLATFORM_PACKAGE_NAME.equals(
                                        bp.getPackageName())) {
                                    if (!bp.isRemoved()) {
                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED
                                                | FLAG_PERMISSION_REVOKED_COMPAT;
                                        wasChanged = true;
                                    }
                                }
                            }

                            if (!uidState.isPermissionGranted(bp.getName())
                                    && uidState.grantPermission(bp)) {
                                wasChanged = true;
                            }

                            // If legacy app always grant the permission but if restricted
                            // and not exempt take a note a restriction should be applied.
                            if (permissionPolicyInitialized
                                    && (hardRestricted || softRestricted)
                                            && !restrictionExempt && !restrictionApplied) {
                                flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
                                wasChanged = true;
                            }
                        }

                        // If unrestricted or restriction exempt, don't apply restriction.
                        if (permissionPolicyInitialized) {
                            if (!(hardRestricted || softRestricted) || restrictionExempt) {
                                if (restrictionApplied) {
                                    flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
                                    // Dropping restriction on a legacy app implies a review
                                    if (!appSupportsRuntimePermissions) {
                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
                                    }
                                    wasChanged = true;
                                }
                            }
                        }

                        if (wasChanged) {
                            updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
                        }

                        uidState.updatePermissionFlags(bp, MASK_PERMISSION_FLAGS_ALL,
                                flags);
                    } else {
                        Slog.wtf(LOG_TAG, "Unknown permission protection " + bp.getProtection()
                                + " for permission " + bp.getName());
                    }
                }

                if ((installPermissionsChangedForUser || replace)
                        && !userState.areInstallPermissionsFixed(ps.getPackageName())
                        && !ps.isSystem() || ps.isUpdatedSystemApp()) {
                    // This is the first that we have heard about this package, so the
                    // permissions we have now selected are fixed until explicitly
                    // changed.
                    userState.setInstallPermissionsFixed(ps.getPackageName(), true);
                }

                if (installPermissionsChangedForUser) {
                    installPermissionsChanged = true;
                    if (changingPackageName != null && replace) {
                        updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
                    }
                }
                updatedUserIds = revokePermissionsNoLongerImplicitLocked(uidState,
                        pkg.getPackageName(), uidImplicitPermissions, uidTargetSdkVersion, userId,
                        updatedUserIds);
                updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origState,
                        uidState, pkg, newImplicitPermissions, userId, updatedUserIds);
            }
        }

        updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, userIds,
                updatedUserIds);

        // TODO: Kill UIDs whose GIDs or runtime permissions changed. This might be more important
        //  for shared users.
        // Persist the runtime permissions state for users with changes. If permissions
        // were revoked because no app in the shared user declares them we have to
        // write synchronously to avoid losing runtime permissions state.
        // Also write synchronously if we changed any install permission for an updated app, because
        // the install permission state is likely already fixed before update, and if we lose the
        // changes here the app won't be reconsidered for newly-added install permissions.
        if (callback != null) {
            callback.onPermissionUpdated(updatedUserIds,
                    (changingPackageName != null && replace && installPermissionsChanged)
                            || runtimePermissionsRevoked, pkg.getUid());
        }
    }

    /**
     * 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() {
        return UserManagerService.getInstance().getUserIdsIncludingPreCreated();
    }

    /**
     * Revoke permissions that are not implicit anymore and that have
     * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
     *
     * @param ps The state of the permissions of the package
     * @param packageName The name of the package
     * @param uidImplicitPermissions The implicit permissions of all packages in the UID
     * @param uidTargetSdkVersion The lowest target SDK version of all packages in the UID
     * @param userIds All user IDs in the system, must be passed in because this method is locked
     * @param updatedUserIds a list of user ids that needs to be amended if the permission state
     *                       for a user is changed.
     *
     * @return The updated value of the {@code updatedUserIds} parameter
     */
    @NonNull
    @GuardedBy("mLock")
    private int[] revokePermissionsNoLongerImplicitLocked(@NonNull UidPermissionState ps,
            @NonNull String packageName, @NonNull Collection<String> uidImplicitPermissions,
            int uidTargetSdkVersion, int userId, @NonNull int[] updatedUserIds) {
        boolean supportsRuntimePermissions = uidTargetSdkVersion >= Build.VERSION_CODES.M;

        for (String permission : ps.getGrantedPermissions()) {
            if (!uidImplicitPermissions.contains(permission)) {
                Permission bp = mRegistry.getPermission(permission);
                if (bp != null && bp.isRuntime()) {
                    int flags = ps.getPermissionFlags(permission);
                    if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
                        int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;

                        // We're willing to preserve an implicit "Nearby devices"
                        // permission grant if this app was already able to interact
                        // with nearby devices via background location access
                        boolean preserveGrant = false;
                        if (ArrayUtils.contains(NEARBY_DEVICES_PERMISSIONS, permission)
                                && ps.isPermissionGranted(
                                        android.Manifest.permission.ACCESS_BACKGROUND_LOCATION)
                                && (ps.getPermissionFlags(
                                        android.Manifest.permission.ACCESS_BACKGROUND_LOCATION)
                                        & (FLAG_PERMISSION_REVOKE_WHEN_REQUESTED
                                                | FLAG_PERMISSION_REVOKED_COMPAT)) == 0) {
                            preserveGrant = true;
                        }

                        if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
                                && supportsRuntimePermissions
                                && !preserveGrant) {
                            if (ps.revokePermission(bp)) {
                                if (DEBUG_PERMISSIONS) {
                                    Slog.i(TAG, "Revoking runtime permission "
                                            + permission + " for " + packageName
                                            + " as it is now requested");
                                }
                            }

                            flagsToRemove |= USER_PERMISSION_FLAGS;
                        }

                        ps.updatePermissionFlags(bp, flagsToRemove, 0);
                        updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
                    }
                }
            }
        }

        return updatedUserIds;
    }

    /**
     * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
     *
     * <p>A single new permission can be split off from several source permissions. In this case
     * the most leniant state is inherited.
     *
     * <p>Warning: This does not handle foreground / background permissions
     *
     * @param sourcePerms The permissions to inherit from
     * @param newPerm The permission to inherit to
     * @param ps The permission state of the package
     * @param pkg The package requesting the permissions
     */
    @GuardedBy("mLock")
    private void inheritPermissionStateToNewImplicitPermissionLocked(
            @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
            @NonNull UidPermissionState ps, @NonNull AndroidPackage pkg) {
        String pkgName = pkg.getPackageName();
        boolean isGranted = false;
        int flags = 0;

        int numSourcePerm = sourcePerms.size();
        for (int i = 0; i < numSourcePerm; i++) {
            String sourcePerm = sourcePerms.valueAt(i);
            if (ps.isPermissionGranted(sourcePerm)) {
                if (!isGranted) {
                    flags = 0;
                }

                isGranted = true;
                flags |= ps.getPermissionFlags(sourcePerm);
            } else {
                if (!isGranted) {
                    flags |= ps.getPermissionFlags(sourcePerm);
                }
            }
        }

        if (isGranted) {
            if (DEBUG_PERMISSIONS) {
                Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
                        + " for " + pkgName);
            }

            ps.grantPermission(mRegistry.getPermission(newPerm));
        }

        // Add permission flags
        ps.updatePermissionFlags(mRegistry.getPermission(newPerm), flags, flags);
    }

    /**
     * When the app has requested legacy storage we might need to update
     * {@link android.app.AppOpsManager#OP_LEGACY_STORAGE}. Hence force an update in
     * {@link com.android.server.policy.PermissionPolicyService#synchronizePackagePermissionsAndAppOpsForUser(Context, String, int)}
     *
     * @param pkg The package for which the permissions are updated
     * @param replace If the app is being replaced
     * @param userIds All user IDs in the system, must be passed in because this method is locked
     * @param updatedUserIds The ids of the users that already changed.
     *
     * @return The ids of the users that are changed
     */
    private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(@NonNull AndroidPackage pkg,
            boolean replace, @NonNull int[] userIds, @NonNull int[] updatedUserIds) {
        if (replace && pkg.isRequestLegacyExternalStorage() && (
                pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE)
                        || pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) {
            return userIds.clone();
        }

        return updatedUserIds;
    }

    /**
     * Set the state of a implicit permission that is seen for the first time.
     *
     * @param origPs The permission state of the package before the split
     * @param ps The new permission state
     * @param pkg The package the permission belongs to
     * @param userId The user ID
     * @param updatedUserIds List of users for which the permission state has already been changed
     *
     * @return  List of users for which the permission state has been changed
     */
    @NonNull
    @GuardedBy("mLock")
    private int[] setInitialGrantForNewImplicitPermissionsLocked(
            @NonNull UidPermissionState origPs, @NonNull UidPermissionState ps,
            @NonNull AndroidPackage pkg, @NonNull ArraySet<String> newImplicitPermissions,
            @UserIdInt int userId, @NonNull int[] updatedUserIds) {
        String pkgName = pkg.getPackageName();
        ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();

        final List<PermissionManager.SplitPermissionInfo> permissionList =
                getSplitPermissionInfos();
        int numSplitPerms = permissionList.size();
        for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
            PermissionManager.SplitPermissionInfo spi = permissionList.get(splitPermNum);

            List<String> newPerms = spi.getNewPermissions();
            int numNewPerms = newPerms.size();
            for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
                String newPerm = newPerms.get(newPermNum);

                ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
                if (splitPerms == null) {
                    splitPerms = new ArraySet<>();
                    newToSplitPerms.put(newPerm, splitPerms);
                }

                splitPerms.add(spi.getSplitPermission());
            }
        }

        int numNewImplicitPerms = newImplicitPermissions.size();
        for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
                newImplicitPermNum++) {
            String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
            ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);

            if (sourcePerms != null) {
                Permission bp = mRegistry.getPermission(newPerm);
                if (bp == null) {
                    throw new IllegalStateException("Unknown new permission in split permission: "
                            + newPerm);
                }
                if (bp.isRuntime()) {

                    if (!(newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)
                            || READ_MEDIA_AURAL_PERMISSIONS.contains(newPerm)
                            || READ_MEDIA_VISUAL_PERMISSIONS.contains(newPerm))) {
                        ps.updatePermissionFlags(bp,
                                FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
                                FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
                    }
                    updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);

                    if (!origPs.hasPermissionState(sourcePerms)) {
                        boolean inheritsFromInstallPerm = false;
                        for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
                                sourcePermNum++) {
                            final String sourcePerm = sourcePerms.valueAt(sourcePermNum);
                            Permission sourceBp = mRegistry.getPermission(sourcePerm);
                            if (sourceBp == null) {
                                throw new IllegalStateException("Unknown source permission in split"
                                        + " permission: " + sourcePerm);
                            }
                            if (!sourceBp.isRuntime()) {
                                inheritsFromInstallPerm = true;
                                break;
                            }
                        }

                        if (!inheritsFromInstallPerm) {
                            // Both permissions are new so nothing to inherit.
                            if (DEBUG_PERMISSIONS) {
                                Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
                                        + " for " + pkgName + " as split permission is also new");
                            }
                            continue;
                        }
                    }

                    // Inherit from new install or existing runtime permissions
                    inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms, newPerm, ps,
                            pkg);
                }
            }
        }

        return updatedUserIds;
    }

    @NonNull
    @Override
    public List<SplitPermissionInfoParcelable> getSplitPermissions() {
        return PermissionManager.splitPermissionInfoListToParcelableList(getSplitPermissionInfos());
    }

    @NonNull
    private List<PermissionManager.SplitPermissionInfo> getSplitPermissionInfos() {
        return SystemConfig.getInstance().getSplitPermissions();
    }

    private static boolean isCompatPlatformPermissionForPackage(String perm, AndroidPackage pkg) {
        boolean allowed = false;
        for (int i = 0, size = CompatibilityPermissionInfo.COMPAT_PERMS.length; i < size; i++) {
            final CompatibilityPermissionInfo info = CompatibilityPermissionInfo.COMPAT_PERMS[i];
            if (info.getName().equals(perm)
                    && pkg.getTargetSdkVersion() < info.getSdkVersion()) {
                allowed = true;
                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
                        + pkg.getPackageName());
                break;
            }
        }
        return allowed;
    }

    private boolean checkPrivilegedPermissionAllowlist(@NonNull AndroidPackage pkg,
            @NonNull PackageStateInternal packageSetting, @NonNull Permission permission) {
        if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE) {
            return true;
        }
        final String packageName = pkg.getPackageName();
        if (Objects.equals(packageName, PLATFORM_PACKAGE_NAME)) {
            return true;
        }
        if (!(packageSetting.isSystem() && packageSetting.isPrivileged())) {
            return true;
        }
        if (!mPrivilegedPermissionAllowlistSourcePackageNames
                .contains(permission.getPackageName())) {
            return true;
        }
        final String permissionName = permission.getName();
        final String containingApexPackageName =
                mApexManager.getActiveApexPackageNameContainingPackage(packageName);
        final Boolean allowlistState = getPrivilegedPermissionAllowlistState(packageSetting,
                permissionName, containingApexPackageName);
        if (allowlistState != null) {
            return allowlistState;
        }
        // Updated system apps do not need to be allowlisted
        if (packageSetting.isUpdatedSystemApp()) {
            // Let shouldGrantPermissionByProtectionFlags() decide whether the privileged permission
            // can be granted, because an updated system app may be in a shared UID, and in case a
            // new privileged permission is requested by the updated system app but not the factory
            // app, although this app and permission combination isn't in the allowlist and can't
            // get the permission this way, other apps in the shared UID may still get it. A proper
            // fix for this would be to perform the reconciliation by UID, but for now let's keep
            // the old workaround working, which is to keep granted privileged permissions still
            // granted.
            return true;
        }
        // Only enforce the allowlist on boot
        if (!mSystemReady) {
            final boolean isInUpdatedApex = packageSetting.isApkInUpdatedApex();
            // Apps that are in updated apexs' do not need to be allowlisted
            if (!isInUpdatedApex) {
                Slog.w(TAG, "Privileged permission " + permissionName + " for package "
                        + packageName + " (" + pkg.getPath()
                        + ") not in privapp-permissions allowlist");
                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
                    synchronized (mLock) {
                        if (mPrivappPermissionsViolations == null) {
                            mPrivappPermissionsViolations = new ArraySet<>();
                        }
                        mPrivappPermissionsViolations.add(packageName + " (" + pkg.getPath() + "): "
                                + permissionName);
                    }
                }
            }
        }
        return !RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE;
    }

    @Nullable
    private Boolean getPrivilegedPermissionAllowlistState(@NonNull PackageState packageState,
            @NonNull String permissionName, String containingApexPackageName) {
        final PermissionAllowlist permissionAllowlist =
                SystemConfig.getInstance().getPermissionAllowlist();
        final String packageName = packageState.getPackageName();
        if (packageState.isVendor() || packageState.isOdm()) {
            return permissionAllowlist.getVendorPrivilegedAppAllowlistState(packageName,
                    permissionName);
        } else if (packageState.isProduct()) {
            return permissionAllowlist.getProductPrivilegedAppAllowlistState(packageName,
                    permissionName);
        } else if (packageState.isSystemExt()) {
            return permissionAllowlist.getSystemExtPrivilegedAppAllowlistState(packageName,
                    permissionName);
        } else if (containingApexPackageName != null) {
            final Boolean nonApexAllowlistState =
                    permissionAllowlist.getPrivilegedAppAllowlistState(packageName, permissionName);
            if (nonApexAllowlistState != null) {
                // TODO(andreionea): Remove check as soon as all apk-in-apex
                // permission allowlists are migrated.
                Slog.w(TAG, "Package " + packageName + " is an APK in APEX,"
                        + " but has permission allowlist on the system image. Please bundle the"
                        + " allowlist in the " + containingApexPackageName + " APEX instead.");
            }
            final String moduleName = mApexManager.getApexModuleNameForPackageName(
                    containingApexPackageName);
            final Boolean apexAllowlistState =
                    permissionAllowlist.getApexPrivilegedAppAllowlistState(moduleName, packageName,
                            permissionName);
            if (apexAllowlistState != null) {
                return apexAllowlistState;
            }
            return nonApexAllowlistState;
        } else {
            return permissionAllowlist.getPrivilegedAppAllowlistState(packageName, permissionName);
        }
    }

    private boolean shouldGrantPermissionBySignature(@NonNull AndroidPackage pkg,
            @NonNull Permission bp) {
        // expect single system package
        String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames(
                KnownPackages.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM));
        final AndroidPackage systemPackage =
                mPackageManagerInt.getPackage(systemPackageName);
        // check if the package is allow to use this signature permission.  A package is allowed to
        // use a signature permission if:
        //     - it has the same set of signing certificates as the source package
        //     - or its signing certificate was rotated from the source package's certificate
        //     - or its signing certificate is a previous signing certificate of the defining
        //       package, and the defining package still trusts the old certificate for permissions
        //     - or it shares a common signing certificate in its lineage with the defining package,
        //       and the defining package still trusts the old certificate for permissions
        //     - or it shares the above relationships with the system package
        final SigningDetails sourceSigningDetails =
                getSourcePackageSigningDetails(bp);
        return sourceSigningDetails.hasCommonSignerWithCapability(
                        pkg.getSigningDetails(),
                        SigningDetails.CertCapabilities.PERMISSION)
                || pkg.getSigningDetails().hasAncestorOrSelf(systemPackage.getSigningDetails())
                || systemPackage.getSigningDetails().checkCapability(
                        pkg.getSigningDetails(),
                        SigningDetails.CertCapabilities.PERMISSION);
    }

    private boolean shouldGrantPermissionByProtectionFlags(@NonNull AndroidPackage pkg,
            @NonNull PackageStateInternal pkgSetting, @NonNull Permission bp,
            @NonNull ArraySet<String> shouldGrantPrivilegedPermissionIfWasGranted) {
        boolean allowed = false;
        final boolean isPrivilegedPermission = bp.isPrivileged();
        final boolean isOemPermission = bp.isOem();
        if (!allowed && (isPrivilegedPermission || isOemPermission) && pkgSetting.isSystem()) {
            final String permissionName = bp.getName();
            // For updated system applications, a privileged/oem permission
            // is granted only if it had been defined by the original application.
            if (pkgSetting.isUpdatedSystemApp()) {
                final PackageStateInternal disabledPs = mPackageManagerInt
                        .getDisabledSystemPackage(pkg.getPackageName());
                final AndroidPackage disabledPkg = disabledPs == null ? null : disabledPs.getPkg();
                if (disabledPkg != null
                        && ((isPrivilegedPermission && disabledPs.isPrivileged())
                        || (isOemPermission && canGrantOemPermission(disabledPs,
                                permissionName)))) {
                    if (disabledPkg.getRequestedPermissions().contains(permissionName)) {
                        allowed = true;
                    } else {
                        // If the original was granted this permission, we take
                        // that grant decision as read and propagate it to the
                        // update.
                        shouldGrantPrivilegedPermissionIfWasGranted.add(permissionName);
                    }
                }
            } else {
                allowed = (isPrivilegedPermission && pkgSetting.isPrivileged())
                        || (isOemPermission && canGrantOemPermission(pkgSetting, permissionName));
            }
            // In any case, don't grant a privileged permission to privileged vendor apps, if
            // the permission's protectionLevel does not have the extra 'vendorPrivileged'
            // flag.
            if (allowed && isPrivilegedPermission && !bp.isVendorPrivileged()
                    && (pkgSetting.isVendor() || pkgSetting.isOdm())) {
                Slog.w(TAG, "Permission " + permissionName
                        + " cannot be granted to privileged vendor apk " + pkg.getPackageName()
                        + " because it isn't a 'vendorPrivileged' permission.");
                allowed = false;
            }
        }
        if (!allowed && bp.isPre23() && pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
            // If this was a previously normal/dangerous permission that got moved
            // to a system permission as part of the runtime permission redesign, then
            // we still want to blindly grant it to old apps.
            allowed = true;
        }
        // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
        //                  need a separate flag anymore. Hence we need to check which
        //                  permissions are needed by the permission controller
        if (!allowed && bp.isInstaller()
                && (ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                        KnownPackages.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM),
                pkg.getPackageName()) || ArrayUtils.contains(
                        mPackageManagerInt.getKnownPackageNames(
                                KnownPackages.PACKAGE_PERMISSION_CONTROLLER,
                UserHandle.USER_SYSTEM), pkg.getPackageName()))) {
            // If this permission is to be granted to the system installer and
            // this app is an installer, then it gets the permission.
            allowed = true;
        }
        if (!allowed && bp.isVerifier()
                && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                        KnownPackages.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM),
                pkg.getPackageName())) {
            // If this permission is to be granted to the system verifier and
            // this app is a verifier, then it gets the permission.
            allowed = true;
        }
        if (!allowed && bp.isPreInstalled() && pkgSetting.isSystem()) {
            // Any pre-installed system app is allowed to get this permission.
            allowed = true;
        }
        if (!allowed && bp.isKnownSigner()) {
            // If the permission is to be granted to a known signer then check if any of this
            // app's signing certificates are in the trusted certificate digest Set.
            allowed = pkg.getSigningDetails().hasAncestorOrSelfWithDigest(bp.getKnownCerts());
        }
        // Deferred to be checked under permission data lock inside restorePermissionState().
        //if (!allowed && bp.isDevelopment()) {
        //    // For development permissions, a development permission
        //    // is granted only if it was already granted.
        //    allowed = origPermissions.isPermissionGranted(permissionName);
        //}
        if (!allowed && bp.isSetup()
                && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                        KnownPackages.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM),
                pkg.getPackageName())) {
            // If this permission is to be granted to the system setup wizard and
            // this app is a setup wizard, then it gets the permission.
            allowed = true;
        }
        if (!allowed && bp.isSystemTextClassifier()
                && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                KnownPackages.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
                UserHandle.USER_SYSTEM), pkg.getPackageName())) {
            // Special permissions for the system default text classifier.
            allowed = true;
        }
        if (!allowed && bp.isConfigurator()
                && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                KnownPackages.PACKAGE_CONFIGURATOR,
                UserHandle.USER_SYSTEM), pkg.getPackageName())) {
            // Special permissions for the device configurator.
            allowed = true;
        }
        if (!allowed && bp.isIncidentReportApprover()
                && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                KnownPackages.PACKAGE_INCIDENT_REPORT_APPROVER,
                UserHandle.USER_SYSTEM), pkg.getPackageName())) {
            // If this permission is to be granted to the incident report approver and
            // this app is the incident report approver, then it gets the permission.
            allowed = true;
        }
        if (!allowed && bp.isAppPredictor()
                && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                        KnownPackages.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM),
                pkg.getPackageName())) {
            // Special permissions for the system app predictor.
            allowed = true;
        }
        if (!allowed && bp.isCompanion()
                && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                        KnownPackages.PACKAGE_COMPANION, UserHandle.USER_SYSTEM),
                pkg.getPackageName())) {
            // Special permissions for the system companion device manager.
            allowed = true;
        }
        if (!allowed && bp.isRetailDemo()
                && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                        KnownPackages.PACKAGE_RETAIL_DEMO, UserHandle.USER_SYSTEM),
                pkg.getPackageName()) && isProfileOwner(pkg.getUid())) {
            // Special permission granted only to the OEM specified retail demo app
            allowed = true;
        }
        if (!allowed && bp.isRecents()
                && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                        KnownPackages.PACKAGE_RECENTS, UserHandle.USER_SYSTEM),
                pkg.getPackageName())) {
            // Special permission for the recents app.
            allowed = true;
        }
        if (!allowed && bp.isModule() && mApexManager.getActiveApexPackageNameContainingPackage(
                pkg.getPackageName()) != null) {
            // Special permission granted for APKs inside APEX modules.
            allowed = true;
        }
        return allowed;
    }

    @NonNull
    private SigningDetails getSourcePackageSigningDetails(
            @NonNull Permission bp) {
        final PackageStateInternal ps = getSourcePackageSetting(bp);
        if (ps == null) {
            return SigningDetails.UNKNOWN;
        }
        return ps.getSigningDetails();
    }

    @Nullable
    private PackageStateInternal getSourcePackageSetting(@NonNull Permission bp) {
        final String sourcePackageName = bp.getPackageName();
        return mPackageManagerInt.getPackageStateInternal(sourcePackageName);
    }

    private static boolean canGrantOemPermission(@NonNull PackageState packageState,
            String permission) {
        if (!packageState.isOem()) {
            return false;
        }
        var packageName = packageState.getPackageName();
        // all oem permissions must explicitly be granted or denied
        final Boolean granted = SystemConfig.getInstance().getPermissionAllowlist()
                .getOemAppAllowlistState(packageState.getPackageName(), permission);
        if (granted == null) {
            throw new IllegalStateException("OEM permission " + permission
                    + " requested by package " + packageName
                    + " must be explicitly declared granted or not");
        }
        return Boolean.TRUE == granted;
    }

    private static boolean isProfileOwner(int uid) {
        DevicePolicyManagerInternal dpmInternal =
                LocalServices.getService(DevicePolicyManagerInternal.class);
        //TODO(b/169395065) Figure out if this flow makes sense in Device Owner mode.
        if (dpmInternal != null) {
            return dpmInternal.isActiveProfileOwner(uid) || dpmInternal.isActiveDeviceOwner(uid);
        }
        return false;
    }

    private boolean isPermissionsReviewRequiredInternal(@NonNull String packageName,
            @UserIdInt int userId) {
        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        if (pkg == null) {
            return false;
        }

        // Permission review applies only to apps not supporting the new permission model.
        if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M) {
            return false;
        }

        // Legacy apps have the permission and get user consent on launch.
        synchronized (mLock) {
            final UidPermissionState uidState = getUidStateLocked(pkg, userId);
            if (uidState == null) {
                Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user "
                        + userId);
                return false;
            }
            return uidState.isPermissionsReviewRequired();
        }
    }

    private void grantRequestedPermissionsInternal(@NonNull AndroidPackage pkg,
            @Nullable ArrayMap<String, Integer> permissionStates, int userId) {
        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;

        final int compatFlags = PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
                | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;

        final boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
                >= Build.VERSION_CODES.M;

        final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.getPackageName(), userId);

        final int myUid = Process.myUid();

        for (String permission : pkg.getRequestedPermissions()) {
            Integer permissionState = permissionStates.get(permission);

            if (permissionState == null || permissionState == PERMISSION_STATE_DEFAULT) {
                continue;
            }

            final boolean shouldGrantRuntimePermission;
            final boolean isAppOpPermission;
            synchronized (mLock) {
                final Permission bp = mRegistry.getPermission(permission);
                if (bp == null) {
                    continue;
                }
                shouldGrantRuntimePermission = (bp.isRuntime() || bp.isDevelopment())
                        && (!instantApp || bp.isInstant())
                        && (supportsRuntimePermissions || !bp.isRuntimeOnly())
                        && permissionState == PERMISSION_STATE_GRANTED;
                isAppOpPermission = bp.isAppOp();
            }

            final int flags = getPermissionFlagsInternal(pkg.getPackageName(), permission,
                    myUid, userId);
            if (shouldGrantRuntimePermission) {
                if (supportsRuntimePermissions) {
                    // Installer cannot change immutable permissions.
                    if ((flags & immutableFlags) == 0) {
                        grantRuntimePermissionInternal(pkg.getPackageName(), permission, false,
                                myUid, userId, mDefaultPermissionCallback);
                    }
                } else {
                    // In permission review mode we clear the review flag and the revoked compat
                    // flag when we are asked to install the app with all permissions granted.
                    if ((flags & compatFlags) != 0) {
                        updatePermissionFlagsInternal(pkg.getPackageName(), permission, compatFlags,
                                0, myUid, userId, false, mDefaultPermissionCallback);
                    }
                }
            } else if (isAppOpPermission
                    && PackageInstallerService.INSTALLER_CHANGEABLE_APP_OP_PERMISSIONS
                    .contains(permission)) {
                if ((flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0) {
                    continue;
                }
                int mode =
                        permissionState == PERMISSION_STATE_GRANTED ? MODE_ALLOWED : MODE_ERRORED;
                int uid = UserHandle.getUid(userId, pkg.getUid());
                String appOp = AppOpsManager.permissionToOp(permission);
                mHandler.post(() -> {
                    AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
                    appOpsManager.setUidMode(appOp, uid, mode);
                });
            }
        }
    }

    private void setAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg,
            @Nullable List<String> permissions,
            @PackageManager.PermissionWhitelistFlags int allowlistFlags,
            @UserIdInt int userId) {
        ArraySet<String> oldGrantedRestrictedPermissions = null;
        boolean updatePermissions = false;
        final int myUid = Process.myUid();

        for (final String permissionName : pkg.getRequestedPermissions()) {
            final boolean isGranted;
            synchronized (mLock) {
                final Permission bp = mRegistry.getPermission(permissionName);
                if (bp == null || !bp.isHardOrSoftRestricted()) {
                    continue;
                }

                final UidPermissionState uidState = getUidStateLocked(pkg, userId);
                if (uidState == null) {
                    Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName()
                            + " and user " + userId);
                    continue;
                }
                isGranted = uidState.isPermissionGranted(permissionName);
            }

            if (isGranted) {
                if (oldGrantedRestrictedPermissions == null) {
                    oldGrantedRestrictedPermissions = new ArraySet<>();
                }
                oldGrantedRestrictedPermissions.add(permissionName);
            }

            final int oldFlags = getPermissionFlagsInternal(pkg.getPackageName(), permissionName,
                    myUid, userId);

            int newFlags = oldFlags;
            int mask = 0;
            int allowlistFlagsCopy = allowlistFlags;
            while (allowlistFlagsCopy != 0) {
                final int flag = 1 << Integer.numberOfTrailingZeros(allowlistFlagsCopy);
                allowlistFlagsCopy &= ~flag;
                switch (flag) {
                    case FLAG_PERMISSION_WHITELIST_SYSTEM: {
                        mask |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                        if (permissions != null && permissions.contains(permissionName)) {
                            newFlags |= FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                        } else {
                            newFlags &= ~FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
                        }
                    }
                    break;
                    case FLAG_PERMISSION_WHITELIST_UPGRADE: {
                        mask |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                        if (permissions != null && permissions.contains(permissionName)) {
                            newFlags |= FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                        } else {
                            newFlags &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
                        }
                    }
                    break;
                    case FLAG_PERMISSION_WHITELIST_INSTALLER: {
                        mask |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                        if (permissions != null && permissions.contains(permissionName)) {
                            newFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                        } else {
                            newFlags &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
                        }
                    }
                    break;
                }
            }

            if (oldFlags == newFlags) {
                continue;
            }

            updatePermissions = true;

            final boolean wasAllowlisted = (oldFlags
                    & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
            final boolean isAllowlisted = (newFlags
                    & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;

            // If the permission is policy fixed as granted but it is no longer
            // on any of the allowlists we need to clear the policy fixed flag
            // as allowlisting trumps policy i.e. policy cannot grant a non
            // grantable permission.
            if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
                if (!isAllowlisted && isGranted) {
                    mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
                    newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
                }
            }

            // If we are allowlisting an app that does not support runtime permissions
            // we need to make sure it goes through the permission review UI at launch.
            if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
                    && !wasAllowlisted && isAllowlisted) {
                mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
                newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
            }

            updatePermissionFlagsInternal(pkg.getPackageName(), permissionName, mask, newFlags,
                    myUid, userId, false, null /*callback*/);
        }

        if (updatePermissions) {
            // Update permission of this app to take into account the new allowlist state.
            restorePermissionState(pkg, false, pkg.getPackageName(), mDefaultPermissionCallback,
                    userId);

            // If this resulted in losing a permission we need to kill the app.
            if (oldGrantedRestrictedPermissions == null) {
                return;
            }

            final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
            for (int j = 0; j < oldGrantedCount; j++) {
                final String permissionName = oldGrantedRestrictedPermissions.valueAt(j);
                // Sometimes we create a new permission state instance during update.
                final boolean isGranted;
                synchronized (mLock) {
                    final UidPermissionState uidState = getUidStateLocked(pkg, userId);
                    if (uidState == null) {
                        Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName()
                                + " and user " + userId);
                        continue;
                    }
                    isGranted = uidState.isPermissionGranted(permissionName);
                }
                if (!isGranted) {
                    mDefaultPermissionCallback.onPermissionRevoked(
                            UserHandle.getUid(userId, pkg.getUid()), userId, null);
                    break;
                }
            }
        }
    }

    private void revokeSharedUserPermissionsForLeavingPackageInternal(
            @Nullable AndroidPackage pkg, int appId, @NonNull List<AndroidPackage> sharedUserPkgs,
            @UserIdInt int userId) {
        if (pkg == null) {
            Slog.i(TAG, "Trying to update info for null package. Just ignoring");
            return;
        }

        // No shared user packages
        if (sharedUserPkgs.isEmpty()) {
            return;
        }

        PackageStateInternal disabledPs = mPackageManagerInt.getDisabledSystemPackage(
                pkg.getPackageName());
        boolean isShadowingSystemPkg = disabledPs != null && disabledPs.getAppId() == pkg.getUid();

        boolean shouldKillUid = false;
        // Update permissions
        for (String eachPerm : pkg.getRequestedPermissions()) {
            // Check if another package in the shared user needs the permission.
            boolean used = false;
            for (AndroidPackage sharedUserpkg : sharedUserPkgs) {
                if (sharedUserpkg != null
                        && !sharedUserpkg.getPackageName().equals(pkg.getPackageName())
                        && sharedUserpkg.getRequestedPermissions().contains(eachPerm)) {
                    used = true;
                    break;
                }
            }
            if (used) {
                continue;
            }

            // If the package is shadowing a disabled system package,
            // do not drop permissions that the shadowed package requests.
            if (isShadowingSystemPkg
                    && disabledPs.getPkg().getRequestedPermissions().contains(eachPerm)) {
                continue;
            }

            synchronized (mLock) {
                UidPermissionState uidState = getUidStateLocked(appId, userId);
                if (uidState == null) {
                    Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName()
                            + " and user " + userId);
                    continue;
                }

                Permission bp = mRegistry.getPermission(eachPerm);
                if (bp == null) {
                    continue;
                }

                // TODO(zhanghai): Why are we only killing the UID when GIDs changed, instead of any
                //  permission change?
                if (uidState.removePermissionState(bp.getName()) && bp.hasGids()) {
                    shouldKillUid = true;
                }
            }
        }

        // If gids changed, kill all affected packages.
        if (shouldKillUid) {
            mHandler.post(() -> {
                // This has to happen with no lock held.
                killUid(appId, UserHandle.USER_ALL, KILL_APP_REASON_GIDS_CHANGED);
            });
        }
    }

    @GuardedBy("mLock")
    private boolean revokeUnusedSharedUserPermissionsLocked(
            @NonNull Collection<String> uidRequestedPermissions,
            @NonNull UidPermissionState uidState) {
        boolean runtimePermissionChanged = false;

        // Prune permissions
        final List<PermissionState> permissionStates = uidState.getPermissionStates();
        final int permissionStatesSize = permissionStates.size();
        for (int i = permissionStatesSize - 1; i >= 0; i--) {
            PermissionState permissionState = permissionStates.get(i);
            if (!uidRequestedPermissions.contains(permissionState.getName())) {
                Permission bp = mRegistry.getPermission(permissionState.getName());
                if (bp != null) {
                    if (uidState.removePermissionState(bp.getName()) && bp.isRuntime()) {
                        runtimePermissionChanged = true;
                    }
                }
            }
        }

        return runtimePermissionChanged;
    }

    /**
     * Update permissions when a package changed.
     *
     * <p><ol>
     *     <li>Reconsider the ownership of permission</li>
     *     <li>Update the state (grant, flags) of the permissions</li>
     * </ol>
     *
     * @param packageName The package that is updated
     * @param pkg The package that is updated, or {@code null} if package is deleted
     */
    private void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) {
        // If the package is being deleted, update the permissions of all the apps
        final int flags =
                (pkg == null ? UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG
                        : UPDATE_PERMISSIONS_REPLACE_PKG);
        updatePermissions(
                packageName, pkg, getVolumeUuidForPackage(pkg), flags, mDefaultPermissionCallback);
    }

    /**
     * Update all permissions for all apps.
     *
     * <p><ol>
     *     <li>Reconsider the ownership of permission</li>
     *     <li>Update the state (grant, flags) of the permissions</li>
     * </ol>
     *
     * @param volumeUuid The volume UUID of the packages to be updated
     * @param fingerprintChanged whether the current build fingerprint is different from what it was
     *                           when this volume was last mounted
     */
    private void updateAllPermissions(@NonNull String volumeUuid, boolean fingerprintChanged) {
        PackageManager.corkPackageInfoCache();  // Prevent invalidation storm
        try {
            final int flags = UPDATE_PERMISSIONS_ALL |
                    (fingerprintChanged
                            ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
                            : 0);
            updatePermissions(null, null, volumeUuid, flags, mDefaultPermissionCallback);
        } finally {
            PackageManager.uncorkPackageInfoCache();
        }
    }

    /**
     * Update all packages on the volume, <u>beside</u> the changing package. If the changing
     * package is set too, all packages are updated.
     */
    private static final int UPDATE_PERMISSIONS_ALL = 1 << 0;
    /** The changing package is replaced. Requires the changing package to be set */
    private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1 << 1;
    /**
     * Schedule all packages <u>beside</u> the changing package for replacement. Requires
     * UPDATE_PERMISSIONS_ALL to be set
     */
    private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1 << 2;

    @IntDef(flag = true, prefix = { "UPDATE_PERMISSIONS_" }, value = {
            UPDATE_PERMISSIONS_ALL, UPDATE_PERMISSIONS_REPLACE_PKG,
            UPDATE_PERMISSIONS_REPLACE_ALL })
    @Retention(RetentionPolicy.SOURCE)
    private @interface UpdatePermissionFlags {}

    /**
     * Update permissions when packages changed.
     *
     * <p><ol>
     *     <li>Reconsider the ownership of permission</li>
     *     <li>Update the state (grant, flags) of the permissions</li>
     * </ol>
     *
     * <p>Meaning of combination of package parameters:
     * <table>
     *     <tr><th></th><th>changingPkgName != null</th><th>changingPkgName == null</th></tr>
     *     <tr><th>changingPkg != null</th><td>package is updated</td><td>invalid</td></tr>
     *     <tr><th>changingPkg == null</th><td>package is deleted</td><td>all packages are
     *                                                                    updated</td></tr>
     * </table>
     *
     * @param changingPkgName The package that is updated, or {@code null} if all packages should be
     *                    updated
     * @param changingPkg The package that is updated, or {@code null} if all packages should be
     *                    updated or package is deleted
     * @param replaceVolumeUuid The volume of the packages to be updated are on, {@code null} for
     *                          all volumes
     * @param flags Control permission for which apps should be updated
     * @param callback Callback to call after permission changes
     */
    private void updatePermissions(final @Nullable String changingPkgName,
            final @Nullable AndroidPackage changingPkg,
            final @Nullable String replaceVolumeUuid,
            @UpdatePermissionFlags int flags,
            final @Nullable PermissionCallback callback) {
        // TODO: Most of the methods exposing BasePermission internals [source package name,
        // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
        // have package settings, we should make note of it elsewhere [map between
        // source package name and BasePermission] and cycle through that here. Then we
        // define a single method on BasePermission that takes a PackageSetting, changing
        // package name and a package.
        // NOTE: With this approach, we also don't need to tree trees differently than
        // normal permissions. Today, we need two separate loops because these BasePermission
        // objects are stored separately.
        // Make sure there are no dangling permission trees.
        boolean permissionTreesSourcePackageChanged = updatePermissionTreeSourcePackage(
                changingPkgName, changingPkg);
        // Make sure all dynamic permissions have been assigned to a package,
        // and make sure there are no dangling permissions.
        boolean permissionSourcePackageChanged = updatePermissionSourcePackage(changingPkgName,
                callback);

        if (permissionTreesSourcePackageChanged | permissionSourcePackageChanged) {
            // Permission ownership has changed. This e.g. changes which packages can get signature
            // permissions
            Slog.i(TAG, "Permission ownership changed. Updating all permissions.");
            flags |= UPDATE_PERMISSIONS_ALL;
        }

        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
        // Now update the permissions for all packages.
        if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
            final boolean replaceAll = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
            mPackageManagerInt.forEachPackage((AndroidPackage pkg) -> {
                if (pkg == changingPkg) {
                    return;
                }
                // Only replace for packages on requested volume
                final String volumeUuid = getVolumeUuidForPackage(pkg);
                final boolean replace = replaceAll && Objects.equals(replaceVolumeUuid, volumeUuid);
                restorePermissionState(pkg, replace, changingPkgName, callback,
                        UserHandle.USER_ALL);
            });
        }

        if (changingPkg != null) {
            // Only replace for packages on requested volume
            final String volumeUuid = getVolumeUuidForPackage(changingPkg);
            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
                    && Objects.equals(replaceVolumeUuid, volumeUuid);
            restorePermissionState(changingPkg, replace, changingPkgName, callback,
                    UserHandle.USER_ALL);
        }
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    }

    /**
     * Update which app declares a permission.
     *
     * @param packageName The package that is updated, or {@code null} if all packages should be
     *                    updated
     *
     * @return {@code true} if a permission source package might have changed
     */
    private boolean updatePermissionSourcePackage(@Nullable String packageName,
            final @Nullable PermissionCallback callback) {
        // Always need update if packageName is null
        if (packageName == null) {
            return true;
        }

        boolean changed = false;
        Set<Permission> needsUpdate = null;
        synchronized (mLock) {
            for (final Permission bp : mRegistry.getPermissions()) {
                if (bp.isDynamic()) {
                    bp.updateDynamicPermission(mRegistry.getPermissionTrees());
                }
                if (!packageName.equals(bp.getPackageName())) {
                    // Not checking sourcePackageSetting because it can be null when
                    // the permission source package is the target package and the target package is
                    // being uninstalled,
                    continue;
                }
                // Don't remove config permissions and lose their GIDs.
                if (bp.getType() == Permission.TYPE_CONFIG && !bp.isReconciled()) {
                    continue;
                }
                // The target package is the source of the current permission
                // Set to changed for either install or uninstall
                changed = true;
                if (needsUpdate == null) {
                    needsUpdate = new ArraySet<>();
                }
                needsUpdate.add(bp);
            }
        }
        if (needsUpdate != null) {
            final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
            for (final Permission bp : needsUpdate) {
                // If the target package is being uninstalled, we need to revoke this permission
                // From all other packages
                if (pkg == null || !hasPermission(pkg, bp.getName())) {
                    if (!isPermissionDeclaredByDisabledSystemPkg(bp)) {
                        Slog.i(TAG, "Removing permission " + bp.getName()
                                + " that used to be declared by " + bp.getPackageName());
                        if (bp.isRuntime()) {
                            final int[] userIds = mUserManagerInt.getUserIds();
                            final int numUserIds = userIds.length;
                            for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
                                final int userId = userIds[userIdNum];
                                mPackageManagerInt.forEachPackage((AndroidPackage p) ->
                                        revokePermissionFromPackageForUser(p.getPackageName(),
                                                bp.getName(), true, userId, callback));
                            }
                        } else {
                            mPackageManagerInt.forEachPackage(p -> {
                                final int[] userIds = mUserManagerInt.getUserIds();
                                synchronized (mLock) {
                                    for (final int userId : userIds) {
                                        final UidPermissionState uidState = getUidStateLocked(p,
                                                userId);
                                        if (uidState == null) {
                                            Slog.e(TAG, "Missing permissions state for "
                                                    + p.getPackageName() + " and user " + userId);
                                            continue;
                                        }
                                        uidState.removePermissionState(bp.getName());
                                    }
                                }
                            });
                        }
                    }
                    synchronized (mLock) {
                        mRegistry.removePermission(bp.getName());
                    }
                    continue;
                }
                final AndroidPackage sourcePkg =
                        mPackageManagerInt.getPackage(bp.getPackageName());
                final PackageStateInternal sourcePs =
                        mPackageManagerInt.getPackageStateInternal(bp.getPackageName());
                synchronized (mLock) {
                    if (sourcePkg != null && sourcePs != null) {
                        continue;
                    }
                    Slog.w(TAG, "Removing dangling permission: " + bp.getName()
                            + " from package " + bp.getPackageName());
                    mRegistry.removePermission(bp.getName());
                }
            }
        }
        return changed;
    }

    private boolean isPermissionDeclaredByDisabledSystemPkg(@NonNull Permission permission) {
        final PackageStateInternal disabledSourcePs = mPackageManagerInt.getDisabledSystemPackage(
                    permission.getPackageName());
        if (disabledSourcePs != null && disabledSourcePs.getPkg() != null) {
            final String permissionName = permission.getName();
            final List<ParsedPermission> sourcePerms = disabledSourcePs.getPkg().getPermissions();
            for (ParsedPermission sourcePerm : sourcePerms) {
                if (TextUtils.equals(permissionName, sourcePerm.getName())
                        && permission.getProtectionLevel() == sourcePerm.getProtectionLevel()) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Revoke a runtime permission from a package for a given user ID.
     */
    private void revokePermissionFromPackageForUser(@NonNull String pName,
            @NonNull String permissionName, boolean overridePolicy, int userId,
            @Nullable PermissionCallback callback) {
        final ApplicationInfo appInfo =
                mPackageManagerInt.getApplicationInfo(pName, 0,
                        Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
        if (appInfo != null
                && appInfo.targetSdkVersion < Build.VERSION_CODES.M) {
            return;
        }

        if (checkPermission(pName, permissionName, userId)
                == PackageManager.PERMISSION_GRANTED) {
            try {
                revokeRuntimePermissionInternal(
                        pName, permissionName,
                        overridePolicy,
                        Process.SYSTEM_UID,
                        userId,
                        null, callback);
            } catch (IllegalArgumentException e) {
                Slog.e(TAG,
                        "Failed to revoke "
                                + permissionName
                                + " from "
                                + pName,
                        e);
            }
        }
    }

    /**
     * Update which app owns a permission trees.
     *
     * <p>Possible parameter combinations
     * <table>
     *     <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr>
     *     <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr>
     *     <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr>
     * </table>
     *
     * @param packageName The package that is updated, or {@code null} if all packages should be
     *                    updated
     * @param pkg The package that is updated, or {@code null} if all packages should be updated or
     *            package is deleted
     *
     * @return {@code true} if a permission tree ownership might have changed
     */
    private boolean updatePermissionTreeSourcePackage(@Nullable String packageName,
            @Nullable AndroidPackage pkg) {
        // Always need update if packageName is null
        if (packageName == null) {
            return true;
        }
        boolean changed = false;

        synchronized (mLock) {
            final Iterator<Permission> it = mRegistry.getPermissionTrees().iterator();
            while (it.hasNext()) {
                final Permission bp = it.next();
                if (!packageName.equals(bp.getPackageName())) {
                    // Not checking sourcePackageSetting because it can be null when
                    // the permission source package is the target package and the target package is
                    // being uninstalled,
                    continue;
                }
                // The target package is the source of the current permission tree
                // Set to changed for either install or uninstall
                changed = true;
                if (pkg == null || !hasPermission(pkg, bp.getName())) {
                    Slog.i(TAG, "Removing permission tree " + bp.getName()
                            + " that used to be declared by " + bp.getPackageName());
                    it.remove();
                }
            }
        }
        return changed;
    }

    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
                != PackageManager.PERMISSION_GRANTED
            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException(message + " requires "
                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
        }
    }

    private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) {
        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
                != PackageManager.PERMISSION_GRANTED
            && mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
                != PackageManager.PERMISSION_GRANTED
            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException(message + " requires "
                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " or "
                    + Manifest.permission.GET_RUNTIME_PERMISSIONS);
        }
    }

    /**
     * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
     * or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
     *
     * @param checkShell whether to prevent shell from access if there's a debugging restriction
     * @param message the message to log on security exception
     */
    private void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
            boolean requireFullPermission, boolean checkShell, @Nullable String message) {
        if (userId < 0) {
            throw new IllegalArgumentException("Invalid userId " + userId);
        }
        if (checkShell) {
            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
        }
        final int callingUserId = UserHandle.getUserId(callingUid);
        if (checkCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission)) {
            return;
        }
        String errorMessage = buildInvalidCrossUserPermissionMessage(
                callingUid, userId, message, requireFullPermission);
        Slog.w(TAG, errorMessage);
        throw new SecurityException(errorMessage);
    }

    /**
     *  Enforces that if the caller is shell, it does not have the provided user restriction.
     */
    private void enforceShellRestriction(@NonNull String restriction, int callingUid,
            @UserIdInt int userId) {
        if (callingUid == Process.SHELL_UID) {
            if (userId >= 0 && mUserManagerInt.hasUserRestriction(restriction, userId)) {
                throw new SecurityException("Shell does not have permission to access user "
                        + userId);
            } else if (userId < 0) {
                Slog.e(LOG_TAG, "Unable to check shell permission for user "
                        + userId + "\n\t" + Debug.getCallers(3));
            }
        }
    }

    private boolean checkCrossUserPermission(int callingUid, @UserIdInt int callingUserId,
            @UserIdInt int userId, boolean requireFullPermission) {
        if (userId == callingUserId) {
            return true;
        }
        if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) {
            return true;
        }
        if (requireFullPermission) {
            return checkCallingOrSelfPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
        }
        return checkCallingOrSelfPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
                || checkCallingOrSelfPermission(android.Manifest.permission.INTERACT_ACROSS_USERS);
    }

    private boolean checkCallingOrSelfPermission(String permission) {
        return mContext.checkCallingOrSelfPermission(permission)
                == PackageManager.PERMISSION_GRANTED;
    }

    @NonNull
    private static String buildInvalidCrossUserPermissionMessage(int callingUid,
            @UserIdInt int userId, @Nullable String message, boolean requireFullPermission) {
        StringBuilder builder = new StringBuilder();
        if (message != null) {
            builder.append(message);
            builder.append(": ");
        }
        builder.append("UID ");
        builder.append(callingUid);
        builder.append(" requires ");
        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
        if (!requireFullPermission) {
            builder.append(" or ");
            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
        }
        builder.append(" to access user ");
        builder.append(userId);
        builder.append(".");
        return builder.toString();
    }

    @GuardedBy("mLock")
    private int calculateCurrentPermissionFootprintLocked(@NonNull Permission permissionTree) {
        int size = 0;
        for (final Permission permission : mRegistry.getPermissions()) {
            size += permissionTree.calculateFootprint(permission);
        }
        return size;
    }

    @GuardedBy("mLock")
    private void enforcePermissionCapLocked(PermissionInfo info, Permission tree) {
        // We calculate the max size of permissions defined by this uid and throw
        // if that plus the size of 'info' would exceed our stated maximum.
        if (tree.getUid() != Process.SYSTEM_UID) {
            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
            if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
                throw new SecurityException("Permission tree size cap exceeded");
            }
        }
    }

    @Override
    public void onSystemReady() {
        // Now that we've scanned all packages, and granted any default
        // permissions, ensure permissions are updated. Beware of dragons if you
        // try optimizing this.
        updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, false);

        final PermissionPolicyInternal permissionPolicyInternal = LocalServices.getService(
                PermissionPolicyInternal.class);
        permissionPolicyInternal.setOnInitializedCallback(userId ->
                // The SDK updated case is already handled when we run during the ctor.
                updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, false)
        );

        synchronized (mLock) {
            mSystemReady = true;

            if (mPrivappPermissionsViolations != null) {
                throw new IllegalStateException("Signature|privileged permissions not in "
                        + "privapp-permissions allowlist: " + mPrivappPermissionsViolations);
            }
        }

        mPermissionControllerManager = new PermissionControllerManager(
                mContext, PermissionThread.getHandler());
        mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);    }

    private static String getVolumeUuidForPackage(AndroidPackage pkg) {
        if (pkg == null) {
            return StorageManager.UUID_PRIVATE_INTERNAL;
        }
        if (pkg.isExternalStorage()) {
            if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
                return StorageManager.UUID_PRIMARY_PHYSICAL;
            } else {
                return pkg.getVolumeUuid();
            }
        } else {
            return StorageManager.UUID_PRIVATE_INTERNAL;
        }
    }

    private static boolean hasPermission(AndroidPackage pkg, String permName) {
        if (pkg.getPermissions().isEmpty()) {
            return false;
        }

        for (int i = pkg.getPermissions().size() - 1; i >= 0; i--) {
            if (pkg.getPermissions().get(i).getName().equals(permName)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Log that a permission request was granted/revoked.
     *
     * @param action the action performed
     * @param name name of the permission
     * @param packageName package permission is for
     */
    private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
        final LogMaker log = new LogMaker(action);
        log.setPackageName(packageName);
        log.addTaggedData(MetricsProto.MetricsEvent.FIELD_PERMISSION, name);

        mMetricsLogger.write(log);
    }

    @GuardedBy("mLock")
    @Nullable
    private UidPermissionState getUidStateLocked(@NonNull PackageStateInternal ps,
            @UserIdInt int userId) {
        return getUidStateLocked(ps.getAppId(), userId);
    }

    @GuardedBy("mLock")
    @Nullable
    private UidPermissionState getUidStateLocked(@NonNull AndroidPackage pkg,
            @UserIdInt int userId) {
        return getUidStateLocked(pkg.getUid(), userId);
    }

    @GuardedBy("mLock")
    @Nullable
    private UidPermissionState getUidStateLocked(@AppIdInt int appId, @UserIdInt int userId) {
        final UserPermissionState userState = mState.getUserState(userId);
        if (userState == null) {
            return null;
        }
        return userState.getUidState(appId);
    }

    private void removeUidStateAndResetPackageInstallPermissionsFixed(@AppIdInt int appId,
            @NonNull String packageName, @UserIdInt int userId) {
        synchronized (mLock) {
            final UserPermissionState userState = mState.getUserState(userId);
            if (userState == null) {
                return;
            }
            userState.removeUidState(appId);
            userState.setInstallPermissionsFixed(packageName, false);
        }
    }

    @Override
    public void readLegacyPermissionStateTEMP() {
        final int[] userIds = getAllUserIds();
        mPackageManagerInt.forEachPackageState(ps -> {
            final int appId = ps.getAppId();
            final LegacyPermissionState legacyState;
            if (ps.hasSharedUser()) {
                final int sharedUserId = ps.getSharedUserAppId();
                SharedUserApi sharedUserApi = mPackageManagerInt.getSharedUserApi(sharedUserId);
                if (sharedUserApi == null) {
                    Slog.wtf(TAG, "Missing shared user Api for " + sharedUserId);
                    return;
                }
                legacyState = sharedUserApi.getSharedUserLegacyPermissionState();
            } else {
                legacyState = ps.getLegacyPermissionState();
            }
            synchronized (mLock) {
                for (final int userId : userIds) {
                    final UserPermissionState userState = mState.getOrCreateUserState(userId);

                    userState.setInstallPermissionsFixed(ps.getPackageName(),
                            ps.isInstallPermissionsFixed());
                    final UidPermissionState uidState = userState.getOrCreateUidState(appId);
                    uidState.reset();
                    uidState.setMissing(legacyState.isMissing(userId));
                    readLegacyPermissionStatesLocked(uidState,
                            legacyState.getPermissionStates(userId));
                }
            }
        });
    }

    @GuardedBy("mLock")
    private void readLegacyPermissionStatesLocked(@NonNull UidPermissionState uidState,
            @NonNull Collection<LegacyPermissionState.PermissionState> permissionStates) {
        for (final LegacyPermissionState.PermissionState permissionState : permissionStates) {
            final String permissionName = permissionState.getName();
            final Permission permission = mRegistry.getPermission(permissionName);
            if (permission == null) {
                Slog.w(TAG, "Unknown permission: " + permissionName);
                continue;
            }
            uidState.putPermissionState(permission, permissionState.isGranted(),
                    permissionState.getFlags());
        }
    }

    @Override
    public void writeLegacyPermissionStateTEMP() {
        final int[] userIds;
        synchronized (mLock) {
            userIds = mState.getUserIds();
        }
        mPackageManagerInt.forEachPackageSetting(ps -> {
            ps.setInstallPermissionsFixed(false);
            final LegacyPermissionState legacyState;
            if (ps.hasSharedUser()) {
                final int sharedUserId = ps.getSharedUserAppId();
                SharedUserApi sharedUserApi = mPackageManagerInt.getSharedUserApi(sharedUserId);
                if (sharedUserApi == null) {
                    Slog.wtf(TAG, "Missing shared user Api for " + sharedUserId);
                    return;
                }
                legacyState = sharedUserApi.getSharedUserLegacyPermissionState();
            } else {
                legacyState = ps.getLegacyPermissionState();
            }
            legacyState.reset();
            final int appId = ps.getAppId();

            synchronized (mLock) {
                for (final int userId : userIds) {
                    final UserPermissionState userState = mState.getUserState(userId);
                    if (userState == null) {
                        Slog.e(TAG, "Missing user state for " + userId);
                        continue;
                    }

                    if (userState.areInstallPermissionsFixed(ps.getPackageName())) {
                        ps.setInstallPermissionsFixed(true);
                    }

                    final UidPermissionState uidState = userState.getUidState(appId);
                    if (uidState == null) {
                        Slog.e(TAG, "Missing permission state for " + ps.getPackageName()
                                + " and user " + userId);
                        continue;
                    }

                    legacyState.setMissing(uidState.isMissing(), userId);
                    final List<PermissionState> permissionStates = uidState.getPermissionStates();
                    final int permissionStatesSize = permissionStates.size();
                    for (int i = 0; i < permissionStatesSize; i++) {
                        final PermissionState permissionState = permissionStates.get(i);

                        final LegacyPermissionState.PermissionState legacyPermissionState =
                                new LegacyPermissionState.PermissionState(permissionState.getName(),
                                        permissionState.getPermission().isRuntime(),
                                        permissionState.isGranted(), permissionState.getFlags());
                        legacyState.putPermissionState(legacyPermissionState, userId);
                    }
                }
            }
        });
    }

    @Override
    public void readLegacyPermissionsTEMP(
            @NonNull LegacyPermissionSettings legacyPermissionSettings) {
        for (int readPermissionOrPermissionTree = 0; readPermissionOrPermissionTree < 2;
                readPermissionOrPermissionTree++) {
            final List<LegacyPermission> legacyPermissions = readPermissionOrPermissionTree == 0
                    ? legacyPermissionSettings.getPermissions()
                    : legacyPermissionSettings.getPermissionTrees();
            synchronized (mLock) {
                final int legacyPermissionsSize = legacyPermissions.size();
                for (int i = 0; i < legacyPermissionsSize; i++) {
                    final LegacyPermission legacyPermission = legacyPermissions.get(i);
                    final Permission permission = new Permission(
                            legacyPermission.getPermissionInfo(), legacyPermission.getType());
                    if (readPermissionOrPermissionTree == 0) {
                        // Config permissions are currently read in PermissionManagerService
                        // constructor. The old behavior was to add other attributes to the config
                        // permission in LegacyPermission.read(), so equivalently we can add the
                        // GIDs to the new permissions here, since config permissions created in
                        // PermissionManagerService constructor get only their names and GIDs there.
                        final Permission configPermission = mRegistry.getPermission(
                                permission.getName());
                        if (configPermission != null
                                && configPermission.getType() == Permission.TYPE_CONFIG) {
                            permission.setGids(configPermission.getRawGids(),
                                    configPermission.areGidsPerUser());
                        }
                        mRegistry.addPermission(permission);
                    } else {
                        mRegistry.addPermissionTree(permission);
                    }
                }
            }
        }
    }

    @Override
    public void writeLegacyPermissionsTEMP(
            @NonNull LegacyPermissionSettings legacyPermissionSettings) {
        for (int writePermissionOrPermissionTree = 0; writePermissionOrPermissionTree < 2;
                writePermissionOrPermissionTree++) {
            final List<LegacyPermission> legacyPermissions = new ArrayList<>();
            synchronized (mLock) {
                final Collection<Permission> permissions = writePermissionOrPermissionTree == 0
                        ? mRegistry.getPermissions() : mRegistry.getPermissionTrees();
                for (final Permission permission : permissions) {
                    // We don't need to provide UID and GIDs, which are only retrieved when dumping.
                    final LegacyPermission legacyPermission = new LegacyPermission(
                            permission.getPermissionInfo(), permission.getType(), 0,
                            EmptyArray.INT);
                    legacyPermissions.add(legacyPermission);
                }
            }
            if (writePermissionOrPermissionTree == 0) {
                legacyPermissionSettings.replacePermissions(legacyPermissions);
            } else {
                legacyPermissionSettings.replacePermissionTrees(legacyPermissions);
            }
        }
    }

    @Nullable
    @Override
    public String getDefaultPermissionGrantFingerprint(@UserIdInt int userId) {
        return mPackageManagerInt.isPermissionUpgradeNeeded(userId) ? null : Build.FINGERPRINT;
    }

    @Override
    public void setDefaultPermissionGrantFingerprint(@NonNull String fingerprint,
            @UserIdInt int userId) {
        // Ignored - default permission grant here shares the same version with runtime permission
        // upgrade, and the new version is set by that later.
    }

    private void onPackageAddedInternal(@NonNull PackageState packageState,
            @NonNull AndroidPackage pkg, boolean isInstantApp, @Nullable AndroidPackage oldPkg) {
        if (!pkg.getAdoptPermissions().isEmpty()) {
            // This package wants to adopt ownership of permissions from
            // another package.
            for (int i = pkg.getAdoptPermissions().size() - 1; i >= 0; i--) {
                final String origName = pkg.getAdoptPermissions().get(i);
                if (canAdoptPermissionsInternal(origName, pkg)) {
                    Slog.i(TAG, "Adopting permissions from " + origName + " to "
                            + pkg.getPackageName());
                    synchronized (mLock) {
                        mRegistry.transferPermissions(origName, pkg.getPackageName());
                    }
                }
            }
        }

        // Don't allow ephemeral applications to define new permissions groups.
        if (isInstantApp) {
            Slog.w(TAG, "Permission groups from package " + pkg.getPackageName()
                    + " ignored: instant apps cannot define new permission groups.");
        } else {
            addAllPermissionGroupsInternal(pkg);
        }

        // If a permission has had its defining app changed, or it has had its protection
        // upgraded, we need to revoke apps that hold it
        final List<String> permissionsWithChangedDefinition;
        // Don't allow ephemeral applications to define new permissions.
        if (isInstantApp) {
            permissionsWithChangedDefinition = null;
            Slog.w(TAG, "Permissions from package " + pkg.getPackageName()
                    + " ignored: instant apps cannot define new permissions.");
        } else {
            permissionsWithChangedDefinition = addAllPermissionsInternal(packageState, pkg);
        }

        boolean hasOldPkg = oldPkg != null;
        boolean hasPermissionDefinitionChanges =
                !CollectionUtils.isEmpty(permissionsWithChangedDefinition);
        if (hasOldPkg || hasPermissionDefinitionChanges) {
            // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
            // revoke callbacks from this method might need to kill apps which need the
            // mPackages lock on a different thread. This would dead lock.
            AsyncTask.execute(() -> {
                if (hasOldPkg) {
                    revokeRuntimePermissionsIfGroupChangedInternal(pkg, oldPkg);
                    revokeStoragePermissionsIfScopeExpandedInternal(pkg, oldPkg);
                    revokeSystemAlertWindowIfUpgradedPast23(pkg, oldPkg);
                }
                if (hasPermissionDefinitionChanges) {
                    revokeRuntimePermissionsIfPermissionDefinitionChangedInternal(
                            permissionsWithChangedDefinition);
                }
            });
        }
    }

    private boolean canAdoptPermissionsInternal(@NonNull String oldPackageName,
            @NonNull AndroidPackage newPkg) {
        final PackageStateInternal oldPs =
                mPackageManagerInt.getPackageStateInternal(oldPackageName);
        if (oldPs == null) {
            return false;
        }
        if (!oldPs.isSystem()) {
            Slog.w(TAG, "Unable to update from " + oldPs.getPackageName()
                    + " to " + newPkg.getPackageName()
                    + ": old package not in system partition");
            return false;
        }
        if (mPackageManagerInt.getPackage(oldPs.getPackageName()) != null) {
            Slog.w(TAG, "Unable to update from " + oldPs.getPackageName()
                    + " to " + newPkg.getPackageName()
                    + ": old package still exists");
            return false;
        }
        return true;
    }

    private boolean isEffectivelyGranted(PermissionState state) {
        final int flags = state.getFlags();
        final int denyMask = FLAG_PERMISSION_REVIEW_REQUIRED
                | FLAG_PERMISSION_REVOKED_COMPAT
                | FLAG_PERMISSION_ONE_TIME;

        if ((flags & FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
            return true;
        } else if ((flags & FLAG_PERMISSION_POLICY_FIXED) != 0) {
            return (flags & FLAG_PERMISSION_REVOKED_COMPAT) == 0 && state.isGranted();
        } else if ((flags & denyMask) != 0) {
            return false;
        } else {
            return state.isGranted();
        }
    }

    /**
     * Merge srcState into destState. Return [granted, flags].
     */
    private Pair<Boolean, Integer> mergePermissionState(int appId,
            PermissionState srcState, PermissionState destState) {
        // This merging logic prioritizes the shared permission state (destState) over
        // the current package's state (srcState), because an uninstallation of a previously
        // unrelated app (the updated system app) should not affect the functionality of
        // existing apps (other apps in the shared UID group).

        final int userSettableMask = FLAG_PERMISSION_USER_SET
                | FLAG_PERMISSION_USER_FIXED
                | FLAG_PERMISSION_SELECTED_LOCATION_ACCURACY;

        final int defaultGrantMask = FLAG_PERMISSION_GRANTED_BY_DEFAULT
                | FLAG_PERMISSION_GRANTED_BY_ROLE;

        final int priorityFixedMask = FLAG_PERMISSION_SYSTEM_FIXED
                | FLAG_PERMISSION_POLICY_FIXED;

        final int priorityMask = defaultGrantMask | priorityFixedMask;

        final int destFlags = destState.getFlags();
        final boolean destIsGranted = isEffectivelyGranted(destState);

        final int srcFlags = srcState.getFlags();
        final boolean srcIsGranted = isEffectivelyGranted(srcState);

        final int combinedFlags = destFlags | srcFlags;

        /* Merge flags */

        int newFlags = 0;

        // Inherit user set flags only from dest as we want to preserve the
        // user preference of destState, not the one of the current package.
        newFlags |= (destFlags & userSettableMask);

        // Inherit all exempt flags
        newFlags |= (combinedFlags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT);
        // If no exempt flags are set, set APPLY_RESTRICTION
        if ((newFlags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
            newFlags |= FLAG_PERMISSION_APPLY_RESTRICTION;
        }

        // Inherit all priority flags
        newFlags |= (combinedFlags & priorityMask);

        // If no priority flags are set, inherit REVOKE_WHEN_REQUESTED
        if ((combinedFlags & priorityMask) == 0) {
            newFlags |= (combinedFlags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
        }

        // Handle REVIEW_REQUIRED
        if ((newFlags & priorityFixedMask) == 0) {
            if ((newFlags & (defaultGrantMask | userSettableMask)) == 0
                    && NOTIFICATION_PERMISSIONS.contains(srcState.getName())) {
                // For notification permissions, inherit from both states
                // if no priority FIXED or DEFAULT_GRANT or USER_SET flags are set
                newFlags |= (combinedFlags & FLAG_PERMISSION_REVIEW_REQUIRED);
            } else if ((newFlags & priorityMask) == 0) {
                // Else inherit from destState if no priority flags are set
                newFlags |= (destFlags & FLAG_PERMISSION_REVIEW_REQUIRED);
            }
        }

        /* Determine effective grant state */

        final boolean effectivelyGranted;
        if ((newFlags & FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
            effectivelyGranted = true;
        } else if ((destFlags & FLAG_PERMISSION_POLICY_FIXED) != 0) {
            // If this flag comes from destState, preserve its state
            effectivelyGranted = destIsGranted;
        } else if ((srcFlags & FLAG_PERMISSION_POLICY_FIXED) != 0) {
            effectivelyGranted = destIsGranted || srcIsGranted;
            // If this flag comes from srcState, preserve flag only if
            // there is no conflict
            if (destIsGranted != srcIsGranted) {
                newFlags &= ~FLAG_PERMISSION_POLICY_FIXED;
            }
        } else if ((destFlags & defaultGrantMask) != 0) {
            // If a permission state has default grant flags and is not
            // granted, this meant user has overridden the grant state.
            // Respect the user's preference on destState.
            // Due to this reason, if this flag comes from destState,
            // preserve its state
            effectivelyGranted = destIsGranted;
        } else if ((srcFlags & defaultGrantMask) != 0) {
            effectivelyGranted = destIsGranted || srcIsGranted;
        } else if ((destFlags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
            // Similar reason to defaultGrantMask, if this flag comes
            // from destState, preserve its state
            effectivelyGranted = destIsGranted;
        } else if ((srcFlags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
            effectivelyGranted = destIsGranted || srcIsGranted;
            // If this flag comes from srcState, remove this flag if
            // destState is already granted to prevent revocation.
            if (destIsGranted) {
                newFlags &= ~FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
            }
        } else {
            // If still not determined, fallback to destState.
            effectivelyGranted = destIsGranted;
        }

        /* Post-processing / fix ups */

        if (!effectivelyGranted) {
            // If not effectively granted, inherit AUTO_REVOKED
            newFlags |= (combinedFlags & FLAG_PERMISSION_AUTO_REVOKED);

            // REVOKE_WHEN_REQUESTED make no sense when denied
            newFlags &= ~FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
        } else {
            // REVIEW_REQUIRED make no sense when granted
            newFlags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
        }

        if (effectivelyGranted != destIsGranted) {
            // Remove user set flags if state changes
            newFlags &= ~userSettableMask;
        }

        // Fix permission state based on targetSdk of the shared UID
        final boolean newGrantState;
        if (!effectivelyGranted && isPermissionSplitFromNonRuntime(
                srcState.getName(),
                mPackageManagerInt.getUidTargetSdkVersion(appId))) {
            // Even though effectively denied, it has to be set to granted
            // for backwards compatibility
            newFlags |= FLAG_PERMISSION_REVOKED_COMPAT;
            newGrantState = true;
        } else {
            // Either it's effectively granted, or it targets a high enough API level
            // to handle this permission properly
            newGrantState = effectivelyGranted;
        }

        return new Pair<>(newGrantState, newFlags);
    }

    /**
     * This method handles permission migration of packages leaving/joining shared UID
     */
    private void handleAppIdMigration(@NonNull AndroidPackage pkg, int previousAppId) {
        final PackageStateInternal ps =
                mPackageManagerInt.getPackageStateInternal(pkg.getPackageName());

        if (ps.hasSharedUser()) {
            // The package is joining a shared user group. This can only happen when a system
            // app left shared UID with an update, and then the update is uninstalled.
            // If no apps remain in its original shared UID group, clone the current
            // permission state to the shared appId; or else, merge the current permission
            // state into the shared UID state.

            synchronized (mLock) {
                for (final int userId : getAllUserIds()) {
                    final UserPermissionState userState = mState.getOrCreateUserState(userId);

                    // This is the permission state the package was using
                    final UidPermissionState uidState = userState.getUidState(previousAppId);
                    if (uidState == null) {
                        continue;
                    }

                    // This is the shared UID permission state the package wants to join
                    final UidPermissionState sharedUidState = userState.getUidState(ps.getAppId());
                    if (sharedUidState == null) {
                        // No apps remain in the shared UID group, clone permissions
                        userState.createUidStateWithExisting(ps.getAppId(), uidState);
                    } else {
                        final List<PermissionState> states = uidState.getPermissionStates();
                        final int count = states.size();
                        for (int i = 0; i < count; ++i) {
                            final PermissionState srcState = states.get(i);
                            final PermissionState destState =
                                    sharedUidState.getPermissionState(srcState.getName());
                            if (destState != null) {
                                // Merge the 2 permission states
                                Pair<Boolean, Integer> newState =
                                        mergePermissionState(ps.getAppId(), srcState, destState);
                                sharedUidState.putPermissionState(srcState.getPermission(),
                                        newState.first, newState.second);
                            } else {
                                // Simply copy the permission state over
                                sharedUidState.putPermissionState(srcState.getPermission(),
                                        srcState.isGranted(), srcState.getFlags());
                            }
                        }
                    }

                    // Remove permissions for the previous appId
                    userState.removeUidState(previousAppId);
                }
            }
        } else {
            // The package is migrating out of a shared user group.
            // Operations we need to do before calling updatePermissions():
            // - Retrieve the original uid permission state and create a copy of it as the
            //   new app's uid state. The new permission state will be properly updated in
            //   updatePermissions().
            // - Remove the app from the original shared user group. Other apps in the shared
            //   user group will perceive as if the original app is uninstalled.

            final List<AndroidPackage> origSharedUserPackages =
                    mPackageManagerInt.getPackagesForAppId(previousAppId);

            synchronized (mLock) {
                for (final int userId : getAllUserIds()) {
                    // Retrieve the original uid state
                    final UserPermissionState userState = mState.getUserState(userId);
                    if (userState == null) {
                        continue;
                    }
                    final UidPermissionState prevUidState = userState.getUidState(previousAppId);
                    if (prevUidState == null) {
                        continue;
                    }

                    // Insert new uid state by cloning the original one
                    userState.createUidStateWithExisting(ps.getAppId(), prevUidState);

                    // Remove original app ID from original shared user group
                    // Should match the implementation of onPackageUninstalledInternal(...)
                    if (origSharedUserPackages.isEmpty()) {
                        removeUidStateAndResetPackageInstallPermissionsFixed(
                                previousAppId, pkg.getPackageName(), userId);
                    } else {
                        revokeSharedUserPermissionsForLeavingPackageInternal(pkg, previousAppId,
                                origSharedUserPackages, userId);
                    }
                }
            }
        }
    }

    private void onPackageInstalledInternal(@NonNull AndroidPackage pkg, int previousAppId,
            @NonNull PermissionManagerServiceInternal.PackageInstalledParams params,
            @UserIdInt int[] userIds) {
        if (previousAppId != INVALID_UID) {
            handleAppIdMigration(pkg, previousAppId);
        }
        updatePermissions(pkg.getPackageName(), pkg);
        for (final int userId : userIds) {
            addAllowlistedRestrictedPermissionsInternal(pkg,
                    params.getAllowlistedRestrictedPermissions(),
                    FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
            grantRequestedPermissionsInternal(pkg, params.getPermissionStates(), userId);
        }
    }

    private void addAllowlistedRestrictedPermissionsInternal(@NonNull AndroidPackage pkg,
            @NonNull List<String> allowlistedRestrictedPermissions,
            @PackageManager.PermissionWhitelistFlags int flags, @UserIdInt int userId) {
        List<String> permissions = getAllowlistedRestrictedPermissionsInternal(pkg, flags, userId);
        if (permissions != null) {
            ArraySet<String> permissionSet = new ArraySet<>(permissions);
            permissionSet.addAll(allowlistedRestrictedPermissions);
            permissions = new ArrayList<>(permissionSet);
        } else {
            permissions = allowlistedRestrictedPermissions;
        }
        setAllowlistedRestrictedPermissionsInternal(pkg, permissions, flags, userId);
    }

    private void onPackageRemovedInternal(@NonNull AndroidPackage pkg) {
        removeAllPermissionsInternal(pkg);
    }

    private void onPackageUninstalledInternal(@NonNull String packageName, int appId,
            @NonNull PackageState packageState, @Nullable AndroidPackage pkg,
            @NonNull List<AndroidPackage> sharedUserPkgs, @UserIdInt int[] userIds) {
        // TODO: Handle the case when a system app upgrade is uninstalled and need to rejoin
        //  a shared UID permission state.

        // System packages should always have an available APK.
        if (packageState.isSystem() && pkg != null
                // We may be fully removing invalid system packages during boot, and in that case we
                // do want to remove their permission state. So make sure that the package is only
                // being marked as uninstalled instead of fully removed.
                && mPackageManagerInt.getPackage(packageName) != null) {
            // If we are only marking a system package as uninstalled, we need to keep its
            // pregranted permission state so that it still works once it gets reinstalled, thus
            // only reset the user modifications to its permission state.
            for (final int userId : userIds) {
                resetRuntimePermissionsInternal(pkg, userId);
            }
            return;
        }
        updatePermissions(packageName, null);
        for (final int userId : userIds) {
            if (sharedUserPkgs.isEmpty()) {
                removeUidStateAndResetPackageInstallPermissionsFixed(appId, packageName, userId);
            } else {
                // Remove permissions associated with package. Since runtime
                // permissions are per user we have to kill the removed package
                // or packages running under the shared user of the removed
                // package if revoking the permissions requested only by the removed
                // package is successful and this causes a change in gids.
                revokeSharedUserPermissionsForLeavingPackageInternal(pkg, appId, sharedUserPkgs,
                        userId);
            }
        }
    }

    @NonNull
    @Override
    public List<LegacyPermission> getLegacyPermissions() {
        synchronized (mLock) {
            final List<LegacyPermission> legacyPermissions = new ArrayList<>();
            for (final Permission permission : mRegistry.getPermissions()) {
                final LegacyPermission legacyPermission = new LegacyPermission(
                        permission.getPermissionInfo(), permission.getType(), permission.getUid(),
                        permission.getRawGids());
                legacyPermissions.add(legacyPermission);
            }
            return legacyPermissions;
        }
    }

    @Override
    public Map<String, Set<String>> getAllAppOpPermissionPackages() {
        synchronized (mLock) {
            final ArrayMap<String, ArraySet<String>> appOpPermissionPackages =
                    mRegistry.getAllAppOpPermissionPackages();
            final Map<String, Set<String>> deepClone = new ArrayMap<>();
            final int appOpPermissionPackagesSize = appOpPermissionPackages.size();
            for (int i = 0; i < appOpPermissionPackagesSize; i++) {
                final String appOpPermission = appOpPermissionPackages.keyAt(i);
                final ArraySet<String> packageNames = appOpPermissionPackages.valueAt(i);
                deepClone.put(appOpPermission, new ArraySet<>(packageNames));
            }
            return deepClone;
        }
    }

    @NonNull
    @Override
    public LegacyPermissionState getLegacyPermissionState(@AppIdInt int appId) {
        final LegacyPermissionState legacyState = new LegacyPermissionState();
        synchronized (mLock) {
            final int[] userIds = mState.getUserIds();
            for (final int userId : userIds) {
                final UidPermissionState uidState = getUidStateLocked(appId, userId);
                if (uidState == null) {
                    Slog.e(TAG, "Missing permissions state for app ID " + appId + " and user ID "
                            + userId);
                    continue;
                }

                final List<PermissionState> permissionStates = uidState.getPermissionStates();
                final int permissionStatesSize = permissionStates.size();
                for (int i = 0; i < permissionStatesSize; i++) {
                    final PermissionState permissionState = permissionStates.get(i);

                    final LegacyPermissionState.PermissionState legacyPermissionState =
                            new LegacyPermissionState.PermissionState(permissionState.getName(),
                                    permissionState.getPermission().isRuntime(),
                                    permissionState.isGranted(), permissionState.getFlags());
                    legacyState.putPermissionState(legacyPermissionState, userId);
                }
            }
        }
        return legacyState;
    }

    @NonNull
    @Override
    public int[] getGidsForUid(int uid) {
        final int appId = UserHandle.getAppId(uid);
        final int userId = UserHandle.getUserId(uid);
        synchronized (mLock) {
            final UidPermissionState uidState = getUidStateLocked(appId, userId);
            if (uidState == null) {
                Slog.e(TAG, "Missing permissions state for app ID " + appId + " and user ID "
                        + userId);
                return EMPTY_INT_ARRAY;
            }
            return uidState.computeGids(mGlobalGids, userId);
        }
    }

    @Override
    public boolean isPermissionsReviewRequired(@NonNull String packageName,
            @UserIdInt int userId) {
        Objects.requireNonNull(packageName, "packageName");
        // TODO(b/173235285): Some caller may pass USER_ALL as userId.
        //Preconditions.checkArgumentNonnegative(userId, "userId");
        return isPermissionsReviewRequiredInternal(packageName, userId);
    }

    @NonNull
    @Override
    public Set<String> getInstalledPermissions(@NonNull String packageName) {
        Objects.requireNonNull(packageName, "packageName");
        final Set<String> installedPermissions = new ArraySet<>();
        synchronized (mLock) {
            for (final Permission permission : mRegistry.getPermissions()) {
                if (Objects.equals(permission.getPackageName(), packageName)) {
                    installedPermissions.add(permission.getName());
                }
            }
        }
        return installedPermissions;
    }

    @NonNull
    @Override
    public Set<String> getGrantedPermissions(@NonNull String packageName, @UserIdInt int userId) {
        Objects.requireNonNull(packageName, "packageName");
        Preconditions.checkArgumentNonNegative(userId, "userId");
        return getGrantedPermissionsInternal(packageName, userId);
    }

    @NonNull
    @Override
    public int[] getPermissionGids(@NonNull String permissionName, @UserIdInt int userId) {
        Objects.requireNonNull(permissionName, "permissionName");
        Preconditions.checkArgumentNonNegative(userId, "userId");
        return getPermissionGidsInternal(permissionName, userId);
    }

    @NonNull
    @Override
    public String[] getAppOpPermissionPackages(@NonNull String permissionName) {
        Objects.requireNonNull(permissionName, "permissionName");
        return PermissionManagerServiceImpl.this.getAppOpPermissionPackagesInternal(permissionName);
    }

    @Override
    public void onStorageVolumeMounted(@Nullable String volumeUuid, boolean fingerprintChanged) {
        updateAllPermissions(volumeUuid, fingerprintChanged);
    }

    @Override
    public void resetRuntimePermissions(@NonNull AndroidPackage pkg, @UserIdInt int userId) {
        Objects.requireNonNull(pkg, "pkg");
        Preconditions.checkArgumentNonNegative(userId, "userId");
        resetRuntimePermissionsInternal(pkg, userId);
    }

    @Override
    public void resetRuntimePermissionsForUser(@UserIdInt int userId) {
        Preconditions.checkArgumentNonNegative(userId, "userId");
        resetRuntimePermissionsInternal(null, userId);
    }

    @Override
    public Permission getPermissionTEMP(String permName) {
        synchronized (mLock) {
            return mRegistry.getPermission(permName);
        }
    }

    @NonNull
    @Override
    public List<PermissionInfo> getAllPermissionsWithProtection(
            @PermissionInfo.Protection int protection) {
        List<PermissionInfo> matchingPermissions = new ArrayList<>();

        synchronized (mLock) {
            for (final Permission permission : mRegistry.getPermissions()) {
                if (permission.getProtection() == protection) {
                    matchingPermissions.add(permission.generatePermissionInfo(0));
                }
            }
        }

        return matchingPermissions;
    }

    @NonNull
    @Override
    public List<PermissionInfo> getAllPermissionsWithProtectionFlags(
            @PermissionInfo.ProtectionFlags int protectionFlags) {
        List<PermissionInfo> matchingPermissions = new ArrayList<>();

        synchronized (mLock) {
            for (final Permission permission : mRegistry.getPermissions()) {
                if ((permission.getProtectionFlags() & protectionFlags) == protectionFlags) {
                    matchingPermissions.add(permission.generatePermissionInfo(0));
                }
            }
        }

        return matchingPermissions;
    }

    @Override
    public void onUserCreated(@UserIdInt int userId) {
        Preconditions.checkArgumentNonNegative(userId, "userId");
        // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
        updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, true);
    }

    @Override
    public void onPackageAdded(@NonNull PackageState packageState, boolean isInstantApp,
                    @Nullable AndroidPackage oldPkg) {
        Objects.requireNonNull(packageState);
        var pkg = packageState.getAndroidPackage();
        Objects.requireNonNull(pkg);
        onPackageAddedInternal(packageState, pkg, isInstantApp, oldPkg);
    }

    @Override
    public void onPackageInstalled(@NonNull AndroidPackage pkg, int previousAppId,
            @NonNull PermissionManagerServiceInternal.PackageInstalledParams params,
            @UserIdInt int userId) {
        Objects.requireNonNull(pkg, "pkg");
        Objects.requireNonNull(params, "params");
        Preconditions.checkArgument(userId >= UserHandle.USER_SYSTEM
                || userId == UserHandle.USER_ALL, "userId");
        final int[] userIds = userId == UserHandle.USER_ALL ? getAllUserIds()
                : new int[] { userId };
        onPackageInstalledInternal(pkg, previousAppId, params, userIds);
    }

    @Override
    public void onPackageRemoved(@NonNull AndroidPackage pkg) {
        Objects.requireNonNull(pkg);
        onPackageRemovedInternal(pkg);
    }

    @Override
    public void onPackageUninstalled(@NonNull String packageName, int appId,
            @NonNull PackageState packageState, @Nullable AndroidPackage pkg,
            @NonNull List<AndroidPackage> sharedUserPkgs, @UserIdInt int userId) {
        Objects.requireNonNull(packageState, "packageState");
        Objects.requireNonNull(packageName, "packageName");
        Objects.requireNonNull(sharedUserPkgs, "sharedUserPkgs");
        Preconditions.checkArgument(userId >= UserHandle.USER_SYSTEM
                || userId == UserHandle.USER_ALL, "userId");
        final int[] userIds = userId == UserHandle.USER_ALL ? getAllUserIds()
                : new int[] { userId };
        onPackageUninstalledInternal(packageName, appId, packageState, pkg, sharedUserPkgs,
                userIds);
    }

    /**
     * Callbacks invoked when interesting actions have been taken on a permission.
     * <p>
     * NOTE: The current arguments are merely to support the existing use cases. This
     * needs to be properly thought out with appropriate arguments for each of the
     * callback methods.
     */
    private static class PermissionCallback {
        public void onGidsChanged(@AppIdInt int appId, @UserIdInt int userId) {}
        public void onPermissionChanged() {}
        public void onPermissionGranted(int uid, @UserIdInt int userId) {}
        public void onInstallPermissionGranted() {}
        public void onPermissionRevoked(int uid, @UserIdInt int userId, String reason) {
            onPermissionRevoked(uid, userId, reason, false, null);
        }
        public void onPermissionRevoked(int uid, @UserIdInt int userId, String reason,
                boolean overrideKill, @Nullable String permissionName) {}
        public void onInstallPermissionRevoked() {}
        public void onPermissionUpdated(@UserIdInt int[] userIds, boolean sync, int appId) {}
        public void onPermissionRemoved() {}
        public void onInstallPermissionUpdated() {}
    }

    private static final class OnPermissionChangeListeners extends Handler {
        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;

        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
                new RemoteCallbackList<>();

        OnPermissionChangeListeners(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_ON_PERMISSIONS_CHANGED: {
                    final int uid = msg.arg1;
                    handleOnPermissionsChanged(uid);
                } break;
            }
        }

        public void addListener(IOnPermissionsChangeListener listener) {
            mPermissionListeners.register(listener);
        }

        public void removeListener(IOnPermissionsChangeListener listener) {
            mPermissionListeners.unregister(listener);
        }

        public void onPermissionsChanged(int uid) {
            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
            }
        }

        private void handleOnPermissionsChanged(int uid) {
            final int count = mPermissionListeners.beginBroadcast();
            try {
                for (int i = 0; i < count; i++) {
                    IOnPermissionsChangeListener callback = mPermissionListeners
                            .getBroadcastItem(i);
                    try {
                        callback.onPermissionsChanged(uid,
                                VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);
                    } catch (RemoteException e) {
                        Log.e(TAG, "Permission listener is dead", e);
                    }
                }
            } finally {
                mPermissionListeners.finishBroadcast();
            }
        }
    }
}
