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

import android.Manifest;
import android.app.DownloadManager;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal.PackagesProvider;
import android.content.pm.PackageParser;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.os.UserHandle;
import android.provider.MediaStore;
import android.util.ArraySet;
import android.util.Log;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import static android.os.Process.FIRST_APPLICATION_UID;

/**
 * This class is the policy for granting runtime permissions to
 * platform components and default handlers in the system such
 * that the device is usable out-of-the-box. For example, the
 * shell UID is a part of the system and the Phone app should
 * have phone related permission by default.
 */
final class DefaultPermissionGrantPolicy {
    private static final String TAG = "DefaultPermGrantPolicy"; // must be <= 23 chars
    private static final boolean DEBUG = false;

    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";

    private static final Set<String> PHONE_PERMISSIONS = new ArraySet<>();
    static {
        PHONE_PERMISSIONS.add(Manifest.permission.READ_PHONE_STATE);
        PHONE_PERMISSIONS.add(Manifest.permission.CALL_PHONE);
        PHONE_PERMISSIONS.add( Manifest.permission.READ_CALL_LOG);
        PHONE_PERMISSIONS.add(Manifest.permission.WRITE_CALL_LOG);
        PHONE_PERMISSIONS.add(Manifest.permission.ADD_VOICEMAIL);
        PHONE_PERMISSIONS.add(Manifest.permission.USE_SIP);
        PHONE_PERMISSIONS.add(Manifest.permission.PROCESS_OUTGOING_CALLS);
    }

    private static final Set<String> CONTACTS_PERMISSIONS = new ArraySet<>();
    static {
        CONTACTS_PERMISSIONS.add(Manifest.permission.READ_CONTACTS);
        CONTACTS_PERMISSIONS.add(Manifest.permission.WRITE_CONTACTS);
    }

