/*
 * Copyright (C) 2018 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.permissioncontroller.role.model;

import android.app.ActivityManager;
import android.app.role.RoleManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.SharedLibraryInfo;
import android.content.res.Resources;
import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.preference.Preference;

import com.android.modules.utils.build.SdkLevel;
import com.android.permissioncontroller.Constants;
import com.android.permissioncontroller.permission.utils.CollectionUtils;
import com.android.permissioncontroller.permission.utils.Utils;
import com.android.permissioncontroller.role.ui.TwoTargetPreference;
import com.android.permissioncontroller.role.utils.PackageUtils;
import com.android.permissioncontroller.role.utils.RoleManagerCompat;
import com.android.permissioncontroller.role.utils.UserUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * Specifies a role and its properties.
 * <p>
 * A role is a unique name within the system associated with certain privileges. There can be
 * multiple applications qualifying for a role, but only a subset of them can become role holders.
 * To qualify for a role, an application must meet certain requirements, including defining certain
 * components in its manifest. Then the application will need user consent to become the role
 * holder.
 * <p>
 * Upon becoming a role holder, the application may be granted certain permissions, have certain
 * app ops set to certain modes and certain {@code Activity} components configured as preferred for
 * certain {@code Intent} actions. When an application loses its role, these privileges will also be
 * revoked.
 *
 * @see android.app.role.RoleManager
 */
public class Role {

    private static final String LOG_TAG = Role.class.getSimpleName();

    private static final boolean DEBUG = false;

    private static final String PACKAGE_NAME_ANDROID_SYSTEM = "android";

    private static final String PACKAGE_NAME_SEPARATOR = ";";

    /**
     * The name of this role. Must be unique.
     */
    @NonNull
    private final String mName;

    /**
     * Whether this role allows bypassing role holder qualification.
     */
    private final boolean mAllowBypassingQualification;

    /**
     * The behavior of this role.
     */
    @Nullable
    private final RoleBehavior mBehavior;

    @Nullable
    private final String mDefaultHoldersResourceName;

    /**
     * The string resource for the description of this role.
     */
    @StringRes
    private final int mDescriptionResource;

    /**
     * Whether this role is exclusive, i.e. allows at most one holder.
     */
    private final boolean mExclusive;

    /**
     * Whether this role should fall back to the default holder.
     */
    private final boolean mFallBackToDefaultHolder;

    /**
     * The string resource for the label of this role.
     */
    @StringRes
    private final int mLabelResource;

    /**
     * The minimum SDK version for this role to be available.
     */
    private final int mMinSdkVersion;

    /**
     * Whether this role should override user's choice about privileges when granting.
     */
    private final boolean mOverrideUserWhenGranting;

    /**
     * The string resource for the request description of this role, shown below the selected app in
     * the request role dialog.
     */
    @StringRes
    private final int mRequestDescriptionResource;

    /**
     * The string resource for the request title of this role, shown as the title of the request
     * role dialog.
     */
    @StringRes
    private final int mRequestTitleResource;

    /**
     * Whether this role is requestable by applications with
     * {@link android.app.role.RoleManager#createRequestRoleIntent(String)}.
     */
    private final boolean mRequestable;

    /**
     * The string resource for search keywords of this role, in addition to the label of this role,
     * if it's non-zero.
     */
    @StringRes
    private final int mSearchKeywordsResource;

    /**
     * The string resource for the short label of this role, currently used when in a list of roles.
     */
    @StringRes
    private final int mShortLabelResource;

    /**
     * Whether the UI for this role will show the "None" item. Only valid if this role is
     * {@link #mExclusive exclusive}, and {@link #getFallbackHolder(Context)} should also return
     * empty to allow actually selecting "None".
     */
    private final boolean mShowNone;

    /**
     * Whether this role is static, i.e. the role will always be assigned to its default holders.
     */
    private final boolean mStatic;

    /**
     * Whether this role only accepts system apps as its holders.
     */
    private final boolean mSystemOnly;

    /**
     * Whether this role is visible to user.
     */
    private final boolean mVisible;

    /**
     * The required components for an application to qualify for this role.
     */
    @NonNull
    private final List<RequiredComponent> mRequiredComponents;

    /**
     * The permissions to be granted by this role.
     */
    @NonNull
    private final List<Permission> mPermissions;

    /**
     * The app op permissions to be granted by this role.
     */
    @NonNull
    private final List<String> mAppOpPermissions;

