/*
 * Copyright (C) 2017 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.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.content.pm.ApplicationInfo.AUTO_REVOKE_DISALLOWED;
import static android.content.pm.ApplicationInfo.AUTO_REVOKE_DISCOURAGED;
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_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_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.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.ApexManager.MATCH_ACTIVE_PACKAGE;
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 com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;

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

import android.Manifest;
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.ApplicationPackageManager;
import android.app.IActivityManager;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.content.Context;
import android.content.PermissionChecker;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.PermissionGroupInfoFlags;
import android.content.pm.PackageManager.PermissionInfoFlags;
import android.content.pm.PackageManager.PermissionWhitelistFlags;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageParser;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.parsing.component.ParsedPermission;
import android.content.pm.parsing.component.ParsedPermissionGroup;
import android.content.pm.permission.SplitPermissionInfoParcelable;
import android.metrics.LogMaker;
import android.os.Binder;
import android.os.Build;
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.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.os.storage.StorageManager;
import android.os.storage.StorageManagerInternal;
import android.permission.IOnPermissionsChangeListener;
import android.permission.IPermissionManager;
import android.permission.PermissionControllerManager;
import android.permission.PermissionManager;
import android.permission.PermissionManagerInternal;
import android.permission.PermissionManagerInternal.CheckPermissionDelegate;
import android.permission.PermissionManagerInternal.OnRuntimePermissionStateChangedListener;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
import android.util.EventLog;
import android.util.IntArray;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.RoSystemProperties;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IntPair;
import com.android.internal.util.Preconditions;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.FgThread;
import com.android.server.LocalServices;
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.PackageManagerServiceUtils;
import com.android.server.pm.PackageSetting;
import com.android.server.pm.SharedUserSetting;
import com.android.server.pm.UserManagerService;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultBrowserProvider;
import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultDialerProvider;
import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultHomeProvider;
import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
import com.android.server.pm.permission.PermissionsState.PermissionState;
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.Collection;
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;
import java.util.function.Consumer;

/**
 * Manages all permissions and handles permissions related tasks.
 */
public class PermissionManagerService extends IPermissionManager.Stub {
    private static final String TAG = "PackageManager";

    /** Permission grant: not grant the permission. */
    private static final int GRANT_DENIED = 1;
    /** Permission grant: grant the permission as an install permission. */
    private static final int GRANT_INSTALL = 2;
    /** Permission grant: grant the permission as a runtime one. */
    private static final int GRANT_RUNTIME = 3;
    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
    private static final int GRANT_UPGRADE = 4;

    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;

    /** 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);
    }

    /** Lock to protect internal data access */
    private final Object mLock;

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

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

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

    /** Map of OneTimePermissionUserManagers keyed by userId */
    private final SparseArray<OneTimePermissionUserManager> mOneTimePermissionUserManagers =
            new SparseArray<>();

    /** Default permission policy to provide proper behaviour out-of-the-box */
    private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;

    /** App ops manager */
    private final AppOpsManager mAppOpsManager;

    /**
     * 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. */
    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")
    private final PermissionSettings mSettings;

    /** Injector that can be used to facilitate testing. */
    private final Injector mInjector;

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

    @GuardedBy("mLock")
    private boolean mSystemReady;

    @GuardedBy("mLock")
    private PermissionPolicyInternal mPermissionPolicyInternal;

    /**
     * For each foreground/background permission the mapping:
     * Background permission -> foreground permissions
     */
    @GuardedBy("mLock")
    private ArrayMap<String, List<String>> mBackgroundPermissions;

    /**
     * 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();

    /** Listeners for permission state (granting and flags) changes */
    @GuardedBy("mLock")
    final private ArrayList<OnRuntimePermissionStateChangedListener>
            mRuntimePermissionStateChangedListeners = new ArrayList<>();

    @GuardedBy("mLock")
    private CheckPermissionDelegate mCheckPermissionDelegate;

    @GuardedBy("mLock")
    private final OnPermissionChangeListeners mOnPermissionChangeListeners;

    @GuardedBy("mLock")
    private DefaultBrowserProvider mDefaultBrowserProvider;

    @GuardedBy("mLock")
    private DefaultDialerProvider mDefaultDialerProvider;

    @GuardedBy("mLock")
    private DefaultHomeProvider mDefaultHomeProvider;

    // 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 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) {
            mOnPermissionChangeListeners.onPermissionsChanged(uid);

