Only grant runtime permissions to special components.

Now runtime permissions are granted only to components that are
part of the system or perform special system operations. For
exmple, the shell UID gets its runtime permissions granted by
default and the default phone app gets the phone permissions
granted by default.

bug:21764803

Change-Id: If8b8cadbd1980ffe7a6fc15bbb5f54a425f6e8f9
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
new file mode 100644
index 0000000..fe3103b
--- /dev/null
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -0,0 +1,521 @@
+/*
+ * 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.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.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 = "DefaultPermissionGrantPolicy";
+    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;
+
+    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 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;
+
+        synchronized (mService.mPackages) {
+            imePackagesProvider = mImePackagesProvider;
+            locationPackagesProvider = mLocationPackagesProvider;
+            voiceInteractionPackagesProvider = mVoiceInteractionPackagesProvider;
+        }
+
+        String[] imePackageNames = (imePackagesProvider != null)
+                ? imePackagesProvider.getPackages(userId) : null;
+        String[] voiceInteractPackageNames = (voiceInteractionPackagesProvider != null)
+                ? voiceInteractionPackagesProvider.getPackages(userId) : null;
+        String[] locationPackageNames = (locationPackagesProvider != null)
+                ? locationPackagesProvider.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);
+            }
+
+            // 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);
+            }
+
+            // 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);
+            }
+
+            // 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);
+                    }
+                }
+            }
+        }
+    }
+
+    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 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;
+    }
+}