    private static final Set<String> LOCATION_PERMISSIONS = new ArraySet<>();
    static {
        LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_FINE_LOCATION);
        LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_COARSE_LOCATION);
    }

    private static final Set<String> CALENDAR_PERMISSIONS = new ArraySet<>();
    static {
        CALENDAR_PERMISSIONS.add(Manifest.permission.READ_CALENDAR);
        CALENDAR_PERMISSIONS.add(Manifest.permission.WRITE_CALENDAR);
    }

    private static final Set<String> SMS_PERMISSIONS = new ArraySet<>();
    static {
        SMS_PERMISSIONS.add(Manifest.permission.SEND_SMS);
        SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_SMS);
        SMS_PERMISSIONS.add(Manifest.permission.READ_SMS);
        SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_WAP_PUSH);
        SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_MMS);
        SMS_PERMISSIONS.add(Manifest.permission.READ_CELL_BROADCASTS);
    }

    private static final Set<String> MICROPHONE_PERMISSIONS = new ArraySet<>();
    static {
        MICROPHONE_PERMISSIONS.add(Manifest.permission.RECORD_AUDIO);
    }

    private static final Set<String> CAMERA_PERMISSIONS = new ArraySet<>();
    static {
        CAMERA_PERMISSIONS.add(Manifest.permission.CAMERA);
    }

    private static final Set<String> SENSORS_PERMISSIONS = new ArraySet<>();
    static {
        SENSORS_PERMISSIONS.add(Manifest.permission.BODY_SENSORS);
    }

    private static final Set<String> STORAGE_PERMISSIONS = new ArraySet<>();
    static {
        STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }

    private static final Set<String> SETTINGS_PERMISSIONS = new ArraySet<>();
    static {
        SETTINGS_PERMISSIONS.add(Manifest.permission.WRITE_SETTINGS);
    }

    private static final Set<String> INSTALLER_PERMISSIONS = new ArraySet<>();
    static {
        INSTALLER_PERMISSIONS.add(Manifest.permission.GRANT_REVOKE_PERMISSIONS);
        INSTALLER_PERMISSIONS.add(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
        INSTALLER_PERMISSIONS.add(Manifest.permission.CLEAR_APP_USER_DATA);
        INSTALLER_PERMISSIONS.add(Manifest.permission.KILL_UID);
    }

    private static final Set<String> VERIFIER_PERMISSIONS = new ArraySet<>();
    static {
        INSTALLER_PERMISSIONS.add(Manifest.permission.GRANT_REVOKE_PERMISSIONS);
    }

    private final PackageManagerService mService;

    private PackagesProvider mImePackagesProvider;
    private PackagesProvider mLocationPackagesProvider;
    private PackagesProvider mVoiceInteractionPackagesProvider;
    private PackagesProvider mCarrierAppPackagesProvider;

    public DefaultPermissionGrantPolicy(PackageManagerService service) {
        mService = service;
    }

    public void setImePackagesProviderLPr(PackagesProvider provider) {
        mImePackagesProvider = provider;
    }

    public void setLocationPackagesProviderLPw(PackagesProvider provider) {
        mLocationPackagesProvider = provider;
    }

    public void setVoiceInteractionPackagesProviderLPw(PackagesProvider provider) {
        mVoiceInteractionPackagesProvider = provider;
    }

    public void setCarrierAppPackagesProviderLPw(PackagesProvider provider) {
        mCarrierAppPackagesProvider = provider;
    }

    public void grantDefaultPermissions(int userId) {
        grantPermissionsToSysComponentsAndPrivApps(userId);
        grantDefaultSystemHandlerPermissions(userId);
    }

    private void grantPermissionsToSysComponentsAndPrivApps(int userId) {
        Log.i(TAG, "Granting permissions to platform components");

        synchronized (mService.mPackages) {
            for (PackageParser.Package pkg : mService.mPackages.values()) {
                if (!isSysComponentOrPersistentPrivApp(pkg)
                        || !doesPackageSupportRuntimePermissions(pkg)) {
                    continue;
                }
                final int permissionCount = pkg.requestedPermissions.size();
                for (int i = 0; i < permissionCount; i++) {
                    String permission = pkg.requestedPermissions.get(i);
                    BasePermission bp = mService.mSettings.mPermissions.get(permission);
                    if (bp != null && bp.isRuntime()) {
                        final int flags = mService.getPermissionFlags(permission,
                                pkg.packageName, userId);
                        if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) == 0) {
                            mService.grantRuntimePermission(pkg.packageName, permission, userId);
                            mService.updatePermissionFlags(permission, pkg.packageName,
                                    PackageManager.MASK_PERMISSION_FLAGS,
                                    PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, userId);
                            if (DEBUG) {
                                Log.i(TAG, "Granted " + permission + " to system component "
                                        + pkg.packageName);
                            }
                        }
                    }
                }
            }
        }
    }

    private void grantDefaultSystemHandlerPermissions(int userId) {
        Log.i(TAG, "Granting permissions to default platform handlers");

        final PackagesProvider imePackagesProvider;
        final PackagesProvider locationPackagesProvider;
        final PackagesProvider voiceInteractionPackagesProvider;
        final PackagesProvider carrierAppPackagesProvider;

        synchronized (mService.mPackages) {
            imePackagesProvider = mImePackagesProvider;
            locationPackagesProvider = mLocationPackagesProvider;
            voiceInteractionPackagesProvider = mVoiceInteractionPackagesProvider;
            carrierAppPackagesProvider = mCarrierAppPackagesProvider;
        }

        String[] imePackageNames = (imePackagesProvider != null)
                ? imePackagesProvider.getPackages(userId) : null;
        String[] voiceInteractPackageNames = (voiceInteractionPackagesProvider != null)
                ? voiceInteractionPackagesProvider.getPackages(userId) : null;
        String[] locationPackageNames = (locationPackagesProvider != null)
                ? locationPackagesProvider.getPackages(userId) : null;
        String[] carrierAppPackageNames = (carrierAppPackagesProvider != null)
                ? carrierAppPackagesProvider.getPackages(userId) : null;

        synchronized (mService.mPackages) {
            // Installers
            Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
            installerIntent.addCategory(Intent.CATEGORY_DEFAULT);
            installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")),
                    PACKAGE_MIME_TYPE);
            List<PackageParser.Package> installerPackages =
                    getPrivilegedHandlerActivityPackagesLPr(installerIntent, userId);
            final int installerCount = installerPackages.size();
            for (int i = 0; i < installerCount; i++) {
                PackageParser.Package installPackage = installerPackages.get(i);
                grantInstallPermissionsLPw(installPackage, INSTALLER_PERMISSIONS, userId);
                grantRuntimePermissionsLPw(installPackage, STORAGE_PERMISSIONS, userId);
            }

            // Verifiers
            Intent verifierIntent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
            verifierIntent.setType(PACKAGE_MIME_TYPE);
            List<PackageParser.Package> verifierPackages =
                    getPrivilegedHandlerReceiverPackagesLPr(verifierIntent, userId);
            final int verifierCount = verifierPackages.size();
            for (int i = 0; i < verifierCount; i++) {
                PackageParser.Package verifierPackage = verifierPackages.get(i);
                grantInstallPermissionsLPw(verifierPackage, VERIFIER_PERMISSIONS, userId);
                grantRuntimePermissionsLPw(verifierPackage, STORAGE_PERMISSIONS, userId);
            }

            // SetupWizard
            Intent setupIntent = new Intent(Intent.ACTION_MAIN);
            setupIntent.addCategory(Intent.CATEGORY_HOME);
            PackageParser.Package setupPackage = getDefaultSystemHandlerActvityPackageLPr(
                    setupIntent, userId);
            if (setupPackage != null
                    && doesPackageSupportRuntimePermissions(setupPackage)) {
                grantRuntimePermissionsLPw(setupPackage, PHONE_PERMISSIONS, userId);
                grantRuntimePermissionsLPw(setupPackage, CONTACTS_PERMISSIONS, userId);
                grantRuntimePermissionsLPw(setupPackage, SETTINGS_PERMISSIONS, userId);
            }

            // Phone
            Intent dialerIntent = new Intent(Intent.ACTION_DIAL);
            PackageParser.Package dialerPackage = getDefaultSystemHandlerActvityPackageLPr(
                    dialerIntent, userId);
            if (dialerPackage != null
                    && doesPackageSupportRuntimePermissions(dialerPackage)) {
                grantRuntimePermissionsLPw(dialerPackage, PHONE_PERMISSIONS, userId);
                grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId);
                grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId);
                grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId);
            }

            // Camera
            Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            PackageParser.Package cameraPackage = getDefaultSystemHandlerActvityPackageLPr(
                    cameraIntent, userId);
            if (cameraPackage != null
                    && doesPackageSupportRuntimePermissions(cameraPackage)) {
                grantRuntimePermissionsLPw(cameraPackage, CAMERA_PERMISSIONS, userId);
                grantRuntimePermissionsLPw(cameraPackage, MICROPHONE_PERMISSIONS, userId);
                grantRuntimePermissionsLPw(cameraPackage, STORAGE_PERMISSIONS, userId);
            }

            // Media provider
            PackageParser.Package mediaStorePackage = getDefaultProviderAuthorityPackageLPr(
                    MediaStore.AUTHORITY, userId);
            if (mediaStorePackage != null) {
                grantRuntimePermissionsLPw(mediaStorePackage, STORAGE_PERMISSIONS, userId);
            }

            // Downloads provider
            PackageParser.Package downloadsPackage = getDefaultProviderAuthorityPackageLPr(
                    "downloads", userId);
            if (downloadsPackage != null) {
                grantRuntimePermissionsLPw(downloadsPackage, STORAGE_PERMISSIONS, userId);
            }

            // Downloads UI
            Intent downloadsUiIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
            PackageParser.Package downloadsUiPackage = getDefaultSystemHandlerActvityPackageLPr(
                    downloadsUiIntent, userId);
            if (downloadsUiPackage != null
                    && doesPackageSupportRuntimePermissions(downloadsUiPackage)) {
                grantRuntimePermissionsLPw(downloadsUiPackage, STORAGE_PERMISSIONS, userId);
            }

            // Messaging
            Intent messagingIntent = new Intent(Intent.ACTION_MAIN);
            messagingIntent.addCategory(Intent.CATEGORY_APP_MESSAGING);
            PackageParser.Package messagingPackage = getDefaultSystemHandlerActvityPackageLPr(
                    messagingIntent, userId);
            if (messagingPackage != null
                    && doesPackageSupportRuntimePermissions(messagingPackage)) {
                grantRuntimePermissionsLPw(messagingPackage, PHONE_PERMISSIONS, userId);
                grantRuntimePermissionsLPw(messagingPackage, CONTACTS_PERMISSIONS, userId);
                grantRuntimePermissionsLPw(messagingPackage, SMS_PERMISSIONS, userId);
            }

            // Calendar
            Intent calendarIntent = new Intent(Intent.ACTION_MAIN);
            calendarIntent.addCategory(Intent.CATEGORY_APP_CALENDAR);
            PackageParser.Package calendarPackage = getDefaultSystemHandlerActvityPackageLPr(
                    calendarIntent, userId);
            if (calendarPackage != null
                    && doesPackageSupportRuntimePermissions(calendarPackage)) {
                grantRuntimePermissionsLPw(calendarPackage, CALENDAR_PERMISSIONS, userId);
                grantRuntimePermissionsLPw(calendarPackage, CONTACTS_PERMISSIONS, userId);
            }

            // Contacts
            Intent contactsIntent = new Intent(Intent.ACTION_MAIN);
            contactsIntent.addCategory(Intent.CATEGORY_APP_CONTACTS);
            PackageParser.Package contactsPackage = getDefaultSystemHandlerActvityPackageLPr(
                    contactsIntent, userId);
            if (contactsPackage != null
                    && doesPackageSupportRuntimePermissions(contactsPackage)) {
                grantRuntimePermissionsLPw(contactsPackage, CONTACTS_PERMISSIONS, userId);
                grantRuntimePermissionsLPw(contactsPackage, PHONE_PERMISSIONS, userId);
            }

            // Maps
            Intent mapsIntent = new Intent(Intent.ACTION_MAIN);
            mapsIntent.addCategory(Intent.CATEGORY_APP_MAPS);
            PackageParser.Package mapsPackage = getDefaultSystemHandlerActvityPackageLPr(
                    mapsIntent, userId);
            if (mapsPackage != null
                    && doesPackageSupportRuntimePermissions(mapsPackage)) {
                grantRuntimePermissionsLPw(mapsPackage, LOCATION_PERMISSIONS, userId);
            }

            // Email
            Intent emailIntent = new Intent(Intent.ACTION_MAIN);
            emailIntent.addCategory(Intent.CATEGORY_APP_EMAIL);
            PackageParser.Package emailPackage = getDefaultSystemHandlerActvityPackageLPr(
                    emailIntent, userId);
            if (emailPackage != null
                    && doesPackageSupportRuntimePermissions(emailPackage)) {
                grantRuntimePermissionsLPw(emailPackage, CONTACTS_PERMISSIONS, userId);
            }

            // Browser
            Intent browserIntent = new Intent(Intent.ACTION_MAIN);
            browserIntent.addCategory(Intent.CATEGORY_APP_BROWSER);
            PackageParser.Package browserPackage = getDefaultSystemHandlerActvityPackageLPr(
                    browserIntent, userId);
            if (browserPackage != null
                    && doesPackageSupportRuntimePermissions(browserPackage)) {
                grantRuntimePermissionsLPw(browserPackage, LOCATION_PERMISSIONS, userId);
            }

            // IME
            if (imePackageNames != null) {
                for (String imePackageName : imePackageNames) {
                    PackageParser.Package imePackage = getSystemPackageLPr(imePackageName);
                    if (imePackage != null
                            && doesPackageSupportRuntimePermissions(imePackage)) {
                        grantRuntimePermissionsLPw(imePackage, CONTACTS_PERMISSIONS, userId);
                    }
                }
            }

            // Voice interaction
            if (voiceInteractPackageNames != null) {
                for (String voiceInteractPackageName : voiceInteractPackageNames) {
                    PackageParser.Package voiceInteractPackage = getSystemPackageLPr(
                            voiceInteractPackageName);
                    if (voiceInteractPackage != null
                            && doesPackageSupportRuntimePermissions(voiceInteractPackage)) {
                        grantRuntimePermissionsLPw(voiceInteractPackage,
                                CONTACTS_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(voiceInteractPackage,
                                CALENDAR_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(voiceInteractPackage,
                                MICROPHONE_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(voiceInteractPackage,
                                PHONE_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(voiceInteractPackage,
                                SMS_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(voiceInteractPackage,
                                LOCATION_PERMISSIONS, userId);
                    }
                }
            }

            // Location
            if (locationPackageNames != null) {
                for (String packageName : locationPackageNames) {
                    PackageParser.Package locationPackage = getSystemPackageLPr(packageName);
                    if (locationPackage != null
                            && doesPackageSupportRuntimePermissions(locationPackage)) {
                        grantRuntimePermissionsLPw(locationPackage, CONTACTS_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(locationPackage, CALENDAR_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(locationPackage, MICROPHONE_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(locationPackage, PHONE_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(locationPackage, SMS_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(locationPackage, LOCATION_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(locationPackage, CAMERA_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(locationPackage, SENSORS_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(locationPackage, STORAGE_PERMISSIONS, userId);
                    }
                }
            }

            // Carrier apps
            if (carrierAppPackageNames != null) {
                for (String packageName : carrierAppPackageNames) {
                    PackageParser.Package carrierPackage = getSystemPackageLPr(packageName);
                    if (carrierPackage != null
                            && doesPackageSupportRuntimePermissions(carrierPackage)) {
                        grantRuntimePermissionsLPw(carrierPackage, PHONE_PERMISSIONS, userId);
                        grantRuntimePermissionsLPw(carrierPackage, LOCATION_PERMISSIONS, userId);
                    }
                }
            }
        }
    }

    private List<PackageParser.Package> getPrivilegedHandlerReceiverPackagesLPr(
            Intent intent, int userId) {
        List<ResolveInfo> handlers = mService.queryIntentReceivers(
                intent, intent.resolveTypeIfNeeded(mService.mContext.getContentResolver()),
                0, userId);
        return getPrivilegedPackages(handlers);
    }

    private List<PackageParser.Package> getPrivilegedHandlerActivityPackagesLPr(
            Intent intent, int userId) {
        List<ResolveInfo> handlers = mService.queryIntentActivities(
                intent, intent.resolveTypeIfNeeded(mService.mContext.getContentResolver()),
                0, userId);
        return getPrivilegedPackages(handlers);
    }

    private List<PackageParser.Package> getPrivilegedPackages(List<ResolveInfo> resolveInfos) {
        List<PackageParser.Package> handlerPackages = new ArrayList<>();
        final int handlerCount = resolveInfos.size();
        for (int i = 0; i < handlerCount; i++) {
            ResolveInfo handler = resolveInfos.get(i);
            PackageParser.Package handlerPackage = getPrivilegedPackageLPr(
                    handler.activityInfo.packageName);
            if (handlerPackage != null) {
                handlerPackages.add(handlerPackage);
            }
        }
        return handlerPackages;
    }

    private PackageParser.Package getDefaultSystemHandlerActvityPackageLPr(
            Intent intent, int userId) {
        List<ResolveInfo> handlers = mService.queryIntentActivities(intent, null, 0, userId);
        final int handlerCount = handlers.size();
        for (int i = 0; i < handlerCount; i++) {
            ResolveInfo handler = handlers.get(i);
            // TODO: This is a temporary hack to figure out the setup app.
            PackageParser.Package handlerPackage = getSystemPackageLPr(
                    handler.activityInfo.packageName);
            if (handlerPackage != null) {
                return handlerPackage;
            }
        }
        return null;
    }

    private PackageParser.Package getDefaultProviderAuthorityPackageLPr(
            String authority, int userId) {
        ProviderInfo provider = mService.resolveContentProvider(authority, 0, userId);
        if (provider != null) {
            return getSystemPackageLPr(provider.packageName);
        }
        return null;
    }

    private PackageParser.Package getSystemPackageLPr(String packageName) {
        PackageParser.Package pkg = mService.mPackages.get(packageName);
        if (pkg != null && pkg.isSystemApp()) {
            return !isSysComponentOrPersistentPrivApp(pkg) ? pkg : null;
        }
        return null;
    }

    private PackageParser.Package getPrivilegedPackageLPr(String packageName) {
        PackageParser.Package pkg = mService.mPackages.get(packageName);
        if (pkg != null && pkg.applicationInfo.isPrivilegedApp()) {
            return !isSysComponentOrPersistentPrivApp(pkg) ? pkg : null;
        }
        return null;
    }

    private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions,
            int userId) {
        List<String> requestedPermissions = pkg.requestedPermissions;

        if (pkg.isUpdatedSystemApp()) {
            PackageSetting sysPs = mService.mSettings.getDisabledSystemPkgLPr(pkg.packageName);
            if (sysPs != null) {
                requestedPermissions = sysPs.pkg.requestedPermissions;
            }
        }

        final int permissionCount = requestedPermissions.size();
        for (int i = 0; i < permissionCount; i++) {
            String permission = requestedPermissions.get(i);
            if (permissions.contains(permission)) {
                final int flags = mService.getPermissionFlags(permission, pkg.packageName, userId);

                // If any flags are set to the permission, then it is either set in
                // its current state by the system or device/profile owner or the user.
                // In all these cases we do not want to clobber the current state.
                if (flags == 0) {
                    mService.grantRuntimePermission(pkg.packageName, permission, userId);
                    if (DEBUG) {
                        Log.i(TAG, "Granted " + permission + " to default handler "
                                + pkg.packageName);
                    }
                }
            }
        }
    }

    private void grantInstallPermissionsLPw(PackageParser.Package pkg, Set<String> permissions,
            int userId) {
        List<String> requestedPermissions = pkg.requestedPermissions;

        if (pkg.isUpdatedSystemApp()) {
            PackageSetting sysPs = mService.mSettings.getDisabledSystemPkgLPr(pkg.packageName);
            if (sysPs != null) {
                requestedPermissions = sysPs.pkg.requestedPermissions;
            }
        }

        final int permissionCount = requestedPermissions.size();
        for (int i = 0; i < permissionCount; i++) {
            String permission = requestedPermissions.get(i);
            if (permissions.contains(permission)) {
                final int flags = mService.getPermissionFlags(permission, pkg.packageName, userId);

                // If any flags are set to the permission, then it is either set in
                // its current state by the system or device/profile owner or the user.
                // In all these cases we do not want to clobber the current state.
                if (flags == 0) {
                    mService.grantInstallPermissionLPw(permission, pkg);
                    if (DEBUG) {
                        Log.i(TAG, "Granted install " + permission + " to " + pkg.packageName);
                    }
                }
            }
        }
    }

    private static boolean isSysComponentOrPersistentPrivApp(PackageParser.Package pkg) {
        return UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID
                || ((pkg.applicationInfo.privateFlags
                & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0
                && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0);
    }

    private static boolean doesPackageSupportRuntimePermissions(PackageParser.Package pkg) {
        return pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1;
    }
}