    /**
     * The app ops to be set to allowed by this role.
     */
    @NonNull
    private final List<AppOp> mAppOps;

    /**
     * The set of preferred {@code Activity} configurations to be configured by this role.
     */
    @NonNull
    private final List<PreferredActivity> mPreferredActivities;

    public Role(@NonNull String name, boolean allowBypassingQualification,
            @Nullable RoleBehavior behavior, @Nullable String defaultHoldersResourceName,
            @StringRes int descriptionResource, boolean exclusive, boolean fallBackToDefaultHolder,
            @StringRes int labelResource, int minSdkVersion, boolean overrideUserWhenGranting,
            @StringRes int requestDescriptionResource, @StringRes int requestTitleResource,
            boolean requestable, @StringRes int searchKeywordsResource,
            @StringRes int shortLabelResource, boolean showNone, boolean statik, boolean systemOnly,
            boolean visible, @NonNull List<RequiredComponent> requiredComponents,
            @NonNull List<Permission> permissions, @NonNull List<String> appOpPermissions,
            @NonNull List<AppOp> appOps, @NonNull List<PreferredActivity> preferredActivities) {
        mName = name;
        mAllowBypassingQualification = allowBypassingQualification;
        mBehavior = behavior;
        mDefaultHoldersResourceName = defaultHoldersResourceName;
        mDescriptionResource = descriptionResource;
        mExclusive = exclusive;
        mFallBackToDefaultHolder = fallBackToDefaultHolder;
        mLabelResource = labelResource;
        mMinSdkVersion = minSdkVersion;
        mOverrideUserWhenGranting = overrideUserWhenGranting;
        mRequestDescriptionResource = requestDescriptionResource;
        mRequestTitleResource = requestTitleResource;
        mRequestable = requestable;
        mSearchKeywordsResource = searchKeywordsResource;
        mShortLabelResource = shortLabelResource;
        mShowNone = showNone;
        mStatic = statik;
        mSystemOnly = systemOnly;
        mVisible = visible;
        mRequiredComponents = requiredComponents;
        mPermissions = permissions;
        mAppOpPermissions = appOpPermissions;
        mAppOps = appOps;
        mPreferredActivities = preferredActivities;
    }

    @NonNull
    public String getName() {
        return mName;
    }

    /**
     * @see #mAllowBypassingQualification
     */
    public boolean shouldAllowBypassingQualification() {
        return mAllowBypassingQualification;
    }

    @Nullable
    public RoleBehavior getBehavior() {
        return mBehavior;
    }

    @StringRes
    public int getDescriptionResource() {
        return mDescriptionResource;
    }

    public boolean isExclusive() {
        return mExclusive;
    }

    @StringRes
    public int getLabelResource() {
        return mLabelResource;
    }

    @StringRes
    public int getRequestDescriptionResource() {
        return mRequestDescriptionResource;
    }

    @StringRes
    public int getRequestTitleResource() {
        return mRequestTitleResource;
    }

    public boolean isRequestable() {
        return mRequestable;
    }

    @StringRes
    public int getSearchKeywordsResource() {
        return mSearchKeywordsResource;
    }

    @StringRes
    public int getShortLabelResource() {
        return mShortLabelResource;
    }

    /**
     * @see #mOverrideUserWhenGranting
     */
    public boolean shouldOverrideUserWhenGranting() {
        return mOverrideUserWhenGranting;
    }

    /**
     * @see #mShowNone
     */
    public boolean shouldShowNone() {
        return mShowNone;
    }

    public boolean isVisible() {
        return mVisible;
    }

    @NonNull
    public List<RequiredComponent> getRequiredComponents() {
        return mRequiredComponents;
    }

    @NonNull
    public List<Permission> getPermissions() {
        return mPermissions;
    }

    @NonNull
    public List<String> getAppOpPermissions() {
        return mAppOpPermissions;
    }

    @NonNull
    public List<AppOp> getAppOps() {
        return mAppOps;
    }

    @NonNull
    public List<PreferredActivity> getPreferredActivities() {
        return mPreferredActivities;
    }

    /**
     * Callback when this role is added to the system for the first time.
     *
     * @param context the {@code Context} to retrieve system services
     */
    public void onRoleAdded(@NonNull Context context) {
        if (mBehavior != null) {
            mBehavior.onRoleAdded(this, context);
        }
    }