            // Critical; after this call the application should never have the permission
            mPackageManagerInt.writeSettings(false);
            final int appId = UserHandle.getAppId(uid);
            if (reason == null) {
                mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED));
            } else {
                mHandler.post(() -> killUid(appId, userId, reason));
            }
        }
        @Override
        public void onInstallPermissionRevoked() {
            mPackageManagerInt.writeSettings(true);
        }
        @Override
        public void onPermissionUpdated(int[] userIds, boolean sync) {
            mPackageManagerInt.writePermissionSettings(userIds, !sync);
        }
        @Override
        public void onInstallPermissionUpdated() {
            mPackageManagerInt.writeSettings(true);
        }
        @Override
        public void onPermissionRemoved() {
            mPackageManagerInt.writeSettings(false);
        }
        public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync,
                int uid) {
            onPermissionUpdated(updatedUserIds, sync);
            for (int i = 0; i < updatedUserIds.length; i++) {
                int userUid = UserHandle.getUid(updatedUserIds[i], UserHandle.getAppId(uid));
                mOnPermissionChangeListeners.onPermissionsChanged(userUid);
            }
        }
        public void onInstallPermissionUpdatedNotifyListener(int uid) {
            onInstallPermissionUpdated();
            mOnPermissionChangeListeners.onPermissionsChanged(uid);
        }
    };

    PermissionManagerService(Context context,
            @NonNull Object externalLock) {
        this(context, externalLock, new Injector(context));
    }

    @VisibleForTesting
    PermissionManagerService(Context context, @NonNull Object externalLock,
            @NonNull Injector injector) {
        mInjector = injector;
        // The package info cache is the cache for package and permission information.
        mInjector.invalidatePackageInfoCache();
        mInjector.disablePermissionCache();
        mInjector.disablePackageNamePermissionCache();

        mContext = context;
        mLock = externalLock;
        mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
        mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
        mSettings = new PermissionSettings(mLock);
        mAppOpsManager = context.getSystemService(AppOpsManager.class);

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

        mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
                context, mHandlerThread.getLooper());
        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);
                BasePermission bp = mSettings.getPermissionLocked(perm.name);
                if (bp == null) {
                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
                    mSettings.putPermissionLocked(perm.name, bp);
                }
                if (perm.gids != null) {
                    bp.setGids(perm.gids, perm.perUser);
                }
            }
        }

        PermissionManagerServiceInternalImpl localService =
                new PermissionManagerServiceInternalImpl();
        LocalServices.addService(PermissionManagerServiceInternal.class, localService);
        LocalServices.addService(PermissionManagerInternal.class, localService);
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) {
            return;
        }

        mContext.getSystemService(PermissionControllerManager.class).dump(fd, args);
    }

    /**
     * Creates and returns an initialized, internal service for use by other components.
     * <p>
     * The object returned is identical to the one returned by the LocalServices class using:
     * {@code LocalServices.getService(PermissionManagerServiceInternal.class);}
     * <p>
     * NOTE: The external lock is temporary and should be removed. This needs to be a
     * lock created by the permission manager itself.
     */
    public static PermissionManagerServiceInternal create(Context context,
            @NonNull Object externalLock) {
        final PermissionManagerServiceInternal permMgrInt =
                LocalServices.getService(PermissionManagerServiceInternal.class);
        if (permMgrInt != null) {
            return permMgrInt;
        }
        PermissionManagerService permissionService =
                (PermissionManagerService) ServiceManager.getService("permissionmgr");
        if (permissionService == null) {
            permissionService =
                    new PermissionManagerService(context, externalLock);
            ServiceManager.addService("permissionmgr", permissionService);
        }
        return LocalServices.getService(PermissionManagerServiceInternal.class);
    }

    /**
     * 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.
     */
    public 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);
        }
    }

    @Nullable
    BasePermission getPermission(String permName) {
        synchronized (mLock) {
            return mSettings.getPermissionLocked(permName);
        }
    }

    @Override
    public String[] getAppOpPermissionPackages(String permName) {
        return getAppOpPermissionPackagesInternal(permName, getCallingUid());
    }

    private String[] getAppOpPermissionPackagesInternal(String permName, int callingUid) {
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            return null;
        }
        synchronized (mLock) {
            final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
            if (pkgs == null) {
                return null;
            }
            return pkgs.toArray(new String[pkgs.size()]);
        }
    }

    @Override
    @NonNull
    public ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(
            @PermissionGroupInfoFlags int flags) {
        final int callingUid = getCallingUid();
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            return ParceledListSlice.emptyList();
        }
        synchronized (mLock) {
            final int n = mSettings.mPermissionGroups.size();
            final ArrayList<PermissionGroupInfo> out = new ArrayList<>(n);
            for (ParsedPermissionGroup pg : mSettings.mPermissionGroups.values()) {
                out.add(PackageInfoUtils.generatePermissionGroupInfo(pg, flags));
            }
            return new ParceledListSlice<>(out);
        }
    }


    @Override
    @Nullable
    public PermissionGroupInfo getPermissionGroupInfo(String groupName,
            @PermissionGroupInfoFlags int flags) {
        final int callingUid = getCallingUid();
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            return null;
        }
        synchronized (mLock) {
            return PackageInfoUtils.generatePermissionGroupInfo(
                    mSettings.mPermissionGroups.get(groupName), flags);
        }
    }


    @Override
    @Nullable
    public PermissionInfo getPermissionInfo(String permName, String packageName,
            @PermissionInfoFlags int flags) {
        final int callingUid = getCallingUid();
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            return null;
        }
        synchronized (mLock) {
            final BasePermission bp = mSettings.getPermissionLocked(permName);
            if (bp == null) {
                return null;
            }
            final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
                    bp.getProtectionLevel(), packageName, callingUid);
            return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
        }
    }

    @Override
    @Nullable
    public ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
            @PermissionInfoFlags int flags) {
        final int callingUid = getCallingUid();
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            return null;
        }
        synchronized (mLock) {
            if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
                return null;
            }
            final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
            for (BasePermission bp : mSettings.mPermissions.values()) {
                final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
                if (pi != null) {
                    out.add(pi);
                }
            }
            return new ParceledListSlice<>(out);
        }
    }

    @Override
    public boolean addPermission(PermissionInfo info, boolean async) {
        final int callingUid = 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 BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
        final boolean added;
        final boolean changed;
        synchronized (mLock) {
            BasePermission bp = mSettings.getPermissionLocked(info.name);
            added = bp == null;
            int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
            if (added) {
                enforcePermissionCapLocked(info, tree);
                bp = new BasePermission(info.name, tree.getSourcePackageName(),
                        BasePermission.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) {
                mSettings.putPermissionLocked(info.name, bp);
            }
        }
        if (changed) {
            mPackageManagerInt.writeSettings(async);
        }
        return added;
    }

    @Override
    public void removePermission(String permName) {
        final int callingUid = getCallingUid();
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            throw new SecurityException("Instant applications don't have access to this method");
        }
        final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
        synchronized (mLock) {
            final BasePermission bp = mSettings.getPermissionLocked(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);
            }
            mSettings.removePermissionLocked(permName);
            mPackageManagerInt.writeSettings(false);
        }
    }

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

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

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

        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        if (pkg == null) {
            return 0;
        }
        final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
                pkg.getPackageName());
        if (ps == null) {
            return 0;
        }
        synchronized (mLock) {
            if (mSettings.getPermissionLocked(permName) == null) {
                return 0;
            }
        }
        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
            return 0;
        }
        PermissionsState permissionsState = ps.getPermissionsState();
        return permissionsState.getPermissionFlags(permName, userId);
    }

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

        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
            long callingIdentity = Binder.clearCallingIdentity();
            try {
                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;
                }
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
            }
        }

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

    private void updatePermissionFlagsInternal(String permName, String packageName, int flagMask,
            int flagValues, int callingUid, int userId, boolean overridePolicy,
            PermissionCallback callback) {
        if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
                && ApplicationPackageManager.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
                false, // requirePermissionWhenSameUser
                "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 &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
            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);
        final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
                packageName);
        if (pkg == null || ps == null) {
            Log.e(TAG, "Unknown package: " + packageName);
            return;
        }
        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
            throw new IllegalArgumentException("Unknown package: " + packageName);
        }

        final BasePermission bp;
        synchronized (mLock) {
            bp = mSettings.getPermissionLocked(permName);
        }
        if (bp == null) {
            throw new IllegalArgumentException("Unknown permission: " + permName);
        }

        final PermissionsState permissionsState = ps.getPermissionsState();
        final boolean hadState =
                permissionsState.getRuntimePermissionState(permName, userId) != null;
        if (!hadState) {
            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;
                    }
                }
            }
            if (!isRequested) {
                Log.e(TAG, "Permission " + permName + " isn't requested by package " + packageName);
                return;
            }
        }
        final boolean permissionUpdated =
                permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
        if (permissionUpdated && bp.isRuntime()) {
            notifyRuntimePermissionStateChanged(packageName, userId);
        }
        if (permissionUpdated && callback != null) {
            // Install and runtime permissions are stored in different places,
            // so figure out what permission changed and persist the change.
            if (permissionsState.getInstallPermissionState(permName) != null) {
                int userUid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
                callback.onInstallPermissionUpdatedNotifyListener(userUid);
            } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
                    || hadState) {
                callback.onPermissionUpdatedNotifyListener(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 = getCallingUid();
        if (!mUserManagerInt.exists(userId)) {
            return;
        }

        enforceGrantRevokeRuntimePermissionPermissions(
                "updatePermissionFlagsForAllApps");
        enforceCrossUserPermission(callingUid, userId,
                true,  // requireFullPermission
                true,  // checkShell
                false, // requirePermissionWhenSameUser
                "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 -> {
            final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
                    pkg.getPackageName());
            if (ps == null) {
                return;
            }
            final PermissionsState permissionsState = ps.getPermissionsState();
            changed[0] |= permissionsState.updatePermissionFlagsForAllPermissions(
                    userId, effectiveFlagMask, effectiveFlagValues);
            mOnPermissionChangeListeners.onPermissionsChanged(pkg.getUid());
        });

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

    @Override
    public int checkPermission(String permName, String pkgName, int userId) {
        // Not using Objects.requireNonNull() here for compatibility reasons.
        if (permName == null || pkgName == null) {
            return PackageManager.PERMISSION_DENIED;
        }
        if (!mUserManagerInt.exists(userId)) {
            return PackageManager.PERMISSION_DENIED;
        }

        final CheckPermissionDelegate checkPermissionDelegate;
        synchronized (mLock) {
            checkPermissionDelegate = mCheckPermissionDelegate;
        }
        if (checkPermissionDelegate == null) {
            return checkPermissionImpl(permName, pkgName, userId);
        }
        return checkPermissionDelegate.checkPermission(permName, pkgName, userId,
                this::checkPermissionImpl);
    }

    private int checkPermissionImpl(String permName, String pkgName, int userId) {
        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 = getCallingUid();
        if (isPackageExplicit || pkg.getSharedUserId() == null) {
            if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
                return PackageManager.PERMISSION_DENIED;
            }
        } else {
            if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
                return PackageManager.PERMISSION_DENIED;
            }
        }

        final int uid = UserHandle.getUid(userId, pkg.getUid());
        final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
                pkg.getPackageName());
        if (ps == null) {
            return PackageManager.PERMISSION_DENIED;
        }
        final PermissionsState permissionsState = ps.getPermissionsState();

        if (checkSinglePermissionInternal(uid, permissionsState, permissionName)) {
            return PackageManager.PERMISSION_GRANTED;
        }

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

        return PackageManager.PERMISSION_DENIED;
    }

    private boolean checkSinglePermissionInternal(int uid,
            @NonNull PermissionsState permissionsState, @NonNull String permissionName) {
        if (!permissionsState.hasPermission(permissionName, UserHandle.getUserId(uid))) {
            return false;
        }

        if (mPackageManagerInt.getInstantAppPackageName(uid) != null) {
            return mSettings.isPermissionInstant(permissionName);
        }

        return true;
    }

    @Override
    public int checkUidPermission(String permName, int uid) {
        // Not using Objects.requireNonNull() here for compatibility reasons.
        if (permName == null) {
            return PackageManager.PERMISSION_DENIED;
        }
        final int userId = UserHandle.getUserId(uid);
        if (!mUserManagerInt.exists(userId)) {
            return PackageManager.PERMISSION_DENIED;
        }

        final CheckPermissionDelegate checkPermissionDelegate;
        synchronized (mLock) {
            checkPermissionDelegate = mCheckPermissionDelegate;
        }
        if (checkPermissionDelegate == null)  {
            return checkUidPermissionImpl(permName, uid);
        }
        return checkPermissionDelegate.checkUidPermission(permName, uid,
                this::checkUidPermissionImpl);
    }

    private int checkUidPermissionImpl(String permName, int uid) {
        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);
        }

        if (checkSingleUidPermissionInternal(uid, permissionName)) {
            return PackageManager.PERMISSION_GRANTED;
        }

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

        return PackageManager.PERMISSION_DENIED;
    }

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

    @Override
    public int checkDeviceIdentifierAccess(@Nullable String packageName, @Nullable String message,
            @Nullable String callingFeatureId, int pid, int uid) {
        // If the check is being requested by an app then only allow the app to query its own
        // access status.
        int callingUid = mInjector.getCallingUid();
        int callingPid = mInjector.getCallingPid();
        if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID && (callingUid != uid
                || callingPid != pid)) {
            String response = String.format(
                    "Calling uid %d, pid %d cannot check device identifier access for package %s "
                            + "(uid=%d, pid=%d)",
                    callingUid, callingPid, packageName, uid, pid);
            Log.w(TAG, response);
            throw new SecurityException(response);
        }
        // Allow system and root access to the device identifiers.
        final int appId = UserHandle.getAppId(uid);
        if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
            return PackageManager.PERMISSION_GRANTED;
        }
        // Allow access to packages that have the READ_PRIVILEGED_PHONE_STATE permission.
        if (mInjector.checkPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid,
                uid) == PackageManager.PERMISSION_GRANTED) {
            return PackageManager.PERMISSION_GRANTED;
        }
        // If the calling package is not null then perform the appop and device / profile owner
        // check.
        if (packageName != null) {
            // Allow access to a package that has been granted the READ_DEVICE_IDENTIFIERS appop.
            long token = mInjector.clearCallingIdentity();
            AppOpsManager appOpsManager = (AppOpsManager) mInjector.getSystemService(
                    Context.APP_OPS_SERVICE);
            try {
                if (appOpsManager.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, uid,
                        packageName, callingFeatureId, message) == AppOpsManager.MODE_ALLOWED) {
                    return PackageManager.PERMISSION_GRANTED;
                }
            } finally {
                mInjector.restoreCallingIdentity(token);
            }
            // Check if the calling packages meets the device / profile owner requirements for
            // identifier access.
            DevicePolicyManager devicePolicyManager =
                    (DevicePolicyManager) mInjector.getSystemService(Context.DEVICE_POLICY_SERVICE);
            if (devicePolicyManager != null && devicePolicyManager.hasDeviceIdentifierAccess(
                    packageName, pid, uid)) {
                return PackageManager.PERMISSION_GRANTED;
            }
        }
        return PackageManager.PERMISSION_DENIED;
    }

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

        synchronized (mLock) {
            mOnPermissionChangeListeners.addListenerLocked(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");
        }
        synchronized (mLock) {
            mOnPermissionChangeListeners.removeListenerLocked(listener);
        }
    }

    @Override
    @Nullable public List<String> getWhitelistedRestrictedPermissions(@NonNull String packageName,
            @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,
                    "getWhitelistedRestrictedPermissions for user " + userId);
        }

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

        final int callingUid = Binder.getCallingUid();
        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
            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 whitelist 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 whitelist"
                        + " requires being installer on record or "
                        + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
            }
        }

        final long identity = Binder.clearCallingIdentity();
        try {
            final PermissionsState permissionsState =
                    PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
            if (permissionsState == null) {
                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> whitelistedPermissions = null;

            final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
            for (int i = 0; i < permissionCount; i++) {
                final String permissionName = pkg.getRequestedPermissions().get(i);
                final int currentFlags =
                        permissionsState.getPermissionFlags(permissionName, userId);
                if ((currentFlags & queryFlags) != 0) {
                    if (whitelistedPermissions == null) {
                        whitelistedPermissions = new ArrayList<>();
                    }
                    whitelistedPermissions.add(permissionName);
                }
            }

            return whitelistedPermissions;
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

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

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

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

    private boolean checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(
            @NonNull String permName) {
        synchronized (mLock) {
            final BasePermission bp = mSettings.getPermissionLocked(permName);
            if (bp == null) {
                Slog.w(TAG, "No such permissions: " + permName);
                return false;
            }
            if (bp.isHardOrSoftRestricted() && bp.isImmutablyRestricted()
                    && mContext.checkCallingOrSelfPermission(
                    Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
                    != PackageManager.PERMISSION_GRANTED) {
                throw new SecurityException("Cannot modify whitelisting of an immutably "
                        + "restricted permission: " + permName);
            }
            return true;
        }
    }

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

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

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

    private boolean setWhitelistedRestrictedPermissionsInternal(@NonNull String packageName,
            @Nullable List<String> permissions, @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,
                    "setWhitelistedRestrictedPermissions for user " + userId);
        }

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

        final int callingUid = Binder.getCallingUid();
        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
            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 whitelist requires "
                    + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
        }

        if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
            if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
                throw new SecurityException("Modifying upgrade whitelist requires"
                        + " being installer on record or "
                        + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
            }
            final List<String> whitelistedPermissions =
                    getWhitelistedRestrictedPermissions(pkg.getPackageName(), flags, userId);
            if (permissions == null || permissions.isEmpty()) {
                if (whitelistedPermissions == null || whitelistedPermissions.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 ((whitelistedPermissions == null
                            || !whitelistedPermissions.contains(permissions.get(i)))
                            && !isCallerPrivileged) {
                        throw new SecurityException("Adding to upgrade whitelist requires"
                                + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
                    }
                }
            }

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

        final long identity = Binder.clearCallingIdentity();
        try {
            setWhitelistedRestrictedPermissionsForUsers(pkg, new int[]{ userId }, permissions,
                    Process.myUid(), flags, mDefaultPermissionCallback);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }

        return true;
    }

    @Override
    public boolean setAutoRevokeWhitelisted(
            @NonNull String packageName, boolean whitelisted, int userId) {
        Objects.requireNonNull(packageName);

        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        final int callingUid = Binder.getCallingUid();
        final int packageUid = UserHandle.getUid(userId, pkg.getUid());

        if (!checkAutoRevokeAccess(pkg, callingUid)) {
            return false;
        }

        if (mAppOpsManager
                .checkOpNoThrow(AppOpsManager.OP_AUTO_REVOKE_MANAGED_BY_INSTALLER,
                        packageUid, packageName)
                != MODE_ALLOWED) {
            // Whitelist user set - don't override
            return false;
        }

        final long identity = Binder.clearCallingIdentity();
        try {
            mAppOpsManager.setMode(AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
                    packageUid, packageName,
                    whitelisted ? MODE_IGNORED : MODE_ALLOWED);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
        return true;
    }

    private boolean checkAutoRevokeAccess(AndroidPackage pkg, int callingUid) {
        if (pkg == null) {
            return false;
        }

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

        if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
            throw new SecurityException("Caller must either hold "
                    + Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS
                    + " or be the installer on record");
        }
        return true;
    }

    @Override
    public boolean isAutoRevokeWhitelisted(@NonNull String packageName, int userId) {
        Objects.requireNonNull(packageName);

        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        final int callingUid = Binder.getCallingUid();
        final int packageUid = UserHandle.getUid(userId, pkg.getUid());

        if (!checkAutoRevokeAccess(pkg, callingUid)) {
            return false;
        }

        final long identity = Binder.clearCallingIdentity();
        try {
            return mAppOpsManager.checkOpNoThrow(
                    AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, packageUid, packageName)
                    == MODE_IGNORED;
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

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

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

    // TODO swap permission name and package name
    private void grantRuntimePermissionInternal(String permName, String packageName,
            boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
        if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
                && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
            Log.i(TAG, "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
                false, // requirePermissionWhenSameUser
                "grantRuntimePermission");

        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
                packageName);
        if (pkg == null || ps == null) {
            Log.e(TAG, "Unknown package: " + packageName);
            return;
        }
        final BasePermission bp;
        synchronized (mLock) {
            bp = mSettings.getPermissionLocked(permName);
        }
        if (bp == null) {
            throw new IllegalArgumentException("Unknown permission: " + permName);
        }
        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
            throw new IllegalArgumentException("Unknown package: " + packageName);
        }

        bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);

        // 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 uid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));

        final PermissionsState permissionsState = ps.getPermissionsState();

        final int flags = permissionsState.getPermissionFlags(permName, userId);
        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() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
                pkg.toAppInfoWithoutState(), pkg, UserHandle.of(userId), permName)
                .mayGrantPermission()) {
            Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
                    + packageName);
            return;
        }

        if (bp.isDevelopment()) {
            // Development permissions must be handled specially, since they are not
            // normal runtime permissions.  For now they apply to all users.
            if (permissionsState.grantInstallPermission(bp)
                    != PERMISSION_OPERATION_FAILURE) {
                if (callback != null) {
                    callback.onInstallPermissionGranted();
                }
            }
            return;
        }

        if (ps.getInstantApp(userId) && !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;
        }

        final int result = permissionsState.grantRuntimePermission(bp, userId);
        switch (result) {
            case PERMISSION_OPERATION_FAILURE: {
                return;
            }

            case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
                if (callback != null) {
                    callback.onGidsChanged(UserHandle.getAppId(pkg.getUid()), userId);
                }
            }
            break;
        }

        if (bp.isRuntime()) {
            logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
        }

        if (callback != null) {
            callback.onPermissionGranted(uid, userId);
        }

        if (bp.isRuntime()) {
            notifyRuntimePermissionStateChanged(packageName, userId);
        }

        // Only need to do this if user is initialized. Otherwise it's a new user
        // and there are no processes running as the user yet and there's no need
        // to make an expensive call to remount processes for the changed permissions.
        if (READ_EXTERNAL_STORAGE.equals(permName)
                || WRITE_EXTERNAL_STORAGE.equals(permName)) {
            final long token = Binder.clearCallingIdentity();
            try {
                if (mUserManagerInt.isUserInitialized(userId)) {
                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
                            StorageManagerInternal.class);
                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
                }
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

    }

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

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

    // TODO swap permission name and package name
    private void revokeRuntimePermissionInternal(String permName, String packageName,
            boolean overridePolicy, int callingUid, final int userId, String reason,
            PermissionCallback callback) {
        if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
                && ApplicationPackageManager.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
                false, // requirePermissionWhenSameUser
                "revokeRuntimePermission");

        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
                packageName);
        if (pkg == null || ps == null) {
            Log.e(TAG, "Unknown package: " + packageName);
            return;
        }
        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
            throw new IllegalArgumentException("Unknown package: " + packageName);
        }
        final BasePermission bp = mSettings.getPermissionLocked(permName);
        if (bp == null) {
            throw new IllegalArgumentException("Unknown permission: " + permName);
        }

        bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);

        // 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 PermissionsState permissionsState = ps.getPermissionsState();

        final int flags = permissionsState.getPermissionFlags(permName, userId);
        // 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);
        }

        if (bp.isDevelopment()) {
            // Development permissions must be handled specially, since they are not
            // normal runtime permissions.  For now they apply to all users.
            if (permissionsState.revokeInstallPermission(bp)
                    != PERMISSION_OPERATION_FAILURE) {
                if (callback != null) {
                    mDefaultPermissionCallback.onInstallPermissionRevoked();
                }
            }
            return;
        }

        // Permission is already revoked, no need to do anything.
        if (!permissionsState.hasRuntimePermission(permName, userId)) {
            return;
        }

        if (permissionsState.revokeRuntimePermission(bp, userId)
                == PERMISSION_OPERATION_FAILURE) {
            return;
        }

        if (bp.isRuntime()) {
            logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
        }

        if (callback != null) {
            callback.onPermissionRevoked(UserHandle.getUid(userId,
                    UserHandle.getAppId(pkg.getUid())), userId, reason);
        }

        if (bp.isRuntime()) {
            notifyRuntimePermissionStateChanged(packageName, userId);
        }
    }

    @Override
    public void resetRuntimePermissions() {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
                "revokeRuntimePermission");

        final int callingUid = Binder.getCallingUid();
        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                    "resetRuntimePermissions");
        }

        updateAllPermissions(
                StorageManager.UUID_PRIVATE_INTERNAL, false, mDefaultPermissionCallback);
        for (final int userId : UserManagerService.getInstance().getUserIds()) {
            mPackageManagerInt.forEachPackage(
                    (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId));
        }
    }

    /**
     * Reverts user permission state changes (permissions and flags).
     *
     * @param pkg The package for which to reset.
     * @param userId The device user for which to do a reset.
     */
    @GuardedBy("mLock")
    private void resetRuntimePermissionsInternal(final AndroidPackage pkg,
            final int userId) {
        final String packageName = pkg.getPackageName();

        // 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;

        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
                | FLAG_PERMISSION_POLICY_FIXED;

        // Delay and combine non-async permission callbacks
        final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
        final boolean[] permissionRemoved = new boolean[1];
        final ArraySet<Long> revokedPermissions = new ArraySet<>();
        final IntArray syncUpdatedUsers = new IntArray(permissionCount);
        final IntArray asyncUpdatedUsers = new IntArray(permissionCount);

        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) {
                revokedPermissions.add(IntPair.of(uid, userId));

                syncUpdatedUsers.add(userId);
            }

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

            public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
                for (int userId : updatedUserIds) {
                    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();
            }

            public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds,
                    boolean sync, int uid) {
                onPermissionUpdated(updatedUserIds, sync);
                mOnPermissionChangeListeners.onPermissionsChanged(uid);
            }

            public void onInstallPermissionUpdatedNotifyListener(int uid) {
                mDefaultPermissionCallback.onInstallPermissionUpdatedNotifyListener(uid);
            }
        };

        for (int i = 0; i < permissionCount; i++) {
            final String permName = pkg.getRequestedPermissions().get(i);
            final BasePermission bp;
            synchronized (mLock) {
                bp = mSettings.getPermissionLocked(permName);
            }
            if (bp == null) {
                continue;
            }

            if (bp.isRemoved()) {
                continue;
            }

            // 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(permName, packageName, 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 && bp.isRuntime())
                    ? FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKED_COMPAT
                    : 0;

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

            // Below is only runtime permission handling.
            if (!bp.isRuntime()) {
                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(permName, packageName, false,
                        Process.SYSTEM_UID, userId, delayingPermCallback);
            // If permission review is enabled the permissions for a legacy apps
            // are represented as constantly granted runtime ones, so don't revoke.
            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
                // Otherwise, reset the permission.
                revokeRuntimePermissionInternal(permName, packageName, false, Process.SYSTEM_UID,
                        userId, null, 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(syncUpdatedUsers.toArray(), false);
        mPackageManagerInt.writePermissionSettings(asyncUpdatedUsers.toArray(), true);
    }

    @Override
    public String getDefaultBrowser(int userId) {
        final int callingUid = Binder.getCallingUid();
        if (UserHandle.getUserId(callingUid) != userId) {
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
        }
        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
            return null;
        }
        DefaultBrowserProvider provider;
        synchronized (mLock) {
            provider = mDefaultBrowserProvider;
        }
        return provider != null ? provider.getDefaultBrowser(userId) : null;
    }

    @Override
    public boolean setDefaultBrowser(String packageName, int userId) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
        if (UserHandle.getCallingUserId() != userId) {
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
        }
        return setDefaultBrowserInternal(packageName, false, true, userId);
    }

    private boolean setDefaultBrowserInternal(String packageName, boolean async,
            boolean doGrant, int userId) {
        if (userId == UserHandle.USER_ALL) {
            return false;
        }
        DefaultBrowserProvider provider;
        synchronized (mLock) {
            provider = mDefaultBrowserProvider;
        }
        if (provider == null) {
            return false;
        }
        if (async) {
            provider.setDefaultBrowserAsync(packageName, userId);
        } else {
            if (!provider.setDefaultBrowser(packageName, userId)) {
                return false;
            }
        }
        if (doGrant && packageName != null) {
            synchronized (mLock) {
                mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
                        userId);
            }
        }
        return true;
    }

    @Override
    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
        final int callingUid = Binder.getCallingUid();
        PackageManagerServiceUtils
                .enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps", callingUid);
        synchronized (mLock) {
            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
                    .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId));
        }
    }

    @Override
    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
        final int callingUid = Binder.getCallingUid();
        PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
                "grantDefaultPermissionsToEnabledImsServices", callingUid);
        synchronized (mLock) {
            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
                    .grantDefaultPermissionsToEnabledImsServices(packageNames, userId));
        }
    }

    @Override
    public void grantDefaultPermissionsToEnabledTelephonyDataServices(
            String[] packageNames, int userId) {
        final int callingUid = Binder.getCallingUid();
        PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
                "grantDefaultPermissionsToEnabledTelephonyDataServices", callingUid);
        synchronized (mLock) {
            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
                    .grantDefaultPermissionsToEnabledTelephonyDataServices(
                            packageNames, userId));
        }
    }

    @Override
    public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
            String[] packageNames, int userId) {
        final int callingUid = Binder.getCallingUid();
        PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
                "revokeDefaultPermissionsFromDisabledTelephonyDataServices", callingUid);
        synchronized (mLock) {
            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
                    .revokeDefaultPermissionsFromDisabledTelephonyDataServices(
                            packageNames, userId));
        }
    }

    @Override
    public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
        final int callingUid = Binder.getCallingUid();
        PackageManagerServiceUtils
                .enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp", callingUid);
        synchronized (mLock) {
            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
                    .grantDefaultPermissionsToActiveLuiApp(packageName, userId));
        }
    }

    @Override
    public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
        final int callingUid = Binder.getCallingUid();
        PackageManagerServiceUtils
                .enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps", callingUid);
        synchronized (mLock) {
            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
                    .revokeDefaultPermissionsFromLuiApps(packageNames, userId));
        }
    }

    @Override
    public void setPermissionEnforced(String permName, boolean enforced) {
        // TODO: Now that we no longer change GID for storage, this should to away.
        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
                "setPermissionEnforced");
        if (READ_EXTERNAL_STORAGE.equals(permName)) {
            mPackageManagerInt.setReadExternalStorageEnforced(enforced);
            // kill any non-foreground processes so we restart them and
            // grant/revoke the GID.
            final IActivityManager am = ActivityManager.getService();
            if (am != null) {
                final long token = Binder.clearCallingIdentity();
                try {
                    am.killProcessesBelowForeground("setPermissionEnforcement");
                } catch (RemoteException e) {
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
            }
        } else {
            throw new IllegalArgumentException("No selective enforcement for " + permName);
        }
    }

    /** @deprecated */
    @Override
    @Deprecated
    public boolean isPermissionEnforced(String permName) {
        // allow instant applications
        return true;
    }

    /**
     * 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 permName,
            String packageName, 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(permName, packageName, userId)
                == PackageManager.PERMISSION_GRANTED) {
            return false;
        }

        final int flags;

        final long identity = Binder.clearCallingIdentity();
        try {
            flags = getPermissionFlagsInternal(permName, packageName, 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;
        }

        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 permName, String packageName, int userId) {
        if (UserHandle.getCallingUserId() != userId) {
            mContext.enforceCallingPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                    "isPermissionRevokedByPolicy for user " + userId);
        }

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

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

        final long identity = Binder.clearCallingIdentity();
        try {
            final int flags = getPermissionFlagsInternal(permName, packageName, 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 user The user the data should be extracted for
     *
     * @return The state as a xml file
     */
    private @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
        CompletableFuture<byte[]> backup = new CompletableFuture<>();
        mPermissionControllerManager.getRuntimePermissionBackup(user, mContext.getMainExecutor(),
                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, 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 user The user the data should be restored for
     */
    private void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
        synchronized (mLock) {
            mHasNoDelayedPermBackup.delete(user.getIdentifier());
            mPermissionControllerManager.stageAndApplyRuntimePermissionsBackup(backup, user);
        }
    }

    /**
     * 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 user The user the package is installed for
     *
     * @see #restoreRuntimePermissions
     */
    private void restoreDelayedRuntimePermissions(@NonNull String packageName,
            @NonNull UserHandle user) {
        synchronized (mLock) {
            if (mHasNoDelayedPermBackup.get(user.getIdentifier(), false)) {
                return;
            }

            mPermissionControllerManager.applyStagedRuntimePermissionBackup(packageName, user,
                    mContext.getMainExecutor(), (hasMoreBackup) -> {
                        if (hasMoreBackup) {
                            return;
                        }

                        synchronized (mLock) {
                            mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
                        }
                    });
        }
    }

    private void addOnRuntimePermissionStateChangedListener(@NonNull
            OnRuntimePermissionStateChangedListener listener) {
        synchronized (mLock) {
            mRuntimePermissionStateChangedListeners.add(listener);
        }
    }

    private void removeOnRuntimePermissionStateChangedListener(@NonNull
            OnRuntimePermissionStateChangedListener listener) {
        synchronized (mLock) {
            mRuntimePermissionStateChangedListeners.remove(listener);
        }
    }

    private void notifyRuntimePermissionStateChanged(@NonNull String packageName,
            @UserIdInt int userId) {
        FgThread.getHandler().sendMessage(PooledLambda.obtainMessage
                (PermissionManagerService::doNotifyRuntimePermissionStateChanged,
                        PermissionManagerService.this, packageName, userId));
    }

    private void doNotifyRuntimePermissionStateChanged(@NonNull String packageName,
            @UserIdInt int userId) {
        final ArrayList<OnRuntimePermissionStateChangedListener> listeners;
        synchronized (mLock) {
            if (mRuntimePermissionStateChangedListeners.isEmpty()) {
                return;
            }
            listeners = new ArrayList<>(mRuntimePermissionStateChangedListeners);
        }
        final int listenerCount = listeners.size();
        for (int i = 0; i < listenerCount; i++) {
            listeners.get(i).onRuntimePermissionStateChanged(packageName, userId);
        }
    }

    private int adjustPermissionProtectionFlagsLocked(
            int protectionLevel, String packageName, int uid) {
        // Signature permission flags area always reported
        final int protectionLevelMasked = protectionLevel
                & (PermissionInfo.PROTECTION_NORMAL
                | PermissionInfo.PROTECTION_DANGEROUS
                | PermissionInfo.PROTECTION_SIGNATURE);
        if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
            return protectionLevel;
        }
        // System sees all flags.
        final int appId = UserHandle.getAppId(uid);
        if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
                || appId == Process.SHELL_UID) {
            return protectionLevel;
        }
        // Normalize package name to handle renamed packages and static libs
        final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
        if (pkg == null) {
            return protectionLevel;
        }
        if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
            return protectionLevelMasked;
        }
        // Apps that target O see flags for all protection levels.
        final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
                pkg.getPackageName());
        if (ps == null) {
            return protectionLevel;
        }
        if (ps.getAppId() != appId) {
            return protectionLevel;
        }
        return protectionLevel;
    }

    /**
     * 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
     * @param allPackageNames All package names
     * @param permissionCallback Callback for permission changed
     */
    private void revokeRuntimePermissionsIfGroupChanged(
            @NonNull AndroidPackage newPackage,
            @NonNull AndroidPackage oldPackage,
            @NonNull ArrayList<String> allPackageNames,
            @NonNull PermissionCallback permissionCallback) {
        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 = newPermission.getProtection();

            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();
                    final int numUserIds = userIds.length;
                    for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
                        final int userId = userIds[userIdNum];

                        final int numPackages = allPackageNames.size();
                        for (int packageNum = 0; packageNum < numPackages; packageNum++) {
                            final String packageName = allPackageNames.get(packageNum);
                            final int permissionState = checkPermission(permissionName, packageName,
                                    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(permissionName, packageName,
                                            false, callingUid, userId, null, permissionCallback);
                                } catch (IllegalArgumentException e) {
                                    Slog.e(TAG, "Could not revoke " + permissionName + " from "
                                            + packageName, e);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private void addAllPermissions(AndroidPackage pkg, boolean chatty) {
        final int N = ArrayUtils.size(pkg.getPermissions());
        for (int i=0; i<N; i++) {
            ParsedPermission p = pkg.getPermissions().get(i);

            // Assume by default that we did not install this permission into the system.
            p.setFlags(p.getFlags() & ~PermissionInfo.FLAG_INSTALLED);

            synchronized (PermissionManagerService.this.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) {
                    p.setParsedPermissionGroup(mSettings.mPermissionGroups.get(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());
                    }
                }

                if (p.isTree()) {
                    final BasePermission bp = BasePermission.createOrUpdate(
                            mPackageManagerInt,
                            mSettings.getPermissionTreeLocked(p.getName()), p, pkg,
                            mSettings.getAllPermissionTreesLocked(), chatty);
                    mSettings.putPermissionTreeLocked(p.getName(), bp);
                } else {
                    final BasePermission bp = BasePermission.createOrUpdate(
                            mPackageManagerInt,
                            mSettings.getPermissionLocked(p.getName()),
                            p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
                    mSettings.putPermissionLocked(p.getName(), bp);
                }
            }
        }
    }

    private void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) {
        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 = mSettings.mPermissionGroups.get(pg.getName());
            final String curPackageName = (cur == null) ? null : cur.getPackageName();
            final boolean isPackageUpdate = pg.getPackageName().equals(curPackageName);
            if (cur == null || isPackageUpdate) {
                mSettings.mPermissionGroups.put(pg.getName(), pg);
                if (chatty && 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 (chatty && 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 removeAllPermissions(AndroidPackage pkg, boolean chatty) {
        synchronized (mLock) {
            int N = ArrayUtils.size(pkg.getPermissions());
            StringBuilder r = null;
            for (int i=0; i<N; i++) {
                ParsedPermission p = pkg.getPermissions().get(i);
                BasePermission bp = mSettings.mPermissions.get(p.getName());
                if (bp == null) {
                    bp = mSettings.mPermissionTrees.get(p.getName());
                }
                if (bp != null && bp.isPermission(p)) {
                    bp.setPermission(null);
                    if (DEBUG_REMOVE && chatty) {
                        if (r == null) {
                            r = new StringBuilder(256);
                        } else {
                            r.append(' ');
                        }
                        r.append(p.getName());
                    }
                }
                if (p.isAppOp()) {
                    ArraySet<String> appOpPkgs =
                            mSettings.mAppOpPermissionPackages.get(p.getName());
                    if (appOpPkgs != null) {
                        appOpPkgs.remove(pkg.getPackageName());
                    }
                }
            }
            if (r != null) {
                if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
            }

            N = pkg.getRequestedPermissions().size();
            r = null;
            for (int i=0; i<N; i++) {
                String perm = pkg.getRequestedPermissions().get(i);
                if (mSettings.isPermissionAppOp(perm)) {
                    ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
                    if (appOpPkgs != null) {
                        appOpPkgs.remove(pkg.getPackageName());
                        if (appOpPkgs.isEmpty()) {
                            mSettings.mAppOpPermissionPackages.remove(perm);
                        }
                    }
                }
            }
            if (r != null) {
                if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
            }
        }
    }

    /**
     * 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>
     *
     * <p>This restores the permission state for all users.
     *
     * @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 packageOfInterest If this is the name of {@code pkg} add extra logging
     * @param callback Result call back
     */
    private void restorePermissionState(@NonNull AndroidPackage pkg, boolean replace,
            @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
        // 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 PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
                pkg.getPackageName());
        if (ps == null) {
            return;
        }

        final PermissionsState permissionsState = ps.getPermissionsState();

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

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

        for (int userId : currentUserIds) {
            if (permissionsState.isMissing(userId)) {
                Collection<String> requestedPermissions;
                int targetSdkVersion;
                if (!ps.isSharedUser()) {
                    requestedPermissions = pkg.getRequestedPermissions();
                    targetSdkVersion = pkg.getTargetSdkVersion();
                } else {
                    requestedPermissions = new ArraySet<>();
                    targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
                    List<AndroidPackage> packages = ps.getSharedUser().getPackages();
                    int packagesSize = packages.size();
                    for (int i = 0; i < packagesSize; i++) {
                        AndroidPackage sharedUserPackage = packages.get(i);
                        requestedPermissions.addAll(sharedUserPackage.getRequestedPermissions());
                        targetSdkVersion = Math.min(targetSdkVersion,
                                sharedUserPackage.getTargetSdkVersion());
                    }
                }

                for (String permissionName : requestedPermissions) {
                    BasePermission permission = mSettings.getPermission(permissionName);
                    if (permission == null) {
                        continue;
                    }
                    if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME)
                            && permission.isRuntime() && !permission.isRemoved()) {
                        if (permission.isHardOrSoftRestricted()
                                || permission.isImmutablyRestricted()) {
                            permissionsState.updatePermissionFlags(permission, userId,
                                    FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
                                    FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
                        }
                        if (targetSdkVersion < Build.VERSION_CODES.M) {
                            permissionsState.updatePermissionFlags(permission, userId,
                                    PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
                                            | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT,
                                    PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
                                            | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT);
                            permissionsState.grantRuntimePermission(permission, userId);
                        }
                    }
                }

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

        PermissionsState origPermissions = permissionsState;

        boolean changedInstallPermission = false;

        if (replace) {
            ps.setInstallPermissionsFixed(false);
            if (!ps.isSharedUser()) {
                origPermissions = new PermissionsState(permissionsState);
                permissionsState.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.
                synchronized (mLock) {
                    updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
                            ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
                    if (!ArrayUtils.isEmpty(updatedUserIds)) {
                        runtimePermissionsRevoked = true;
                    }
                }
            }
        }

        permissionsState.setGlobalGids(mGlobalGids);

        synchronized (mLock) {
            ArraySet<String> newImplicitPermissions = new ArraySet<>();

            final int N = pkg.getRequestedPermissions().size();
            for (int i = 0; i < N; i++) {
                final String permName = pkg.getRequestedPermissions().get(i);
                final BasePermission bp = mSettings.getPermissionLocked(permName);
                final boolean appSupportsRuntimePermissions =
                        pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M;
                String upgradedActivityRecognitionPermission = null;

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

                if (bp == null || getSourcePackageSetting(bp) == null) {
                    if (packageOfInterest == null || packageOfInterest.equals(
                            pkg.getPackageName())) {
                        if (DEBUG_PERMISSIONS) {
                            Slog.i(TAG, "Unknown permission " + permName
                                    + " in package " + pkg.getPackageName());
                        }
                    }
                    continue;
                }

                // Cache newImplicitPermissions before modifing permissionsState as for the shared
                // uids the original and new state are the same object
                if (!origPermissions.hasRequestedPermission(permName)
                        && (pkg.getImplicitPermissions().contains(permName)
                                || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) {
                    if (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 " + pkg.getPackageName());
                        }
                    } else {
                        // Special case for Activity Recognition permission. Even if AR permission
                        // is not an implicit permission we want to add it to the list (try to
                        // auto-grant it) if the app was installed on a device before AR permission
                        // was split, regardless of if the app now requests the new AR permission
                        // or has updated its target SDK and AR is no longer implicit to it.
                        // This is a compatibility workaround for apps when AR permission was
                        // split in Q.
                        final List<SplitPermissionInfoParcelable> permissionList =
                                getSplitPermissions();
                        int numSplitPerms = permissionList.size();
                        for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
                            SplitPermissionInfoParcelable sp = permissionList.get(splitPermNum);
                            String splitPermName = sp.getSplitPermission();
                            if (sp.getNewPermissions().contains(permName)
                                    && origPermissions.hasInstallPermission(splitPermName)) {
                                upgradedActivityRecognitionPermission = splitPermName;
                                newImplicitPermissions.add(permName);

                                if (DEBUG_PERMISSIONS) {
                                    Slog.i(TAG, permName + " is newly added for "
                                            + pkg.getPackageName());
                                }
                                break;
                            }
                        }
                    }
                }

                // 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 " + pkg.getPackageName());
                    }
                    continue;
                }

                final String perm = bp.getName();
                boolean allowedSig = false;
                int grant = GRANT_DENIED;

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

                if (bp.isNormal()) {
                    // For all apps normal permissions are install time ones.
                    grant = GRANT_INSTALL;
                } else if (bp.isRuntime()) {
                    if (origPermissions.hasInstallPermission(bp.getName())
                            || upgradedActivityRecognitionPermission != null) {
                        // Before Q we represented some runtime permissions as install permissions,
                        // in Q we cannot do this anymore. Hence upgrade them all.
                        grant = GRANT_UPGRADE;
                    } else {
                        // For modern apps keep runtime permissions unchanged.
                        grant = GRANT_RUNTIME;
                    }
                } else if (bp.isSignature()) {
                    // For all apps signature permissions are install time ones.
                    allowedSig = grantSignaturePermission(perm, pkg, ps, bp, origPermissions);
                    if (allowedSig) {
                        grant = GRANT_INSTALL;
                    }
                }

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

                if (grant != GRANT_DENIED) {
                    if (!ps.isSystem() && ps.areInstallPermissionsFixed() && !bp.isRuntime()) {
                        // 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 ad dynamic.
                        if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
                            // Except...  if this is a permission that was added
                            // to the platform (note: need to only do this when
                            // updating the platform).
                            if (!isNewPlatformPermissionForPackage(perm, pkg)) {
                                grant = GRANT_DENIED;
                            }
                        }
                    }

                    switch (grant) {
                        case GRANT_INSTALL: {
                            // Revoke this as runtime permission to handle the case of
                            // a runtime permission being downgraded to an install one.
                            // Also in permission review mode we keep dangerous permissions
                            // for legacy apps
                            for (int userId : UserManagerService.getInstance().getUserIds()) {
                                if (origPermissions.getRuntimePermissionState(
                                        perm, userId) != null) {
                                    // Revoke the runtime permission and clear the flags.
                                    origPermissions.revokeRuntimePermission(bp, userId);
                                    origPermissions.updatePermissionFlags(bp, userId,
                                            PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
                                    // If we revoked a permission permission, we have to write.
                                    updatedUserIds = ArrayUtils.appendInt(
                                            updatedUserIds, userId);
                                }
                            }
                            // Grant an install permission.
                            if (permissionsState.grantInstallPermission(bp) !=
                                    PERMISSION_OPERATION_FAILURE) {
                                changedInstallPermission = true;
                            }
                        } break;

                        case GRANT_RUNTIME: {
                            boolean hardRestricted = bp.isHardRestricted();
                            boolean softRestricted = bp.isSoftRestricted();

                            for (int userId : currentUserIds) {
                                // If permission policy is not ready we don't deal with restricted
                                // permissions as the policy may whitelist some permissions. Once
                                // the policy is initialized we would re-evaluate permissions.
                                final boolean permissionPolicyInitialized =
                                        mPermissionPolicyInternal != null
                                                && mPermissionPolicyInternal.isInitialized(userId);

                                PermissionState permState = origPermissions
                                        .getRuntimePermissionState(perm, userId);
                                int flags = permState != null ? permState.getFlags() : 0;

                                boolean wasChanged = false;

                                boolean restrictionExempt =
                                        (origPermissions.getPermissionFlags(bp.name, userId)
                                                & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
                                boolean restrictionApplied = (origPermissions.getPermissionFlags(
                                        bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;

                                if (appSupportsRuntimePermissions) {
                                    // If hard restricted we don't allow holding it
                                    if (permissionPolicyInitialized && hardRestricted) {
                                        if (!restrictionExempt) {
                                            if (permState != null && permState.isGranted()
                                                    && permissionsState.revokeRuntimePermission(
                                                    bp, userId) != PERMISSION_OPERATION_FAILURE) {
                                                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 ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
                                        flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
                                        wasChanged = true;
                                    }

                                    if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0) {
                                        flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;
                                        wasChanged = true;
                                    // Hard restricted permissions cannot be held.
                                    } else if (!permissionPolicyInitialized
                                            || (!hardRestricted || restrictionExempt)) {
                                        if (permState != null && permState.isGranted()) {
                                            if (permissionsState.grantRuntimePermission(bp, userId)
                                                    == PERMISSION_OPERATION_FAILURE) {
                                                wasChanged = true;
                                            }
                                        }
                                    }
                                } else {
                                    if (permState == null) {
                                        // New permission
                                        if (PLATFORM_PACKAGE_NAME.equals(
                                                bp.getSourcePackageName())) {
                                            if (!bp.isRemoved()) {
                                                flags |= FLAG_PERMISSION_REVIEW_REQUIRED
                                                        | FLAG_PERMISSION_REVOKED_COMPAT;
                                                wasChanged = true;
                                            }
                                        }
                                    }

                                    if (!permissionsState.hasRuntimePermission(bp.name, userId)
                                            && permissionsState.grantRuntimePermission(bp, userId)
                                                    != PERMISSION_OPERATION_FAILURE) {
                                        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);
                                }

                                permissionsState.updatePermissionFlags(bp, userId,
                                        MASK_PERMISSION_FLAGS_ALL, flags);
                            }
                        } break;

                        case GRANT_UPGRADE: {
                            // Upgrade from Pre-Q to Q permission model. Make all permissions
                            // runtime
                            PermissionState permState = origPermissions
                                    .getInstallPermissionState(perm);
                            int flags = (permState != null) ? permState.getFlags() : 0;

                            BasePermission bpToRevoke =
                                    upgradedActivityRecognitionPermission == null
                                    ? bp : mSettings.getPermissionLocked(
                                            upgradedActivityRecognitionPermission);
                            // Remove install permission
                            if (origPermissions.revokeInstallPermission(bpToRevoke)
                                    != PERMISSION_OPERATION_FAILURE) {
                                origPermissions.updatePermissionFlags(bpToRevoke,
                                        UserHandle.USER_ALL,
                                        (MASK_PERMISSION_FLAGS_ALL
                                                & ~FLAG_PERMISSION_APPLY_RESTRICTION), 0);
                                changedInstallPermission = true;
                            }

                            boolean hardRestricted = bp.isHardRestricted();
                            boolean softRestricted = bp.isSoftRestricted();

                            for (int userId : currentUserIds) {
                                // If permission policy is not ready we don't deal with restricted
                                // permissions as the policy may whitelist some permissions. Once
                                // the policy is initialized we would re-evaluate permissions.
                                final boolean permissionPolicyInitialized =
                                        mPermissionPolicyInternal != null
                                                && mPermissionPolicyInternal.isInitialized(userId);

                                boolean wasChanged = false;

                                boolean restrictionExempt =
                                        (origPermissions.getPermissionFlags(bp.name, userId)
                                                & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
                                boolean restrictionApplied = (origPermissions.getPermissionFlags(
                                        bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;

                                if (appSupportsRuntimePermissions) {
                                    // If hard restricted we don't allow holding it
                                    if (permissionPolicyInitialized && hardRestricted) {
                                        if (!restrictionExempt) {
                                            if (permState != null && permState.isGranted()
                                                    && permissionsState.revokeRuntimePermission(
                                                    bp, userId) != PERMISSION_OPERATION_FAILURE) {
                                                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 ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
                                        flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
                                        wasChanged = true;
                                    }

                                    if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0) {
                                        flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;
                                        wasChanged = true;
                                    // Hard restricted permissions cannot be held.
                                    } else if (!permissionPolicyInitialized ||
                                            (!hardRestricted || restrictionExempt)) {
                                        if (permissionsState.grantRuntimePermission(bp, userId) !=
                                                PERMISSION_OPERATION_FAILURE) {
                                             wasChanged = true;
                                        }
                                    }
                                } else {
                                    if (!permissionsState.hasRuntimePermission(bp.name, userId)
                                            && permissionsState.grantRuntimePermission(bp,
                                                    userId) != PERMISSION_OPERATION_FAILURE) {
                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
                                        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);
                                }

                                permissionsState.updatePermissionFlags(bp, userId,
                                        MASK_PERMISSION_FLAGS_ALL, flags);
                            }
                        } break;

                        default: {
                            if (packageOfInterest == null
                                    || packageOfInterest.equals(pkg.getPackageName())) {
                                if (DEBUG_PERMISSIONS) {
                                    Slog.i(TAG, "Not granting permission " + perm
                                            + " to package " + pkg.getPackageName()
                                            + " because it was previously installed without");
                                }
                            }
                        } break;
                    }
                } else {
                    if (permissionsState.revokeInstallPermission(bp) !=
                            PERMISSION_OPERATION_FAILURE) {
                        // Also drop the permission flags.
                        permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
                                MASK_PERMISSION_FLAGS_ALL, 0);
                        changedInstallPermission = true;
                        if (DEBUG_PERMISSIONS) {
                            Slog.i(TAG, "Un-granting permission " + perm
                                    + " from package " + pkg.getPackageName()
                                    + " (protectionLevel=" + bp.getProtectionLevel()
                                    + " flags=0x"
                                    + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg, ps))
                                    + ")");
                        }
                    } else if (bp.isAppOp()) {
                        // Don't print warning for app op permissions, since it is fine for them
                        // not to be granted, there is a UI for the user to decide.
                        if (DEBUG_PERMISSIONS
                                && (packageOfInterest == null
                                        || packageOfInterest.equals(pkg.getPackageName()))) {
                            Slog.i(TAG, "Not granting permission " + perm
                                    + " to package " + pkg.getPackageName()
                                    + " (protectionLevel=" + bp.getProtectionLevel()
                                    + " flags=0x"
                                    + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg, ps))
                                    + ")");
                        }
                    }
                }
            }

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

            updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
                    updatedUserIds);
            updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
                    permissionsState, pkg, newImplicitPermissions, updatedUserIds);
            updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, updatedUserIds);
        }

        // 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.
        if (callback != null) {
            callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
        }

        for (int userId : updatedUserIds) {
            notifyRuntimePermissionStateChanged(pkg.getPackageName(), userId);
        }
    }

    /**
     * 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 pkg The package that is currently looked at
     * @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
     */
    private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
            @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
            @NonNull int[] updatedUserIds) {
        String pkgName = pkg.getPackageName();
        boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
                >= Build.VERSION_CODES.M;

        int[] users = UserManagerService.getInstance().getUserIds();
        int numUsers = users.length;
        for (int i = 0; i < numUsers; i++) {
            int userId = users[i];

            for (String permission : ps.getPermissions(userId)) {
                if (!pkg.getImplicitPermissions().contains(permission)) {
                    if (!ps.hasInstallPermission(permission)) {
                        int flags = ps.getRuntimePermissionState(permission, userId).getFlags();

                        if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
                            BasePermission bp = mSettings.getPermissionLocked(permission);

                            int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;

                            if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
                                    && supportsRuntimePermissions) {
                                int revokeResult = ps.revokeRuntimePermission(bp, userId);
                                if (revokeResult != PERMISSION_OPERATION_FAILURE) {
                                    if (DEBUG_PERMISSIONS) {
                                        Slog.i(TAG, "Revoking runtime permission "
                                                + permission + " for " + pkgName
                                                + " as it is now requested");
                                    }
                                }

                                flagsToRemove |= USER_PERMISSION_FLAGS;
                            }

                            ps.updatePermissionFlags(bp, userId, 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
     * @param userId The user the permission belongs to
     */
    private void inheritPermissionStateToNewImplicitPermissionLocked(
            @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
            @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
            @UserIdInt int userId) {
        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.hasRuntimePermission(sourcePerm, userId))
                    || ps.hasInstallPermission(sourcePerm)) {
                if (!isGranted) {
                    flags = 0;
                }

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

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

            ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
        }

        // Add permission flags
        ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, 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 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[] updatedUserIds) {
        if (replace && pkg.isRequestLegacyExternalStorage() && (
                pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE)
                        || pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) {
            return UserManagerService.getInstance().getUserIds();
        }

        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 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
     */
    private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
            @NonNull PermissionsState origPs,
            @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
            @NonNull ArraySet<String> newImplicitPermissions,
            @NonNull int[] updatedUserIds) {
        String pkgName = pkg.getPackageName();
        ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();

        final List<SplitPermissionInfoParcelable> permissionList = getSplitPermissions();
        int numSplitPerms = permissionList.size();
        for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
            SplitPermissionInfoParcelable 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) {
                if (!ps.hasInstallPermission(newPerm)) {
                    BasePermission bp = mSettings.getPermissionLocked(newPerm);

                    int[] users = UserManagerService.getInstance().getUserIds();
                    int numUsers = users.length;
                    for (int userNum = 0; userNum < numUsers; userNum++) {
                        int userId = users[userNum];

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

                        boolean inheritsFromInstallPerm = false;
                        for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
                                sourcePermNum++) {
                            if (ps.hasInstallPermission(sourcePerms.valueAt(sourcePermNum))) {
                                inheritsFromInstallPerm = true;
                                break;
                            }
                        }

                        if (!origPs.hasRequestedPermission(sourcePerms)
                                && !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");
                            }
                        } else {
                            // Inherit from new install or existing runtime permissions
                            inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
                                    newPerm, ps, pkg, userId);
                        }
                    }
                }
            }
        }

        return updatedUserIds;
    }

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

    private OneTimePermissionUserManager getOneTimePermissionUserManager(@UserIdInt int userId) {
        OneTimePermissionUserManager oneTimePermissionUserManager;
        synchronized (mLock) {
            oneTimePermissionUserManager =
                    mOneTimePermissionUserManagers.get(userId);
            if (oneTimePermissionUserManager != null) {
                return oneTimePermissionUserManager;
            }
            oneTimePermissionUserManager = new OneTimePermissionUserManager(
                    mContext.createContextAsUser(UserHandle.of(userId), /*flags*/ 0));
            mOneTimePermissionUserManagers.put(userId, oneTimePermissionUserManager);
        }
        oneTimePermissionUserManager.registerUninstallListener();
        return oneTimePermissionUserManager;
    }

    @Override
    public void startOneTimePermissionSession(String packageName, @UserIdInt int userId,
            long timeoutMillis, int importanceToResetTimer, int importanceToKeepSessionAlive) {
        mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
                "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
                        + " to register permissions as one time.");
        Objects.requireNonNull(packageName);

        long token = Binder.clearCallingIdentity();
        try {
            getOneTimePermissionUserManager(userId).startPackageOneTimeSession(packageName,
                    timeoutMillis, importanceToResetTimer, importanceToKeepSessionAlive);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    @Override
    public void stopOneTimePermissionSession(String packageName, @UserIdInt int userId) {
        mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
                "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
                        + " to remove permissions as one time.");
        Objects.requireNonNull(packageName);

        long token = Binder.clearCallingIdentity();
        try {
            getOneTimePermissionUserManager(userId).stopPackageOneTimeSession(packageName);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    @Override
    public List<String> getAutoRevokeExemptionRequestedPackages(int userId) {
        return getPackagesWithAutoRevokePolicy(AUTO_REVOKE_DISCOURAGED, userId);
    }

    @Override
    public List<String> getAutoRevokeExemptionGrantedPackages(int userId) {
        return getPackagesWithAutoRevokePolicy(AUTO_REVOKE_DISALLOWED, userId);
    }

    @NonNull
    private List<String> getPackagesWithAutoRevokePolicy(int autoRevokePolicy, int userId) {
        mContext.enforceCallingPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
                "Must hold " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);

        List<String> result = new ArrayList<>();
        mPackageManagerInt.forEachInstalledPackage(pkg -> {
            if (pkg.getAutoRevokePermissions() == autoRevokePolicy) {
                result.add(pkg.getPackageName());
            }
        }, userId);
        return result;
    }

    private boolean isNewPlatformPermissionForPackage(String perm, AndroidPackage pkg) {
        boolean allowed = false;
        final int NP = PackageParser.NEW_PERMISSIONS.length;
        for (int ip=0; ip<NP; ip++) {
            final PackageParser.NewPermissionInfo npi
                    = PackageParser.NEW_PERMISSIONS[ip];
            if (npi.name.equals(perm)
                    && pkg.getTargetSdkVersion() < npi.sdkVersion) {
                allowed = true;
                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
                        + pkg.getPackageName());
                break;
            }
        }
        return allowed;
    }

    /**
     * Determines whether a package is whitelisted for a particular privapp permission.
     *
     * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
     *
     * <p>This handles parent/child apps.
     */
    private boolean hasPrivappWhitelistEntry(String perm, AndroidPackage pkg) {
        ArraySet<String> wlPermissions;
        if (pkg.isVendor()) {
            wlPermissions =
                    SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.getPackageName());
        } else if (pkg.isProduct()) {
            wlPermissions =
                    SystemConfig.getInstance().getProductPrivAppPermissions(pkg.getPackageName());
        } else if (pkg.isSystemExt()) {
            wlPermissions =
                    SystemConfig.getInstance().getSystemExtPrivAppPermissions(
                            pkg.getPackageName());
        } else {
            wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.getPackageName());
        }

        return wlPermissions != null && wlPermissions.contains(perm);
    }

    private boolean grantSignaturePermission(String perm, AndroidPackage pkg,
            PackageSetting pkgSetting, BasePermission bp, PermissionsState origPermissions) {
        boolean oemPermission = bp.isOEM();
        boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
        boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
        boolean privappPermissionsDisable =
                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName());
        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
                && !platformPackage && platformPermission) {
            if (!hasPrivappWhitelistEntry(perm, pkg)) {
                // Only enforce whitelist this on boot
                if (!mSystemReady
                        // Updated system apps do not need to be whitelisted
                        && !pkgSetting.getPkgState().isUpdatedSystemApp()) {
                    ApexManager apexMgr = ApexManager.getInstance();
                    String apexContainingPkg = apexMgr.getActiveApexPackageNameContainingPackage(
                            pkg);

                    // Apps that are in updated apexs' do not need to be whitelisted
                    if (apexContainingPkg == null || apexMgr.isFactory(
                            apexMgr.getPackageInfo(apexContainingPkg, MATCH_ACTIVE_PACKAGE))) {
                        // it's only a reportable violation if the permission isn't explicitly
                        // denied
                        ArraySet<String> deniedPermissions = null;
                        if (pkg.isVendor()) {
                            deniedPermissions = SystemConfig.getInstance()
                                    .getVendorPrivAppDenyPermissions(pkg.getPackageName());
                        } else if (pkg.isProduct()) {
                            deniedPermissions = SystemConfig.getInstance()
                                    .getProductPrivAppDenyPermissions(pkg.getPackageName());
                        } else if (pkg.isSystemExt()) {
                            deniedPermissions = SystemConfig.getInstance()
                                    .getSystemExtPrivAppDenyPermissions(pkg.getPackageName());
                        } else {
                            deniedPermissions = SystemConfig.getInstance()
                                    .getPrivAppDenyPermissions(pkg.getPackageName());
                        }
                        final boolean permissionViolation =
                                deniedPermissions == null || !deniedPermissions.contains(perm);
                        if (permissionViolation) {
                            Slog.w(TAG, "Privileged permission " + perm + " for package "
                                    + pkg.getPackageName() + " (" + pkg.getCodePath()
                                    + ") not in privapp-permissions whitelist");

                            if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
                                if (mPrivappPermissionsViolations == null) {
                                    mPrivappPermissionsViolations = new ArraySet<>();
                                }
                                mPrivappPermissionsViolations.add(
                                        pkg.getPackageName() + " (" + pkg.getCodePath() + "): "
                                                + perm);
                            }
                        } else {
                            return false;
                        }
                    }
                }
                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
                    return false;
                }
            }
        }
        // expect single system package
        String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames(
                PackageManagerInternal.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 the above relationships with the system package
        final PackageParser.SigningDetails sourceSigningDetails =
                getSourcePackageSigningDetails(bp);
        boolean allowed =
                pkg.getSigningDetails().hasAncestorOrSelf(sourceSigningDetails)
                || sourceSigningDetails.checkCapability(
                        pkg.getSigningDetails(),
                        PackageParser.SigningDetails.CertCapabilities.PERMISSION)
                || pkg.getSigningDetails().hasAncestorOrSelf(systemPackage.getSigningDetails())
                || systemPackage.getSigningDetails().checkCapability(
                        pkg.getSigningDetails(),
                        PackageParser.SigningDetails.CertCapabilities.PERMISSION);
        if (!allowed && (privilegedPermission || oemPermission)) {
            if (pkg.isSystem()) {
                // For updated system applications, a privileged/oem permission
                // is granted only if it had been defined by the original application.
                if (pkgSetting.getPkgState().isUpdatedSystemApp()) {
                    final PackageSetting disabledPs = mPackageManagerInt
                            .getDisabledSystemPackage(pkg.getPackageName());
                    final AndroidPackage disabledPkg = disabledPs == null ? null : disabledPs.pkg;
                    if (disabledPs != null
                            && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
                        // If the original was granted this permission, we take
                        // that grant decision as read and propagate it to the
                        // update.
                        if ((privilegedPermission && disabledPs.isPrivileged())
                                || (oemPermission && disabledPs.isOem()
                                        && canGrantOemPermission(disabledPs, perm))) {
                            allowed = true;
                        }
                    } else {
                        // The system apk may have been updated with an older
                        // version of the one on the data partition, but which
                        // granted a new system permission that it didn't have
                        // before.  In this case we do want to allow the app to
                        // now get the new permission if the ancestral apk is
                        // privileged to get it.
                        if (disabledPs != null && disabledPkg != null
                                && isPackageRequestingPermission(disabledPkg, perm)
                                && ((privilegedPermission && disabledPs.isPrivileged())
                                        || (oemPermission && disabledPs.isOem()
                                                && canGrantOemPermission(disabledPs, perm)))) {
                            allowed = true;
                        }
                    }
                } else {
                    final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
                            pkg.getPackageName());
                    allowed = (privilegedPermission && pkg.isPrivileged())
                            || (oemPermission && pkg.isOem()
                                    && canGrantOemPermission(ps, perm));
                }
                // 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 && privilegedPermission &&
                        !vendorPrivilegedPermission && pkg.isVendor()) {
                   Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
                           + pkg.getPackageName()
                           + " because it isn't a 'vendorPrivileged' permission.");
                   allowed = false;
                }
            }
        }
        if (!allowed) {
            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(
                            PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM),
                    pkg.getPackageName()) || ArrayUtils.contains(
                            mPackageManagerInt.getKnownPackageNames(
                                    PackageManagerInternal.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(
                            PackageManagerInternal.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()
                    && pkg.isSystem()) {
                // Any pre-installed system app is allowed to get this permission.
                allowed = true;
            }
            if (!allowed && bp.isDevelopment()) {
                // For development permissions, a development permission
                // is granted only if it was already granted.
                allowed = origPermissions.hasInstallPermission(perm);
            }
            if (!allowed && bp.isSetup()
                    && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                            PackageManagerInternal.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(
                            PackageManagerInternal.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(
                            PackageManagerInternal.PACKAGE_CONFIGURATOR,
                    UserHandle.USER_SYSTEM), pkg.getPackageName())) {
                // Special permissions for the device configurator.
                allowed = true;
            }
            if (!allowed && bp.isWellbeing()
                    && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                            PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM),
                    pkg.getPackageName())) {
                // Special permission granted only to the OEM specified wellbeing app
                allowed = true;
            }
            if (!allowed && bp.isDocumenter()
                    && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                            PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM),
                    pkg.getPackageName())) {
                // If this permission is to be granted to the documenter and
                // this app is the documenter, then it gets the permission.
                allowed = true;
            }
            if (!allowed && bp.isIncidentReportApprover()
                    && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
                            PackageManagerInternal.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(
                            PackageManagerInternal.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(
                        PackageManagerInternal.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(
                            PackageManagerInternal.PACKAGE_RETAIL_DEMO, UserHandle.USER_SYSTEM),
                    pkg.getPackageName()) && isProfileOwner(pkg.getUid())) {
                // Special permission granted only to the OEM specified retail demo app
                allowed = true;
            }
        }
        return allowed;
    }

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

    @Nullable
    private PackageSetting getSourcePackageSetting(@NonNull BasePermission bp) {
        final String sourcePackageName = bp.getSourcePackageName();
        return mPackageManagerInt.getPackageSetting(sourcePackageName);
    }

    private static boolean isProfileOwner(int uid) {
        DevicePolicyManagerInternal dpmInternal =
                LocalServices.getService(DevicePolicyManagerInternal.class);
        if (dpmInternal != null) {
            return dpmInternal
                    .isActiveAdminWithPolicy(uid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
        }
        return false;
    }

    private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
        if (!ps.isOem()) {
            return false;
        }
        // all oem permissions must explicitly be granted or denied
        final Boolean granted =
                SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
        if (granted == null) {
            throw new IllegalStateException("OEM permission" + permission + " requested by package "
                    + ps.name + " must be explicitly declared granted or not");
        }
        return Boolean.TRUE == granted;
    }

    private boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
            @UserIdInt int userId) {
        // 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.
        final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
                pkg.getPackageName());
        if (ps == null) {
            return false;
        }
        final PermissionsState permissionsState = ps.getPermissionsState();
        return permissionsState.isPermissionReviewRequired(userId);
    }

    private boolean isPackageRequestingPermission(AndroidPackage pkg, String permission) {
        final int permCount = pkg.getRequestedPermissions().size();
        for (int j = 0; j < permCount; j++) {
            String requestedPermission = pkg.getRequestedPermissions().get(j);
            if (permission.equals(requestedPermission)) {
                return true;
            }
        }
        return false;
    }

    private void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
            String[] grantedPermissions, int callingUid, PermissionCallback callback) {
        for (int userId : userIds) {
            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
                    callback);
        }
    }

    private void grantRequestedRuntimePermissionsForUser(AndroidPackage pkg, int userId,
            String[] grantedPermissions, int callingUid, PermissionCallback callback) {
        PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
                pkg.getPackageName());
        if (ps == null) {
            return;
        }

        PermissionsState permissionsState = ps.getPermissionsState();

        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);

        for (String permission : pkg.getRequestedPermissions()) {
            final BasePermission bp;
            synchronized (mLock) {
                bp = mSettings.getPermissionLocked(permission);
            }
            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
                    && (!instantApp || bp.isInstant())
                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
                    && (grantedPermissions == null
                           || ArrayUtils.contains(grantedPermissions, permission))) {
                final int flags = permissionsState.getPermissionFlags(permission, userId);
                if (supportsRuntimePermissions) {
                    // Installer cannot change immutable permissions.
                    if ((flags & immutableFlags) == 0) {
                        grantRuntimePermissionInternal(permission, pkg.getPackageName(), false,
                                callingUid, userId, callback);
                    }
                } 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(permission, pkg.getPackageName(), compatFlags,
                                0, callingUid, userId, false, callback);
                    }
                }
            }
        }
    }

    private void setWhitelistedRestrictedPermissionsForUsers(@NonNull AndroidPackage pkg,
            @UserIdInt int[] userIds, @Nullable List<String> permissions, int callingUid,
            @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
        final PermissionsState permissionsState =
                PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
        if (permissionsState == null) {
            return;
        }

        SparseArray<ArraySet<String>> oldGrantedRestrictedPermissions = new SparseArray<>();
        boolean updatePermissions = false;
        final int permissionCount = pkg.getRequestedPermissions().size();

        for (int i = 0; i < userIds.length; i++) {
            int userId = userIds[i];
            for (int j = 0; j < permissionCount; j++) {
                final String permissionName = pkg.getRequestedPermissions().get(j);

                final BasePermission bp = mSettings.getPermissionLocked(permissionName);

                if (bp == null || !bp.isHardOrSoftRestricted()) {
                    continue;
                }

                if (permissionsState.hasPermission(permissionName, userId)) {
                    if (oldGrantedRestrictedPermissions.get(userId) == null) {
                        oldGrantedRestrictedPermissions.put(userId, new ArraySet<>());
                    }
                    oldGrantedRestrictedPermissions.get(userId).add(permissionName);
                }

                final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);

                int newFlags = oldFlags;
                int mask = 0;
                int whitelistFlagsCopy = whitelistFlags;
                while (whitelistFlagsCopy != 0) {
                    final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
                    whitelistFlagsCopy &= ~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 wasWhitelisted = (oldFlags
                        & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
                final boolean isWhitelisted = (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 whitelists we need to clear the policy fixed flag
                // as whitelisting trumps policy i.e. policy cannot grant a non
                // grantable permission.
                if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
                    final boolean isGranted = permissionsState.hasPermission(permissionName,
                            userId);
                    if (!isWhitelisted && isGranted) {
                        mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
                        newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
                    }
                }

                // If we are whitelisting 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
                        && !wasWhitelisted && isWhitelisted) {
                    mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
                    newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
                }

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

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

            // If this resulted in losing a permission we need to kill the app.
            for (int i = 0; i < userIds.length; i++) {
                int userId = userIds[i];
                ArraySet<String> oldPermsForUser = oldGrantedRestrictedPermissions.get(userId);
                if (oldPermsForUser == null) {
                    continue;
                }

                final int oldGrantedCount = oldPermsForUser.size();
                for (int j = 0; j < oldGrantedCount; j++) {
                    final String permission = oldPermsForUser.valueAt(j);
                    // Sometimes we create a new permission state instance during update.
                    final PermissionsState newPermissionsState =
                            PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt,
                                    pkg);
                    if (!newPermissionsState.hasPermission(permission, userId)) {
                        callback.onPermissionRevoked(pkg.getUid(), userId, null);
                        break;
                    }
                }
            }
        }
    }

    @GuardedBy("mLock")
    private int[] revokeUnusedSharedUserPermissionsLocked(
            SharedUserSetting suSetting, int[] allUserIds) {
        // Collect all used permissions in the UID
        final ArraySet<String> usedPermissions = new ArraySet<>();
        final List<AndroidPackage> pkgList = suSetting.getPackages();
        if (pkgList == null || pkgList.size() == 0) {
            return EmptyArray.INT;
        }
        for (AndroidPackage pkg : pkgList) {
            if (pkg.getRequestedPermissions().isEmpty()) {
                continue;
            }
            final int requestedPermCount = pkg.getRequestedPermissions().size();
            for (int j = 0; j < requestedPermCount; j++) {
                String permission = pkg.getRequestedPermissions().get(j);
                BasePermission bp = mSettings.getPermissionLocked(permission);
                if (bp != null) {
                    usedPermissions.add(permission);
                }
            }
        }

        PermissionsState permissionsState = suSetting.getPermissionsState();
        // Prune install permissions
        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
        final int installPermCount = installPermStates.size();
        for (int i = installPermCount - 1; i >= 0;  i--) {
            PermissionState permissionState = installPermStates.get(i);
            if (!usedPermissions.contains(permissionState.getName())) {
                BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
                if (bp != null) {
                    permissionsState.revokeInstallPermission(bp);
                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
                            MASK_PERMISSION_FLAGS_ALL, 0);
                }
            }
        }

        int[] runtimePermissionChangedUserIds = EmptyArray.INT;

        // Prune runtime permissions
        for (int userId : allUserIds) {
            List<PermissionState> runtimePermStates = permissionsState
                    .getRuntimePermissionStates(userId);
            final int runtimePermCount = runtimePermStates.size();
            for (int i = runtimePermCount - 1; i >= 0; i--) {
                PermissionState permissionState = runtimePermStates.get(i);
                if (!usedPermissions.contains(permissionState.getName())) {
                    BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
                    if (bp != null) {
                        permissionsState.revokeRuntimePermission(bp, userId);
                        permissionsState.updatePermissionFlags(bp, userId,
                                MASK_PERMISSION_FLAGS_ALL, 0);
                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
                                runtimePermissionChangedUserIds, userId);
                    }
                }
            }
        }

        return runtimePermissionChangedUserIds;
    }

    /**
     * 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
     * @param allPackages All currently known packages
     * @param callback Callback to call after permission changes
     */
    private void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg,
            @NonNull PermissionCallback callback) {
        // 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, callback);
    }

    /**
     * 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 of the packages to be updated, {@code null} for all volumes
     * @param allPackages All currently known packages
     * @param callback Callback to call after permission changes
     */
    private void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated,
            @NonNull PermissionCallback callback) {
        PackageManager.corkPackageInfoCache();  // Prevent invalidation storm
        try {
            final int flags = UPDATE_PERMISSIONS_ALL |
                    (sdkUpdated
                            ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
                            : 0);
            updatePermissions(null, null, volumeUuid, flags, callback);
        } finally {
            PackageManager.uncorkPackageInfoCache();
        }
    }

    /**
     * Cache background->foreground permission mapping.
     *
     * <p>This is only run once.
     */
    private void cacheBackgroundToForegoundPermissionMapping() {
        synchronized (mLock) {
            if (mBackgroundPermissions == null) {
                // Cache background -> foreground permission mapping.
                // Only system declares background permissions, hence mapping does never change.
                mBackgroundPermissions = new ArrayMap<>();
                for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
                    if (bp.perm != null && bp.perm.getBackgroundPermission() != null) {
                        String fgPerm = bp.name;
                        String bgPerm = bp.perm.getBackgroundPermission();

                        List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
                        if (fgPerms == null) {
                            fgPerms = new ArrayList<>();
                            mBackgroundPermissions.put(bgPerm, fgPerms);
                        }

                        fgPerms.add(fgPerm);
                    }
                }
            }
        }
    }

    /**
     * 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,
                changingPkg, 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;
        }

        cacheBackgroundToForegoundPermissionMapping();

        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);
            });
        }

        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);
        }
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    }

    /**
     * Update which app declares a permission.
     *
     * <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 source package might have changed
     */
    private boolean updatePermissionSourcePackage(@Nullable String packageName,
            @Nullable AndroidPackage pkg,
            final @Nullable PermissionCallback callback) {
        // Always need update if packageName is null
        if (packageName == null) {
            return true;
        }

        boolean changed = false;
        Set<BasePermission> needsUpdate = null;
        synchronized (mLock) {
            final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
            while (it.hasNext()) {
                final BasePermission bp = it.next();
                if (bp.isDynamic()) {
                    bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
                }
                if (!packageName.equals(bp.getSourcePackageName())) {
                    // 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
                // Set to changed for either install or uninstall
                changed = true;
                // If the target package is being uninstalled, we need to revoke this permission
                // From all other packages
                if (pkg == null || !hasPermission(pkg, bp.getName())) {
                    Slog.i(TAG, "Removing permission " + bp.getName()
                            + " that used to be declared by " + bp.getSourcePackageName());
                    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));
                        }
                    }
                    it.remove();
                }
                if (needsUpdate == null) {
                    needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
                }
                needsUpdate.add(bp);
            }
        }
        if (needsUpdate != null) {
            for (final BasePermission bp : needsUpdate) {
                final AndroidPackage sourcePkg =
                        mPackageManagerInt.getPackage(bp.getSourcePackageName());
                final PackageSetting sourcePs =
                        (PackageSetting) mPackageManagerInt.getPackageSetting(
                                bp.getSourcePackageName());
                synchronized (mLock) {
                    if (sourcePkg != null && sourcePs != null) {
                        continue;
                    }
                    Slog.w(TAG, "Removing dangling permission: " + bp.getName()
                            + " from package " + bp.getSourcePackageName());
                    mSettings.removePermissionLocked(bp.getName());
                }
            }
        }
        return changed;
    }

    /**
     * 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 (checkPermissionImpl(permissionName, pName, userId)
                == PackageManager.PERMISSION_GRANTED) {
            try {
                revokeRuntimePermissionInternal(
                        permissionName,
                        pName,
                        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;

        Set<BasePermission> needsUpdate = null;
        synchronized (mLock) {
            final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
            while (it.hasNext()) {
                final BasePermission bp = it.next();
                if (!packageName.equals(bp.getSourcePackageName())) {
                    // 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.getSourcePackageName());
                    it.remove();
                }
                if (needsUpdate == null) {
                    needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
                }
                needsUpdate.add(bp);
            }
        }
        if (needsUpdate != null) {
            for (final BasePermission bp : needsUpdate) {
                final AndroidPackage sourcePkg =
                        mPackageManagerInt.getPackage(bp.getSourcePackageName());
                final PackageSetting sourcePs =
                        (PackageSetting) mPackageManagerInt.getPackageSetting(
                                bp.getSourcePackageName());
                synchronized (mLock) {
                    if (sourcePkg != null && sourcePs != null) {
                        continue;
                    }
                    Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
                            + " from package " + bp.getSourcePackageName());
                    mSettings.removePermissionLocked(bp.getName());
                }
            }
        }
        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);
        }
    }

    /**
     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
     * or INTERACT_ACROSS_USERS_FULL permissions, if the 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, int userId,
            boolean requireFullPermission, boolean checkShell,
            boolean requirePermissionWhenSameUser, String message) {
        if (userId < 0) {
            throw new IllegalArgumentException("Invalid userId " + userId);
        }
        if (checkShell) {
            PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
                    UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
        }
        final int callingUserId = UserHandle.getUserId(callingUid);
        if (hasCrossUserPermission(
                callingUid, callingUserId, userId, requireFullPermission,
                requirePermissionWhenSameUser)) {
            return;
        }
        String errorMessage = buildInvalidCrossUserPermissionMessage(
                message, requireFullPermission);
        Slog.w(TAG, errorMessage);
        throw new SecurityException(errorMessage);
    }

    /**
     * Checks if the request is from the system or an app that has the appropriate cross-user
     * permissions defined as follows:
     * <ul>
     * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
     * <li>INTERACT_ACROSS_USERS if the given {@userId} is in a different profile group
     * to the caller.</li>
     * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@userId} is in the same profile group
     * as the caller.</li>
     * </ul>
     *
     * @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 enforceCrossUserOrProfilePermission(int callingUid, int userId,
            boolean requireFullPermission, boolean checkShell,
            String message) {
        if (userId < 0) {
            throw new IllegalArgumentException("Invalid userId " + userId);
        }
        if (checkShell) {
            PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
                    UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
        }
        final int callingUserId = UserHandle.getUserId(callingUid);
        if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission,
                /*requirePermissionWhenSameUser= */ false)) {
            return;
        }
        final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId);
        if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight(
                mContext,
                android.Manifest.permission.INTERACT_ACROSS_PROFILES,
                PermissionChecker.PID_UNKNOWN,
                callingUid,
                mPackageManagerInt.getPackage(callingUid).getPackageName())
                == PermissionChecker.PERMISSION_GRANTED) {
            return;
        }
        String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage(
                message, requireFullPermission, isSameProfileGroup);
        Slog.w(TAG, errorMessage);
        throw new SecurityException(errorMessage);
    }

    private boolean hasCrossUserPermission(
            int callingUid, int callingUserId, int userId, boolean requireFullPermission,
            boolean requirePermissionWhenSameUser) {
        if (!requirePermissionWhenSameUser && userId == callingUserId) {
            return true;
        }
        if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) {
            return true;
        }
        if (requireFullPermission) {
            return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
        }
        return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
                || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS);
    }

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

    private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
        final long identity = Binder.clearCallingIdentity();
        try {
            return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    private static String buildInvalidCrossUserPermissionMessage(
            String message, boolean requireFullPermission) {
        StringBuilder builder = new StringBuilder();
        if (message != null) {
            builder.append(message);
            builder.append(": ");
        }
        builder.append("Requires ");
        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
        if (requireFullPermission) {
            builder.append(".");
            return builder.toString();
        }
        builder.append(" or ");
        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
        builder.append(".");
        return builder.toString();
    }

    private static String buildInvalidCrossUserOrProfilePermissionMessage(
            String message, boolean requireFullPermission, boolean isSameProfileGroup) {
        StringBuilder builder = new StringBuilder();
        if (message != null) {
            builder.append(message);
            builder.append(": ");
        }
        builder.append("Requires ");
        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
        if (requireFullPermission) {
            builder.append(".");
            return builder.toString();
        }
        builder.append(" or ");
        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
        if (isSameProfileGroup) {
            builder.append(" or ");
            builder.append(android.Manifest.permission.INTERACT_ACROSS_PROFILES);
        }
        builder.append(".");
        return builder.toString();
    }

    @GuardedBy({"mSettings.mLock", "mLock"})
    private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
        int size = 0;
        for (BasePermission perm : mSettings.mPermissions.values()) {
            size += tree.calculateFootprint(perm);
        }
        return size;
    }

    @GuardedBy({"mSettings.mLock", "mLock"})
    private void enforcePermissionCapLocked(PermissionInfo info, BasePermission 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");
            }
        }
    }

    private void systemReady() {
        mSystemReady = true;
        if (mPrivappPermissionsViolations != null) {
            throw new IllegalStateException("Signature|privileged permissions not in "
                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
        }

        mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
        mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);

        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
        for (int userId : UserManagerService.getInstance().getUserIds()) {
            if (mPackageManagerInt.isPermissionUpgradeNeeded(userId)) {
                grantPermissionsUserIds = ArrayUtils.appendInt(
                        grantPermissionsUserIds, userId);
            }
        }
        // If we upgraded grant all default permissions before kicking off.
        for (int userId : grantPermissionsUserIds) {
            mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
        }
        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
            // If we did not grant default permissions, we preload from this the
            // default permission exceptions lazily to ensure we don't hit the
            // disk on a new user creation.
            mDefaultPermissionGrantPolicy.scheduleReadDefaultPermissionExceptions();
        }
    }

    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(MetricsEvent.FIELD_PERMISSION, name);

        mMetricsLogger.write(log);
    }

    /**
     * Get the mapping of background permissions to their foreground permissions.
     *
     * <p>Only initialized in the system server.
     *
     * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
     */
    public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
        return mBackgroundPermissions;
    }

    private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
        @Override
        public void systemReady() {
            PermissionManagerService.this.systemReady();
        }
        @Override
        public boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
                @UserIdInt int userId) {
            return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
        }

        @Override
        public void revokeRuntimePermissionsIfGroupChanged(
                @NonNull AndroidPackage newPackage,
                @NonNull AndroidPackage oldPackage,
                @NonNull ArrayList<String> allPackageNames) {
            PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
                    oldPackage, allPackageNames, mDefaultPermissionCallback);
        }
        @Override
        public void addAllPermissions(AndroidPackage pkg, boolean chatty) {
            PermissionManagerService.this.addAllPermissions(pkg, chatty);
        }
        @Override
        public void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) {
            PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
        }
        @Override
        public void removeAllPermissions(AndroidPackage pkg, boolean chatty) {
            PermissionManagerService.this.removeAllPermissions(pkg, chatty);
        }
        @Override
        public void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
                String[] grantedPermissions, int callingUid) {
            PermissionManagerService.this.grantRequestedRuntimePermissions(
                    pkg, userIds, grantedPermissions, callingUid, mDefaultPermissionCallback);
        }
        @Override
        public void setWhitelistedRestrictedPermissions(@NonNull AndroidPackage pkg,
                @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
                @PackageManager.PermissionWhitelistFlags int flags) {
            setWhitelistedRestrictedPermissionsForUsers(pkg, userIds, permissions,
                    callingUid, flags, mDefaultPermissionCallback);
        }
        @Override
        public void setWhitelistedRestrictedPermissions(String packageName,
                List<String> permissions, int flags, int userId) {
            PermissionManagerService.this.setWhitelistedRestrictedPermissionsInternal(
                    packageName, permissions, flags, userId);
        }
        @Override
        public void setAutoRevokeWhitelisted(
                @NonNull String packageName, boolean whitelisted, int userId) {
            PermissionManagerService.this.setAutoRevokeWhitelisted(
                    packageName, whitelisted, userId);
        }
        @Override
        public void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) {
            PermissionManagerService.this
                    .updatePermissions(packageName, pkg, mDefaultPermissionCallback);
        }
        @Override
        public void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated) {
            PermissionManagerService.this
                    .updateAllPermissions(volumeUuid, sdkUpdated, mDefaultPermissionCallback);
        }
        @Override
        public void resetRuntimePermissions(AndroidPackage pkg, int userId) {
            PermissionManagerService.this.resetRuntimePermissionsInternal(pkg, userId);
        }
        @Override
        public void resetAllRuntimePermissions(final int userId) {
            mPackageManagerInt.forEachPackage(
                    (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId));
        }
        @Override
        public String[] getAppOpPermissionPackages(String permName, int callingUid) {
            return PermissionManagerService.this
                    .getAppOpPermissionPackagesInternal(permName, callingUid);
        }
        @Override
        public void enforceCrossUserPermission(int callingUid, int userId,
                boolean requireFullPermission, boolean checkShell, String message) {
            PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
                    requireFullPermission, checkShell, false, message);
        }
        @Override
        public void enforceCrossUserPermission(int callingUid, int userId,
                boolean requireFullPermission, boolean checkShell,
                boolean requirePermissionWhenSameUser, String message) {
            PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
                    requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
        }

        @Override
        public void enforceCrossUserOrProfilePermission(int callingUid, int userId,
                boolean requireFullPermission, boolean checkShell, String message) {
            PermissionManagerService.this.enforceCrossUserOrProfilePermission(
                    callingUid,
                    userId,
                    requireFullPermission,
                    checkShell,
                    message);
        }

        @Override
        public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
            PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
        }
        @Override
        public PermissionSettings getPermissionSettings() {
            return mSettings;
        }
        @Override
        public BasePermission getPermissionTEMP(String permName) {
            synchronized (PermissionManagerService.this.mLock) {
                return mSettings.getPermissionLocked(permName);
            }
        }

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

            synchronized (mLock) {
                int numTotalPermissions = mSettings.mPermissions.size();

                for (int i = 0; i < numTotalPermissions; i++) {
                    BasePermission bp = mSettings.mPermissions.valueAt(i);

                    if (bp.perm != null && bp.perm.getProtection() == protection) {
                        matchingPermissions.add(
                                PackageInfoUtils.generatePermissionInfo(bp.perm, 0));
                    }
                }
            }

            return matchingPermissions;
        }

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

            synchronized (mLock) {
                int numTotalPermissions = mSettings.mPermissions.size();

                for (int i = 0; i < numTotalPermissions; i++) {
                    BasePermission bp = mSettings.mPermissions.valueAt(i);

                    if (bp.perm != null && (bp.perm.getProtectionFlags() & protectionFlags)
                            == protectionFlags) {
                        matchingPermissions.add(
                                PackageInfoUtils.generatePermissionInfo(bp.perm, 0));
                    }
                }
            }

            return matchingPermissions;
        }

        @Override
        public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
            return PermissionManagerService.this.backupRuntimePermissions(user);
        }

        @Override
        public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
            PermissionManagerService.this.restoreRuntimePermissions(backup, user);
        }

        @Override
        public void restoreDelayedRuntimePermissions(@NonNull String packageName,
                @NonNull UserHandle user) {
            PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
        }

        @Override
        public void addOnRuntimePermissionStateChangedListener(
                OnRuntimePermissionStateChangedListener listener) {
            PermissionManagerService.this.addOnRuntimePermissionStateChangedListener(
                    listener);
        }

        @Override
        public void removeOnRuntimePermissionStateChangedListener(
                OnRuntimePermissionStateChangedListener listener) {
            PermissionManagerService.this.removeOnRuntimePermissionStateChangedListener(
                    listener);
        }

        @Override
        public CheckPermissionDelegate getCheckPermissionDelegate() {
            synchronized (mLock) {
                return mCheckPermissionDelegate;
            }
        }

        @Override
        public void setCheckPermissionDelegate(CheckPermissionDelegate delegate) {
            synchronized (mLock) {
                if (delegate != null || mCheckPermissionDelegate != null) {
                    PackageManager.invalidatePackageInfoCache();
                }
                mCheckPermissionDelegate = delegate;
            }
        }

        @Override
        public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
            synchronized (mLock) {
                mDefaultBrowserProvider = provider;
            }
        }

        @Override
        public void setDefaultBrowser(String packageName, boolean async, boolean doGrant,
                int userId) {
            setDefaultBrowserInternal(packageName, async, doGrant, userId);
        }

        @Override
        public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
            synchronized (mLock) {
                mDefaultDialerProvider = provider;
            }
        }

        @Override
        public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
            synchronized (mLock) {
                mDefaultHomeProvider = provider;
            }
        }

        @Override
        public void setDefaultHome(String packageName, int userId, Consumer<Boolean> callback) {
            if (userId == UserHandle.USER_ALL) {
                return;
            }
            DefaultHomeProvider provider;
            synchronized (mLock) {
                provider = mDefaultHomeProvider;
            }
            if (provider == null) {
                return;
            }
            provider.setDefaultHomeAsync(packageName, userId, callback);
        }

        @Override
        public void setDialerAppPackagesProvider(PackagesProvider provider) {
            synchronized (mLock) {
                mDefaultPermissionGrantPolicy.setDialerAppPackagesProvider(provider);
            }
        }

        @Override
        public void setLocationExtraPackagesProvider(PackagesProvider provider) {
            synchronized (mLock) {
                mDefaultPermissionGrantPolicy.setLocationExtraPackagesProvider(provider);
            }
        }

        @Override
        public void setLocationPackagesProvider(PackagesProvider provider) {
            synchronized (mLock) {
                mDefaultPermissionGrantPolicy.setLocationPackagesProvider(provider);
            }
        }

        @Override
        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
            synchronized (mLock) {
                mDefaultPermissionGrantPolicy.setSimCallManagerPackagesProvider(provider);
            }
        }

        @Override
        public void setSmsAppPackagesProvider(PackagesProvider provider) {
            synchronized (mLock) {
                mDefaultPermissionGrantPolicy.setSmsAppPackagesProvider(provider);
            }
        }

        @Override
        public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
            synchronized (mLock) {
                mDefaultPermissionGrantPolicy.setSyncAdapterPackagesProvider(provider);
            }
        }

        @Override
        public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
            synchronized (mLock) {
                mDefaultPermissionGrantPolicy.setUseOpenWifiAppPackagesProvider(provider);
            }
        }

        @Override
        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
            synchronized (mLock) {
                mDefaultPermissionGrantPolicy.setVoiceInteractionPackagesProvider(provider);
            }
        }

        @Override
        public String getDefaultBrowser(int userId) {
            DefaultBrowserProvider provider;
            synchronized (mLock) {
                provider = mDefaultBrowserProvider;
            }
            return provider != null ? provider.getDefaultBrowser(userId) : null;
        }

        @Override
        public String getDefaultDialer(int userId) {
            DefaultDialerProvider provider;
            synchronized (mLock) {
                provider = mDefaultDialerProvider;
            }
            return provider != null ? provider.getDefaultDialer(userId) : null;
        }

        @Override
        public String getDefaultHome(int userId) {
            DefaultHomeProvider provider;
            synchronized (mLock) {
                provider = mDefaultHomeProvider;
            }
            return provider != null ? provider.getDefaultHome(userId) : null;
        }

        @Override
        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
            synchronized (mLock) {
                mDefaultPermissionGrantPolicy
                        .grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
            }
        }

        @Override
        public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
            synchronized (mLock) {
                mDefaultPermissionGrantPolicy
                        .grantDefaultPermissionsToDefaultUseOpenWifiApp(packageName, userId);
            }
        }

        @Override
        public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
            synchronized (mLock) {
                mDefaultPermissionGrantPolicy
                        .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
            }
        }

        @Override
        public void onNewUserCreated(int userId) {
            mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
            synchronized (mLock) {
                // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
                PermissionManagerService.this.updateAllPermissions(
                        StorageManager.UUID_PRIVATE_INTERNAL, true, mDefaultPermissionCallback);
            }
        }

        @Override
        public void retainHardAndSoftRestrictedPermissions(@NonNull List<String> permissions) {
            synchronized (mLock) {
                Iterator<String> iterator = permissions.iterator();
                while (iterator.hasNext()) {
                    String permission = iterator.next();
                    BasePermission basePermission = mSettings.mPermissions.get(permission);
                    if (basePermission == null || !basePermission.isHardOrSoftRestricted()) {
                        iterator.remove();
                    }
                }
            }
        }
    }

    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 addListenerLocked(IOnPermissionsChangeListener listener) {
            mPermissionListeners.register(listener);

        }

        public void removeListenerLocked(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);
                    } catch (RemoteException e) {
                        Log.e(TAG, "Permission listener is dead", e);
                    }
                }
            } finally {
                mPermissionListeners.finishBroadcast();
            }
        }
    }

    /**
     * Allows injection of services and method responses to facilitate testing.
     *
     * <p>Test classes can create a mock of this class and pass it to the PermissionManagerService
     * constructor to control behavior of services and external methods during execution.
     * @hide
     */
    @VisibleForTesting
    public static class Injector {
        private final Context mContext;

        /**
         * Public constructor that accepts a {@code context} within which to operate.
         */
        public Injector(@NonNull Context context) {
            mContext = context;
        }

        /**
         * Returns the UID of the calling package.
         */
        public int getCallingUid() {
            return Binder.getCallingUid();
        }

        /**
         * Returns the process ID of the calling package.
         */
        public int getCallingPid() {
            return Binder.getCallingPid();
        }

        /**
         * Invalidates the package info cache.
         */
        public void invalidatePackageInfoCache() {
            PackageManager.invalidatePackageInfoCache();
        }

        /**
         * Disables the permission cache.
         */
        public void disablePermissionCache() {
            PermissionManager.disablePermissionCache();
        }

        /**
         * Disables the package name permission cache.
         */
        public void disablePackageNamePermissionCache() {
            PermissionManager.disablePackageNamePermissionCache();
        }

        /**
         * Checks if the package running under the specified {@code pid} and {@code uid} has been
         * granted the provided {@code permission}.
         *
         * @return {@link PackageManager#PERMISSION_GRANTED} if the package has been granted the
         * permission, {@link PackageManager#PERMISSION_DENIED} otherwise
         */
        public int checkPermission(@NonNull String permission, int pid, int uid) {
            return mContext.checkPermission(permission, pid, uid);
        }

        /**
         * Clears the calling identity to allow subsequent calls to be treated as coming from this
         * package.
         *
         * @return a token that can be used to restore the calling identity
         */
        public long clearCallingIdentity() {
            return Binder.clearCallingIdentity();
        }

        /**
         * Restores the calling identity to that of the calling package based on the provided
         * {@code token}.
         */
        public void restoreCallingIdentity(long token) {
            Binder.restoreCallingIdentity(token);
        }

        /**
         * Returns the system service with the provided {@code name}.
         */
        public Object getSystemService(@NonNull String name) {
            return mContext.getSystemService(name);
        }
    }
}