    /**
     * Check whether this role is available.
     *
     * @param user the user to check for
     * @param context the {@code Context} to retrieve system services
     *
     * @return whether this role is available.
     */
    public boolean isAvailableAsUser(@NonNull UserHandle user, @NonNull Context context) {
        if (!isAvailableBySdkVersion()) {
            return false;
        }
        if (mBehavior != null) {
            return mBehavior.isAvailableAsUser(this, user, context);
        }
        return true;
    }

    /**
     * Check whether this role is available based on SDK version.
     *
     * @return whether this role is available based on SDK version
     */
    boolean isAvailableBySdkVersion() {
        // Workaround to match the value 31+ for S+ in roles.xml before SDK finalization.
        if (mMinSdkVersion >= 31) {
            return SdkLevel.isAtLeastS();
        } else {
            return Build.VERSION.SDK_INT >= mMinSdkVersion;
        }
    }

    /**
     * Check whether this role is available, for current user.
     *
     * @param context the {@code Context} to retrieve system services
     *
     * @return whether this role is available.
     */
    public boolean isAvailable(@NonNull Context context) {
        return isAvailableAsUser(Process.myUserHandle(), context);
    }

    public boolean isStatic() {
        return mStatic;
    }

    /**
     * Get the default holders of this role, which will be added when the role is added for the
     * first time.
     *
     * @param context the {@code Context} to retrieve system services
     *
     * @return the list of package names of the default holders
     */
    @NonNull
    public List<String> getDefaultHolders(@NonNull Context context) {
        if (mDefaultHoldersResourceName == null) {
            if (mBehavior != null) {
                return mBehavior.getDefaultHolders(this, context);
            }
            return Collections.emptyList();
        }

        Resources resources = context.getResources();
        int resourceId = resources.getIdentifier(mDefaultHoldersResourceName, "string", "android");
        if (resourceId == 0) {
            Log.w(LOG_TAG, "Cannot find resource for default holder: "
                    + mDefaultHoldersResourceName);
            return Collections.emptyList();
        }

        String resourceValue;
        try {
            resourceValue = resources.getString(resourceId);
        } catch (Resources.NotFoundException e) {
            Log.w(LOG_TAG, "Cannot get resource for default holder: " + mDefaultHoldersResourceName,
                    e);
            return Collections.emptyList();
        }
        if (TextUtils.isEmpty(resourceValue)) {
            return Collections.emptyList();
        }

        if (isExclusive()) {
            if (!isDefaultHolderQualified(resourceValue, context)) {
                return Collections.emptyList();
            }
            return Collections.singletonList(resourceValue);
        } else {
            String[] resourcePackageNames = resourceValue.split(PACKAGE_NAME_SEPARATOR);
            List<String> packageNames = new ArrayList<>();
            for (String packageName : resourcePackageNames) {
                if (isDefaultHolderQualified(packageName, context)) {
                    packageNames.add(packageName);
                }
            }
            return packageNames;
        }
    }

    private boolean isDefaultHolderQualified(@NonNull String packageName,
            @NonNull Context context) {
        ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, context);
        if (applicationInfo == null) {
            Log.w(LOG_TAG, "Cannot get ApplicationInfo for default holder: " + packageName);
            return false;
        }

        if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
            Log.w(LOG_TAG, "Default holder is not a system app: " + packageName);
            return false;
        }

        return true;
    }

    /**
     * Get the fallback holder of this role, which will be added whenever there are no role holders.
     * <p>
     * Should return {@code null} if this role {@link #mShowNone shows a "None" item}.
     *
     * @param context the {@code Context} to retrieve system services
     *
     * @return the package name of the fallback holder, or {@code null} if none
     */
    @Nullable
    public String getFallbackHolder(@NonNull Context context) {
        if (isNoneHolderSelected(context)) {
            return null;
        }
        if (mFallBackToDefaultHolder) {
            return CollectionUtils.firstOrNull(getDefaultHolders(context));
        }
        if (mBehavior != null) {
            return mBehavior.getFallbackHolder(this, context);
        }
        return null;
    }

    /**
     * Check whether this role should be visible to user.
     *
     * @param user the user to check for
     * @param context the {@code Context} to retrieve system services
     *
     * @return whether this role should be visible to user
     */
    public boolean isVisibleAsUser(@NonNull UserHandle user, @NonNull Context context) {
        return mVisible && (mBehavior == null || mBehavior.isVisibleAsUser(this, user, context));
    }

    /**
     * Check whether this role should be visible to user, for current user.
     *
     * @param context the {@code Context} to retrieve system services
     *
     * @return whether this role should be visible to user.
     */
    public boolean isVisible(@NonNull Context context) {
        return isVisibleAsUser(Process.myUserHandle(), context);
    }

    /**
     * Get the {@link Intent} to manage this role, or {@code null} to use the default UI.
     *
     * @param user the user to manage this role for
     * @param context the {@code Context} to retrieve system services
     *
     * @return the {@link Intent} to manage this role, or {@code null} to use the default UI.
     */
    @Nullable
    public Intent getManageIntentAsUser(@NonNull UserHandle user, @NonNull Context context) {
        if (mBehavior != null) {
            return mBehavior.getManageIntentAsUser(this, user, context);
        }
        return null;
    }

    /**
     * Prepare a {@link Preference} for this role.
     *
     * @param preference the {@link Preference} for this role
     * @param user the user for this role
     * @param context the {@code Context} to retrieve system services
     */
    public void preparePreferenceAsUser(@NonNull TwoTargetPreference preference,
            @NonNull UserHandle user, @NonNull Context context) {
        if (mBehavior != null) {
            mBehavior.preparePreferenceAsUser(this, preference, user, context);
        }
    }

    /**
     * Check whether a qualifying application should be visible to user.
     *
     * @param applicationInfo the {@link ApplicationInfo} for the application
     * @param user the user for the application
     * @param context the {@code Context} to retrieve system services
     *
     * @return whether the qualifying application should be visible to user
     */
    public boolean isApplicationVisibleAsUser(@NonNull ApplicationInfo applicationInfo,
            @NonNull UserHandle user, @NonNull Context context) {
        if (mBehavior != null) {
            return mBehavior.isApplicationVisibleAsUser(this, applicationInfo, user, context);
        }
        return true;
    }

    /**
     * Prepare a {@link Preference} for an application.
     *
     * @param preference the {@link Preference} for the application
     * @param applicationInfo the {@link ApplicationInfo} for the application
     * @param user the user for the application
     * @param context the {@code Context} to retrieve system services
     */
    public void prepareApplicationPreferenceAsUser(@NonNull Preference preference,
            @NonNull ApplicationInfo applicationInfo, @NonNull UserHandle user,
            @NonNull Context context) {
        if (mBehavior != null) {
            mBehavior.prepareApplicationPreferenceAsUser(this, preference, applicationInfo, user,
                    context);
        }
    }

    /**
     * Get the confirmation message for adding an application as a holder of this role.
     *
     * @param packageName the package name of the application to get confirmation message for
     * @param context the {@code Context} to retrieve system services
     *
     * @return the confirmation message, or {@code null} if no confirmation is needed
     */
    @Nullable
    public CharSequence getConfirmationMessage(@NonNull String packageName,
            @NonNull Context context) {
        if (mBehavior != null) {
            return mBehavior.getConfirmationMessage(this, packageName, context);
        }
        return null;
    }

    /**
     * Check whether a package is qualified for this role, i.e. whether it contains all the required
     * components (plus meeting some other general restrictions).
     *
     * @param packageName the package name to check for
     * @param context the {@code Context} to retrieve system services
     *
     * @return whether the package is qualified for a role
     */
    public boolean isPackageQualified(@NonNull String packageName, @NonNull Context context) {
        RoleManager roleManager = context.getSystemService(RoleManager.class);
        if (mAllowBypassingQualification
                && RoleManagerCompat.isBypassingRoleQualification(roleManager)) {
            return true;
        }

        if (!isPackageMinimallyQualifiedAsUser(packageName, Process.myUserHandle(), context)) {
            return false;
        }

        if (mBehavior != null) {
            Boolean isPackageQualified = mBehavior.isPackageQualified(this, packageName, context);
            if (isPackageQualified != null) {
                return isPackageQualified;
            }
        }

        int requiredComponentsSize = mRequiredComponents.size();
        for (int i = 0; i < requiredComponentsSize; i++) {
            RequiredComponent requiredComponent = mRequiredComponents.get(i);
            if (requiredComponent.getQualifyingComponentForPackage(packageName, context) == null) {
                Log.i(LOG_TAG, packageName + " not qualified for " + mName
                        + " due to missing " + requiredComponent);
                return false;
            }
        }

        if (mStatic && !getDefaultHolders(context).contains(packageName)) {
            return false;
        }

        return true;
    }

    /**
     * Get the list of packages that are qualified for this role, i.e. packages containing all the
     * required components (plus meeting some other general restrictions).
     *
     * @param user the user to get the qualifying packages.
     * @param context the {@code Context} to retrieve system services
     *
     * @return the list of packages that are qualified for this role
     */
    @NonNull
    public List<String> getQualifyingPackagesAsUser(@NonNull UserHandle user,
            @NonNull Context context) {
        List<String> qualifyingPackages = null;

        if (mBehavior != null) {
            qualifyingPackages = mBehavior.getQualifyingPackagesAsUser(this, user, context);
        }

        if (qualifyingPackages == null) {
            ArrayMap<String, Integer> packageComponentCountMap = new ArrayMap<>();
            int requiredComponentsSize = mRequiredComponents.size();
            for (int requiredComponentsIndex = 0; requiredComponentsIndex < requiredComponentsSize;
                    requiredComponentsIndex++) {
                RequiredComponent requiredComponent = mRequiredComponents.get(
                        requiredComponentsIndex);

                // This returns at most one component per package.
                List<ComponentName> qualifyingComponents =
                        requiredComponent.getQualifyingComponentsAsUser(user, context);
                int qualifyingComponentsSize = qualifyingComponents.size();
                for (int qualifyingComponentsIndex = 0;
                        qualifyingComponentsIndex < qualifyingComponentsSize;
                        ++qualifyingComponentsIndex) {
                    ComponentName componentName = qualifyingComponents.get(
                            qualifyingComponentsIndex);

                    String packageName = componentName.getPackageName();
                    Integer componentCount = packageComponentCountMap.get(packageName);
                    packageComponentCountMap.put(packageName, componentCount == null ? 1
                            : componentCount + 1);
                }
            }

            qualifyingPackages = new ArrayList<>();
            int packageComponentCountMapSize = packageComponentCountMap.size();
            for (int i = 0; i < packageComponentCountMapSize; i++) {
                int componentCount = packageComponentCountMap.valueAt(i);

                if (componentCount != requiredComponentsSize) {
                    continue;
                }
                String packageName = packageComponentCountMap.keyAt(i);
                qualifyingPackages.add(packageName);
            }
        }

        int qualifyingPackagesSize = qualifyingPackages.size();
        for (int i = 0; i < qualifyingPackagesSize; ) {
            String packageName = qualifyingPackages.get(i);

            if (!isPackageMinimallyQualifiedAsUser(packageName, user, context)) {
                qualifyingPackages.remove(i);
                qualifyingPackagesSize--;
            } else {
                i++;
            }
        }

        return qualifyingPackages;
    }

    private boolean isPackageMinimallyQualifiedAsUser(
            @NonNull String packageName, @NonNull UserHandle user, @NonNull Context context) {
        if (Objects.equals(packageName, PACKAGE_NAME_ANDROID_SYSTEM)) {
            return false;
        }

        ApplicationInfo applicationInfo = PackageUtils.getApplicationInfoAsUser(packageName, user,
                context);
        if (applicationInfo == null) {
            Log.w(LOG_TAG, "Cannot get ApplicationInfo for package: " + packageName + ", user: "
                    + user.getIdentifier());
            return false;
        }

        if (mSystemOnly && (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
            return false;
        }

        if (!applicationInfo.enabled) {
            return false;
        }

        if (applicationInfo.isInstantApp()) {
            return false;
        }

        PackageManager userPackageManager = UserUtils.getUserContext(context, user)
                .getPackageManager();
        List<SharedLibraryInfo> declaredLibraries = userPackageManager.getDeclaredSharedLibraries(
                packageName, 0);
        final int libCount = declaredLibraries.size();
        for (int i = 0; i < libCount; i++) {
            SharedLibraryInfo sharedLibrary = declaredLibraries.get(i);
            if (sharedLibrary.getType() != SharedLibraryInfo.TYPE_DYNAMIC) {
                return false;
            }
        }

        return true;
    }

    /**
     * Grant this role to an application.
     *
     * @param packageName the package name of the application to be granted this role to
     * @param dontKillApp whether this application should not be killed despite changes
     * @param overrideUserSetAndFixedPermissions whether to override user set and fixed flags on
     *                                           permissions
     * @param context the {@code Context} to retrieve system services
     */
    public void grant(@NonNull String packageName, boolean dontKillApp,
            boolean overrideUserSetAndFixedPermissions, @NonNull Context context) {
        boolean permissionOrAppOpChanged = Permissions.grant(packageName,
                Permissions.filterBySdkVersion(mPermissions),
                SdkLevel.isAtLeastS() ? !mSystemOnly : true, overrideUserSetAndFixedPermissions,
                true, false, false, context);

        int appOpPermissionsSize = mAppOpPermissions.size();
        for (int i = 0; i < appOpPermissionsSize; i++) {
            String appOpPermissions = mAppOpPermissions.get(i);
            AppOpPermissions.grant(packageName, appOpPermissions, context);
        }

        int appOpsSize = mAppOps.size();
        for (int i = 0; i < appOpsSize; i++) {
            AppOp appOp = mAppOps.get(i);
            appOp.grant(packageName, context);
        }

        int preferredActivitiesSize = mPreferredActivities.size();
        for (int i = 0; i < preferredActivitiesSize; i++) {
            PreferredActivity preferredActivity = mPreferredActivities.get(i);
            preferredActivity.configure(packageName, context);
        }

        if (mBehavior != null) {
            mBehavior.grant(this, packageName, context);
        }

        if (!dontKillApp && permissionOrAppOpChanged && !Permissions.isRuntimePermissionsSupported(
                packageName, context)) {
            killApp(packageName, context);
        }
    }

    /**
     * Revoke this role from an application.
     *
     * @param packageName the package name of the application to be granted this role to
     * @param dontKillApp whether this application should not be killed despite changes
     * @param overrideSystemFixedPermissions whether system-fixed permissions can be revoked
     * @param context the {@code Context} to retrieve system services
     */
    public void revoke(@NonNull String packageName, boolean dontKillApp,
            boolean overrideSystemFixedPermissions, @NonNull Context context) {
        RoleManager roleManager = context.getSystemService(RoleManager.class);
        List<String> otherRoleNames = roleManager.getHeldRolesFromController(packageName);
        otherRoleNames.remove(mName);

        List<String> permissionsToRevoke = Permissions.filterBySdkVersion(mPermissions);
        ArrayMap<String, Role> roles = Roles.get(context);
        int otherRoleNamesSize = otherRoleNames.size();
        for (int i = 0; i < otherRoleNamesSize; i++) {
            String roleName = otherRoleNames.get(i);
            Role role = roles.get(roleName);
            permissionsToRevoke.removeAll(Permissions.filterBySdkVersion(role.mPermissions));
        }

        boolean permissionOrAppOpChanged = Permissions.revoke(packageName, permissionsToRevoke,
                true, false, overrideSystemFixedPermissions, context);

        List<String> appOpPermissionsToRevoke = new ArrayList<>(mAppOpPermissions);
        for (int i = 0; i < otherRoleNamesSize; i++) {
            String roleName = otherRoleNames.get(i);
            Role role = roles.get(roleName);
            appOpPermissionsToRevoke.removeAll(role.mAppOpPermissions);
        }
        int appOpPermissionsSize = appOpPermissionsToRevoke.size();
        for (int i = 0; i < appOpPermissionsSize; i++) {
            String appOpPermission = appOpPermissionsToRevoke.get(i);
            AppOpPermissions.revoke(packageName, appOpPermission, context);
        }

        List<AppOp> appOpsToRevoke = new ArrayList<>(mAppOps);
        for (int i = 0; i < otherRoleNamesSize; i++) {
            String roleName = otherRoleNames.get(i);
            Role role = roles.get(roleName);
            appOpsToRevoke.removeAll(role.mAppOps);
        }
        int appOpsSize = appOpsToRevoke.size();
        for (int i = 0; i < appOpsSize; i++) {
            AppOp appOp = appOpsToRevoke.get(i);
            appOp.revoke(packageName, context);
        }

        // TODO: Revoke preferred activities? But this is unnecessary for most roles using it as
        //  they have fallback holders. Moreover, clearing the preferred activity might result in
        //  other system components listening to preferred activity change get notified for the
        //  wrong thing when we are removing a exclusive role holder for adding another.

        if (mBehavior != null) {
            mBehavior.revoke(this, packageName, context);
        }

        if (!dontKillApp && permissionOrAppOpChanged) {
            killApp(packageName, context);
        }
    }

    private void killApp(@NonNull String packageName, @NonNull Context context) {
        if (DEBUG) {
            Log.i(LOG_TAG, "Killing " + packageName + " due to "
                    + Thread.currentThread().getStackTrace()[3].getMethodName()
                    + "(" + mName + ")");
        }
        ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, context);
        if (applicationInfo == null) {
            Log.w(LOG_TAG, "Cannot get ApplicationInfo for package: " + packageName);
            return;
        }
        ActivityManager activityManager = context.getSystemService(ActivityManager.class);
        activityManager.killUid(applicationInfo.uid, "Permission or app op changed");
    }

    /**
     * Check whether the "none" role holder is selected.
     *
     * @param context the {@code Context} to retrieve system services
     *
     * @return whether the "none" role holder is selected
     */
    private boolean isNoneHolderSelected(@NonNull Context context) {
        return Utils.getDeviceProtectedSharedPreferences(context).getBoolean(
                Constants.IS_NONE_ROLE_HOLDER_SELECTED_KEY + mName, false);
    }

    /**
     * Callback when a role holder (other than "none") was added.
     *
     * @param packageName the package name of the role holder
     * @param user the user for the role
     * @param context the {@code Context} to retrieve system services
     */
    public void onHolderAddedAsUser(@NonNull String packageName, @NonNull UserHandle user,
            @NonNull Context context) {
        Utils.getDeviceProtectedSharedPreferences(UserUtils.getUserContext(context, user)).edit()
                .remove(Constants.IS_NONE_ROLE_HOLDER_SELECTED_KEY + mName)
                .apply();
    }

    /**
     * Callback when a role holder (other than "none") was selected in the UI and added
     * successfully.
     *
     * @param packageName the package name of the role holder
     * @param user the user for the role
     * @param context the {@code Context} to retrieve system services
     */
    public void onHolderSelectedAsUser(@NonNull String packageName, @NonNull UserHandle user,
            @NonNull Context context) {
        if (mBehavior != null) {
            mBehavior.onHolderSelectedAsUser(this, packageName, user, context);
        }
    }

    /**
     * Callback when a role holder changed.
     *
     * @param user the user for the role
     * @param context the {@code Context} to retrieve system services
     */
    public void onHolderChangedAsUser(@NonNull UserHandle user,
            @NonNull Context context) {
        if (mBehavior != null) {
            mBehavior.onHolderChangedAsUser(this, user, context);
        }
    }

    /**
     * Callback when the "none" role holder was selected in the UI.
     *
     * @param user the user for the role
     * @param context the {@code Context} to retrieve system services
     */
    public void onNoneHolderSelectedAsUser(@NonNull UserHandle user, @NonNull Context context) {
        Utils.getDeviceProtectedSharedPreferences(UserUtils.getUserContext(context, user)).edit()
                .putBoolean(Constants.IS_NONE_ROLE_HOLDER_SELECTED_KEY + mName, true)
                .apply();
    }

    @Override
    public String toString() {
        return "Role{"
                + "mName='" + mName + '\''
                + ", mAllowBypassingQualification=" + mAllowBypassingQualification
                + ", mBehavior=" + mBehavior
                + ", mDefaultHoldersResourceName=" + mDefaultHoldersResourceName
                + ", mDescriptionResource=" + mDescriptionResource
                + ", mExclusive=" + mExclusive
                + ", mFallBackToDefaultHolder=" + mFallBackToDefaultHolder
                + ", mLabelResource=" + mLabelResource
                + ", mMinSdkVersion=" + mMinSdkVersion
                + ", mOverrideUserWhenGranting=" + mOverrideUserWhenGranting
                + ", mRequestDescriptionResource=" + mRequestDescriptionResource
                + ", mRequestTitleResource=" + mRequestTitleResource
                + ", mRequestable=" + mRequestable
                + ", mSearchKeywordsResource=" + mSearchKeywordsResource
                + ", mShortLabelResource=" + mShortLabelResource
                + ", mShowNone=" + mShowNone
                + ", mStatic=" + mStatic
                + ", mSystemOnly=" + mSystemOnly
                + ", mVisible=" + mVisible
                + ", mRequiredComponents=" + mRequiredComponents
                + ", mPermissions=" + mPermissions
                + ", mAppOpPermissions=" + mAppOpPermissions
                + ", mAppOps=" + mAppOps
                + ", mPreferredActivities=" + mPreferredActivities
                + '}';
    }
}
