/*
 * 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.permission;

import static android.os.Process.FIRST_APPLICATION_UID;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.DownloadManager;
import android.app.admin.DevicePolicyManager;
import android.companion.CompanionDeviceManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageList;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManagerInternal.PackagesProvider;
import android.content.pm.PackageManagerInternal.SyncAdapterPackagesProvider;
import android.content.pm.PackageParser;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.print.PrintManager;
import android.provider.CalendarContract;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.provider.Telephony.Sms.Intents;
import android.security.Credentials;
import android.service.textclassifier.TextClassifierService;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
import android.util.Xml;

import com.android.internal.util.XmlUtils;
import com.android.server.LocalServices;
import com.android.server.pm.PackageManagerService;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 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.
 * <p>
 * NOTE: This class is at the wrong abstraction level. It is a part of the package manager
 * service but knows about lots of higher level subsystems. The correct way to do this is
 * to have an interface defined in the package manager but have the impl next to other
 * policy stuff like PhoneWindowManager
 */
public final class DefaultPermissionGrantPolicy {
    private static final String TAG = "DefaultPermGrantPolicy"; // must be <= 23 chars
    private static final boolean DEBUG = false;

    private static final int DEFAULT_FLAGS =
            PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                    | PackageManager.MATCH_UNINSTALLED_PACKAGES;

    private static final String AUDIO_MIME_TYPE = "audio/mpeg";

    private static final String TAG_EXCEPTIONS = "exceptions";
    private static final String TAG_EXCEPTION = "exception";
    private static final String TAG_PERMISSION = "permission";
    private static final String ATTR_PACKAGE = "package";
    private static final String ATTR_NAME = "name";
    private static final String ATTR_FIXED = "fixed";

    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);
        CONTACTS_PERMISSIONS.add(Manifest.permission.GET_ACCOUNTS);
    }

    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> COARSE_LOCATION_PERMISSIONS = new ArraySet<>();
    static {
        COARSE_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 int MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS = 1;

    private static final String ACTION_TRACK = "com.android.fitness.TRACK";

    private final Handler mHandler;

    private PackagesProvider mLocationPackagesProvider;
    private PackagesProvider mVoiceInteractionPackagesProvider;
    private PackagesProvider mSmsAppPackagesProvider;
    private PackagesProvider mDialerAppPackagesProvider;
    private PackagesProvider mSimCallManagerPackagesProvider;
    private PackagesProvider mUseOpenWifiAppPackagesProvider;
    private SyncAdapterPackagesProvider mSyncAdapterPackagesProvider;

    private ArrayMap<String, List<DefaultPermissionGrant>> mGrantExceptions;
    private final Context mContext;
    private final Object mLock = new Object();
    private final PackageManagerInternal mServiceInternal;
    private final PermissionManagerService mPermissionManager;
    private final DefaultPermissionGrantedCallback mPermissionGrantedCallback;
    public interface DefaultPermissionGrantedCallback {
        /** Callback when permissions have been granted */
        public void onDefaultRuntimePermissionsGranted(int userId);
    }

    public DefaultPermissionGrantPolicy(Context context, Looper looper,
            @Nullable DefaultPermissionGrantedCallback callback,
            @NonNull PermissionManagerService permissionManager) {
        mContext = context;
        mHandler = new Handler(looper) {
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS) {
                    synchronized (mLock) {
                        if (mGrantExceptions == null) {
                            mGrantExceptions = readDefaultPermissionExceptionsLocked();
                        }
                    }
                }
            }
        };
        mPermissionGrantedCallback = callback;
        mPermissionManager = permissionManager;
        mServiceInternal = LocalServices.getService(PackageManagerInternal.class);
    }

    public void setLocationPackagesProvider(PackagesProvider provider) {
        synchronized (mLock) {
            mLocationPackagesProvider = provider;
        }
    }

    public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
        synchronized (mLock) {
            mVoiceInteractionPackagesProvider = provider;
        }
    }

    public void setSmsAppPackagesProvider(PackagesProvider provider) {
        synchronized (mLock) {
            mSmsAppPackagesProvider = provider;
        }
    }

    public void setDialerAppPackagesProvider(PackagesProvider provider) {
        synchronized (mLock) {
            mDialerAppPackagesProvider = provider;
        }
    }

    public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
        synchronized (mLock) {
            mSimCallManagerPackagesProvider = provider;
        }
    }

    public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
        synchronized (mLock) {
            mUseOpenWifiAppPackagesProvider = provider;
        }
    }

    public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
        synchronized (mLock) {
            mSyncAdapterPackagesProvider = provider;
        }
    }

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

    private void grantRuntimePermissionsForPackage(int userId, PackageParser.Package pkg) {
        Set<String> permissions = new ArraySet<>();
        for (String permission :  pkg.requestedPermissions) {
            final BasePermission bp = mPermissionManager.getPermission(permission);
            if (bp == null) {
                continue;
            }
            if (bp.isRuntime()) {
                permissions.add(permission);
            }
        }
        if (!permissions.isEmpty()) {
            grantRuntimePermissions(pkg, permissions, true, userId);
        }
    }

    private void grantAllRuntimePermissions(int userId) {
        Log.i(TAG, "Granting all runtime permissions for user " + userId);
        final PackageList packageList = mServiceInternal.getPackageList();
        for (String packageName : packageList.getPackageNames()) {
            final PackageParser.Package pkg = mServiceInternal.getPackage(packageName);
            if (pkg == null) {
                continue;
            }
            grantRuntimePermissionsForPackage(userId, pkg);
        }
    }

    public void scheduleReadDefaultPermissionExceptions() {
        mHandler.sendEmptyMessage(MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS);
    }

    private void grantPermissionsToSysComponentsAndPrivApps(int userId) {
        Log.i(TAG, "Granting permissions to platform components for user " + userId);
        final PackageList packageList = mServiceInternal.getPackageList();
        for (String packageName : packageList.getPackageNames()) {
            final PackageParser.Package pkg = mServiceInternal.getPackage(packageName);
            if (pkg == null) {
                continue;
            }
            if (!isSysComponentOrPersistentPlatformSignedPrivApp(pkg)
                    || !doesPackageSupportRuntimePermissions(pkg)
                    || pkg.requestedPermissions.isEmpty()) {
                continue;
            }
            grantRuntimePermissionsForPackage(userId, pkg);
        }
    }

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

        final PackagesProvider locationPackagesProvider;
        final PackagesProvider voiceInteractionPackagesProvider;
        final PackagesProvider smsAppPackagesProvider;
        final PackagesProvider dialerAppPackagesProvider;
        final PackagesProvider simCallManagerPackagesProvider;
        final PackagesProvider useOpenWifiAppPackagesProvider;
        final SyncAdapterPackagesProvider syncAdapterPackagesProvider;

        synchronized (mLock) {
            locationPackagesProvider = mLocationPackagesProvider;
            voiceInteractionPackagesProvider = mVoiceInteractionPackagesProvider;
            smsAppPackagesProvider = mSmsAppPackagesProvider;
            dialerAppPackagesProvider = mDialerAppPackagesProvider;
            simCallManagerPackagesProvider = mSimCallManagerPackagesProvider;
            useOpenWifiAppPackagesProvider = mUseOpenWifiAppPackagesProvider;
            syncAdapterPackagesProvider = mSyncAdapterPackagesProvider;
        }

        String[] voiceInteractPackageNames = (voiceInteractionPackagesProvider != null)
                ? voiceInteractionPackagesProvider.getPackages(userId) : null;
        String[] locationPackageNames = (locationPackagesProvider != null)
                ? locationPackagesProvider.getPackages(userId) : null;
        String[] smsAppPackageNames = (smsAppPackagesProvider != null)
                ? smsAppPackagesProvider.getPackages(userId) : null;
        String[] dialerAppPackageNames = (dialerAppPackagesProvider != null)
                ? dialerAppPackagesProvider.getPackages(userId) : null;
        String[] simCallManagerPackageNames = (simCallManagerPackagesProvider != null)
                ? simCallManagerPackagesProvider.getPackages(userId) : null;
        String[] useOpenWifiAppPackageNames = (useOpenWifiAppPackagesProvider != null)
                ? useOpenWifiAppPackagesProvider.getPackages(userId) : null;
        String[] contactsSyncAdapterPackages = (syncAdapterPackagesProvider != null) ?
                syncAdapterPackagesProvider.getPackages(ContactsContract.AUTHORITY, userId) : null;
        String[] calendarSyncAdapterPackages = (syncAdapterPackagesProvider != null) ?
                syncAdapterPackagesProvider.getPackages(CalendarContract.AUTHORITY, userId) : null;

        // Installer
        final String installerPackageName = mServiceInternal.getKnownPackageName(
                PackageManagerInternal.PACKAGE_INSTALLER, userId);
        PackageParser.Package installerPackage = getSystemPackage(installerPackageName);
        if (installerPackage != null
                && doesPackageSupportRuntimePermissions(installerPackage)) {
            grantRuntimePermissions(installerPackage, STORAGE_PERMISSIONS, true, userId);
        }

        // Verifier
        final String verifierPackageName = mServiceInternal.getKnownPackageName(
                PackageManagerInternal.PACKAGE_VERIFIER, userId);
        PackageParser.Package verifierPackage = getSystemPackage(verifierPackageName);
        if (verifierPackage != null
                && doesPackageSupportRuntimePermissions(verifierPackage)) {
            grantRuntimePermissions(verifierPackage, STORAGE_PERMISSIONS, true, userId);
            grantRuntimePermissions(verifierPackage, PHONE_PERMISSIONS, false, userId);
            grantRuntimePermissions(verifierPackage, SMS_PERMISSIONS, false, userId);
        }

        // SetupWizard
        final String setupWizardPackageName = mServiceInternal.getKnownPackageName(
                PackageManagerInternal.PACKAGE_SETUP_WIZARD, userId);
        PackageParser.Package setupPackage = getSystemPackage(setupWizardPackageName);
        if (setupPackage != null
                && doesPackageSupportRuntimePermissions(setupPackage)) {
            grantRuntimePermissions(setupPackage, PHONE_PERMISSIONS, userId);
            grantRuntimePermissions(setupPackage, CONTACTS_PERMISSIONS, userId);
            grantRuntimePermissions(setupPackage, LOCATION_PERMISSIONS, userId);
            grantRuntimePermissions(setupPackage, CAMERA_PERMISSIONS, userId);
        }

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

        // Media provider
        PackageParser.Package mediaStorePackage = getDefaultProviderAuthorityPackage(
                MediaStore.AUTHORITY, userId);
        if (mediaStorePackage != null) {
            grantRuntimePermissions(mediaStorePackage, STORAGE_PERMISSIONS, true, userId);
            grantRuntimePermissions(mediaStorePackage, PHONE_PERMISSIONS, true, userId);
        }

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

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

        // Storage provider
        PackageParser.Package storagePackage = getDefaultProviderAuthorityPackage(
                "com.android.externalstorage.documents", userId);
        if (storagePackage != null) {
            grantRuntimePermissions(storagePackage, STORAGE_PERMISSIONS, true, userId);
        }

        // Container service
        PackageParser.Package containerPackage = getSystemPackage(
                PackageManagerService.DEFAULT_CONTAINER_PACKAGE);
        if (containerPackage != null) {
            grantRuntimePermissions(containerPackage, STORAGE_PERMISSIONS, true, userId);
        }

        // CertInstaller
        Intent certInstallerIntent = new Intent(Credentials.INSTALL_ACTION);
        PackageParser.Package certInstallerPackage = getDefaultSystemHandlerActivityPackage(
                certInstallerIntent, userId);
        if (certInstallerPackage != null
                && doesPackageSupportRuntimePermissions(certInstallerPackage)) {
            grantRuntimePermissions(certInstallerPackage, STORAGE_PERMISSIONS, true, userId);
        }

        // Dialer
        if (dialerAppPackageNames == null) {
            Intent dialerIntent = new Intent(Intent.ACTION_DIAL);
            PackageParser.Package dialerPackage = getDefaultSystemHandlerActivityPackage(
                    dialerIntent, userId);
            if (dialerPackage != null) {
                grantDefaultPermissionsToDefaultSystemDialerApp(dialerPackage, userId);
            }
        } else {
            for (String dialerAppPackageName : dialerAppPackageNames) {
                PackageParser.Package dialerPackage = getSystemPackage(dialerAppPackageName);
                if (dialerPackage != null) {
                    grantDefaultPermissionsToDefaultSystemDialerApp(dialerPackage, userId);
                }
            }
        }

        // Sim call manager
        if (simCallManagerPackageNames != null) {
            for (String simCallManagerPackageName : simCallManagerPackageNames) {
                PackageParser.Package simCallManagerPackage =
                        getSystemPackage(simCallManagerPackageName);
                if (simCallManagerPackage != null) {
                    grantDefaultPermissionsToDefaultSimCallManager(simCallManagerPackage,
                            userId);
                }
            }
        }

        // Use Open Wifi
        if (useOpenWifiAppPackageNames != null) {
            for (String useOpenWifiPackageName : useOpenWifiAppPackageNames) {
                PackageParser.Package useOpenWifiPackage =
                        getSystemPackage(useOpenWifiPackageName);
                if (useOpenWifiPackage != null) {
                    grantDefaultPermissionsToDefaultSystemUseOpenWifiApp(useOpenWifiPackage,
                            userId);
                }
            }
        }

        // SMS
        if (smsAppPackageNames == null) {
            Intent smsIntent = new Intent(Intent.ACTION_MAIN);
            smsIntent.addCategory(Intent.CATEGORY_APP_MESSAGING);
            PackageParser.Package smsPackage = getDefaultSystemHandlerActivityPackage(
                    smsIntent, userId);
            if (smsPackage != null) {
               grantDefaultPermissionsToDefaultSystemSmsApp(smsPackage, userId);
            }
        } else {
            for (String smsPackageName : smsAppPackageNames) {
                PackageParser.Package smsPackage = getSystemPackage(smsPackageName);
                if (smsPackage != null) {
                    grantDefaultPermissionsToDefaultSystemSmsApp(smsPackage, userId);
                }
            }
        }

        // Cell Broadcast Receiver
        Intent cbrIntent = new Intent(Intents.SMS_CB_RECEIVED_ACTION);
        PackageParser.Package cbrPackage =
                getDefaultSystemHandlerActivityPackage(cbrIntent, userId);
        if (cbrPackage != null && doesPackageSupportRuntimePermissions(cbrPackage)) {
            grantRuntimePermissions(cbrPackage, SMS_PERMISSIONS, userId);
        }

        // Carrier Provisioning Service
        Intent carrierProvIntent = new Intent(Intents.SMS_CARRIER_PROVISION_ACTION);
        PackageParser.Package carrierProvPackage =
                getDefaultSystemHandlerServicePackage(carrierProvIntent, userId);
        if (carrierProvPackage != null
                && doesPackageSupportRuntimePermissions(carrierProvPackage)) {
            grantRuntimePermissions(carrierProvPackage, SMS_PERMISSIONS, false, userId);
        }

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

        // Calendar provider
        PackageParser.Package calendarProviderPackage = getDefaultProviderAuthorityPackage(
                CalendarContract.AUTHORITY, userId);
        if (calendarProviderPackage != null) {
            grantRuntimePermissions(calendarProviderPackage, CONTACTS_PERMISSIONS, userId);
            grantRuntimePermissions(calendarProviderPackage, CALENDAR_PERMISSIONS,
                    true, userId);
            grantRuntimePermissions(calendarProviderPackage, STORAGE_PERMISSIONS, userId);
        }

        // Calendar provider sync adapters
        List<PackageParser.Package> calendarSyncAdapters = getHeadlessSyncAdapterPackages(
                calendarSyncAdapterPackages, userId);
        final int calendarSyncAdapterCount = calendarSyncAdapters.size();
        for (int i = 0; i < calendarSyncAdapterCount; i++) {
            PackageParser.Package calendarSyncAdapter = calendarSyncAdapters.get(i);
            if (doesPackageSupportRuntimePermissions(calendarSyncAdapter)) {
                grantRuntimePermissions(calendarSyncAdapter, CALENDAR_PERMISSIONS, userId);
            }
        }

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

        // Contacts provider sync adapters
        List<PackageParser.Package> contactsSyncAdapters = getHeadlessSyncAdapterPackages(
                contactsSyncAdapterPackages, userId);
        final int contactsSyncAdapterCount = contactsSyncAdapters.size();
        for (int i = 0; i < contactsSyncAdapterCount; i++) {
            PackageParser.Package contactsSyncAdapter = contactsSyncAdapters.get(i);
            if (doesPackageSupportRuntimePermissions(contactsSyncAdapter)) {
                grantRuntimePermissions(contactsSyncAdapter, CONTACTS_PERMISSIONS, userId);
            }
        }

        // Contacts provider
        PackageParser.Package contactsProviderPackage = getDefaultProviderAuthorityPackage(
                ContactsContract.AUTHORITY, userId);
        if (contactsProviderPackage != null) {
            grantRuntimePermissions(contactsProviderPackage, CONTACTS_PERMISSIONS,
                    true, userId);
            grantRuntimePermissions(contactsProviderPackage, PHONE_PERMISSIONS,
                    true, userId);
            grantRuntimePermissions(contactsProviderPackage, STORAGE_PERMISSIONS, userId);
        }

        // Device provisioning
        Intent deviceProvisionIntent = new Intent(
                DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE);
        PackageParser.Package deviceProvisionPackage =
                getDefaultSystemHandlerActivityPackage(deviceProvisionIntent, userId);
        if (deviceProvisionPackage != null
                && doesPackageSupportRuntimePermissions(deviceProvisionPackage)) {
            grantRuntimePermissions(deviceProvisionPackage, CONTACTS_PERMISSIONS, userId);
        }

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

        // Gallery
        Intent galleryIntent = new Intent(Intent.ACTION_MAIN);
        galleryIntent.addCategory(Intent.CATEGORY_APP_GALLERY);
        PackageParser.Package galleryPackage = getDefaultSystemHandlerActivityPackage(
                galleryIntent, userId);
        if (galleryPackage != null
                && doesPackageSupportRuntimePermissions(galleryPackage)) {
            grantRuntimePermissions(galleryPackage, STORAGE_PERMISSIONS, userId);
        }

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

        // Browser
        PackageParser.Package browserPackage = null;
        String defaultBrowserPackage = mServiceInternal.getKnownPackageName(
                PackageManagerInternal.PACKAGE_BROWSER, userId);
        if (defaultBrowserPackage != null) {
            browserPackage = getPackage(defaultBrowserPackage);
        }
        if (browserPackage == null) {
            Intent browserIntent = new Intent(Intent.ACTION_MAIN);
            browserIntent.addCategory(Intent.CATEGORY_APP_BROWSER);
            browserPackage = getDefaultSystemHandlerActivityPackage(
                    browserIntent, userId);
        }
        if (browserPackage != null
                && doesPackageSupportRuntimePermissions(browserPackage)) {
            grantRuntimePermissions(browserPackage, LOCATION_PERMISSIONS, userId);
        }

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

        if (ActivityManager.isLowRamDeviceStatic()) {
            // Allow voice search on low-ram devices
            Intent globalSearchIntent = new Intent("android.search.action.GLOBAL_SEARCH");
            PackageParser.Package globalSearchPickerPackage =
                getDefaultSystemHandlerActivityPackage(globalSearchIntent, userId);

            if (globalSearchPickerPackage != null
                    && doesPackageSupportRuntimePermissions(globalSearchPickerPackage)) {
                grantRuntimePermissions(globalSearchPickerPackage,
                    MICROPHONE_PERMISSIONS, false, userId);
                grantRuntimePermissions(globalSearchPickerPackage,
                    LOCATION_PERMISSIONS, false, userId);
            }
        }

        // Voice recognition
        Intent voiceRecoIntent = new Intent("android.speech.RecognitionService");
        voiceRecoIntent.addCategory(Intent.CATEGORY_DEFAULT);
        PackageParser.Package voiceRecoPackage = getDefaultSystemHandlerServicePackage(
                voiceRecoIntent, userId);
        if (voiceRecoPackage != null
                && doesPackageSupportRuntimePermissions(voiceRecoPackage)) {
            grantRuntimePermissions(voiceRecoPackage, MICROPHONE_PERMISSIONS, userId);
        }

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

        // Music
        Intent musicIntent = new Intent(Intent.ACTION_VIEW);
        musicIntent.addCategory(Intent.CATEGORY_DEFAULT);
        musicIntent.setDataAndType(Uri.fromFile(new File("foo.mp3")),
                AUDIO_MIME_TYPE);
        PackageParser.Package musicPackage = getDefaultSystemHandlerActivityPackage(
                musicIntent, userId);
        if (musicPackage != null
                && doesPackageSupportRuntimePermissions(musicPackage)) {
            grantRuntimePermissions(musicPackage, STORAGE_PERMISSIONS, userId);
        }

        // Home
        Intent homeIntent = new Intent(Intent.ACTION_MAIN);
        homeIntent.addCategory(Intent.CATEGORY_HOME);
        homeIntent.addCategory(Intent.CATEGORY_LAUNCHER_APP);
        PackageParser.Package homePackage = getDefaultSystemHandlerActivityPackage(
                homeIntent, userId);
        if (homePackage != null
                && doesPackageSupportRuntimePermissions(homePackage)) {
            grantRuntimePermissions(homePackage, LOCATION_PERMISSIONS, false, userId);
        }

        // Watches
        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH, 0)) {
            // Home application on watches
            Intent wearHomeIntent = new Intent(Intent.ACTION_MAIN);
            wearHomeIntent.addCategory(Intent.CATEGORY_HOME_MAIN);

            PackageParser.Package wearHomePackage = getDefaultSystemHandlerActivityPackage(
                    wearHomeIntent, userId);

            if (wearHomePackage != null
                    && doesPackageSupportRuntimePermissions(wearHomePackage)) {
                grantRuntimePermissions(wearHomePackage, CONTACTS_PERMISSIONS, false,
                        userId);
                grantRuntimePermissions(wearHomePackage, PHONE_PERMISSIONS, true, userId);
                grantRuntimePermissions(wearHomePackage, MICROPHONE_PERMISSIONS, false,
                        userId);
                grantRuntimePermissions(wearHomePackage, LOCATION_PERMISSIONS, false,
                        userId);
            }

            // Fitness tracking on watches
            Intent trackIntent = new Intent(ACTION_TRACK);
            PackageParser.Package trackPackage = getDefaultSystemHandlerActivityPackage(
                    trackIntent, userId);
            if (trackPackage != null
                    && doesPackageSupportRuntimePermissions(trackPackage)) {
                grantRuntimePermissions(trackPackage, SENSORS_PERMISSIONS, false, userId);
                grantRuntimePermissions(trackPackage, LOCATION_PERMISSIONS, false, userId);
            }
        }

        // Print Spooler
        PackageParser.Package printSpoolerPackage = getSystemPackage(
                PrintManager.PRINT_SPOOLER_PACKAGE_NAME);
        if (printSpoolerPackage != null
                && doesPackageSupportRuntimePermissions(printSpoolerPackage)) {
            grantRuntimePermissions(printSpoolerPackage, LOCATION_PERMISSIONS, true, userId);
        }

        // EmergencyInfo
        Intent emergencyInfoIntent = new Intent(TelephonyManager.ACTION_EMERGENCY_ASSISTANCE);
        PackageParser.Package emergencyInfoPckg = getDefaultSystemHandlerActivityPackage(
                emergencyInfoIntent, userId);
        if (emergencyInfoPckg != null
                && doesPackageSupportRuntimePermissions(emergencyInfoPckg)) {
            grantRuntimePermissions(emergencyInfoPckg, CONTACTS_PERMISSIONS, true, userId);
            grantRuntimePermissions(emergencyInfoPckg, PHONE_PERMISSIONS, true, userId);
        }

        // NFC Tag viewer
        Intent nfcTagIntent = new Intent(Intent.ACTION_VIEW);
        nfcTagIntent.setType("vnd.android.cursor.item/ndef_msg");
        PackageParser.Package nfcTagPkg = getDefaultSystemHandlerActivityPackage(
                nfcTagIntent, userId);
        if (nfcTagPkg != null
                && doesPackageSupportRuntimePermissions(nfcTagPkg)) {
            grantRuntimePermissions(nfcTagPkg, CONTACTS_PERMISSIONS, false, userId);
            grantRuntimePermissions(nfcTagPkg, PHONE_PERMISSIONS, false, userId);
        }

        // Storage Manager
        Intent storageManagerIntent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
        PackageParser.Package storageManagerPckg = getDefaultSystemHandlerActivityPackage(
                storageManagerIntent, userId);
        if (storageManagerPckg != null
                && doesPackageSupportRuntimePermissions(storageManagerPckg)) {
            grantRuntimePermissions(storageManagerPckg, STORAGE_PERMISSIONS, true, userId);
        }

        // Companion devices
        PackageParser.Package companionDeviceDiscoveryPackage = getSystemPackage(
                CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME);
        if (companionDeviceDiscoveryPackage != null
                && doesPackageSupportRuntimePermissions(companionDeviceDiscoveryPackage)) {
            grantRuntimePermissions(companionDeviceDiscoveryPackage,
                    LOCATION_PERMISSIONS, true, userId);
        }

        // Ringtone Picker
        Intent ringtonePickerIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
        PackageParser.Package ringtonePickerPackage =
                getDefaultSystemHandlerActivityPackage(ringtonePickerIntent, userId);
        if (ringtonePickerPackage != null
                && doesPackageSupportRuntimePermissions(ringtonePickerPackage)) {
            grantRuntimePermissions(ringtonePickerPackage,
                    STORAGE_PERMISSIONS, true, userId);
        }

        // TextClassifier Service
        String textClassifierPackageName =
                mContext.getPackageManager().getSystemTextClassifierPackageName();
        if (!TextUtils.isEmpty(textClassifierPackageName)) {
            PackageParser.Package textClassifierPackage =
                    getSystemPackage(textClassifierPackageName);
            if (textClassifierPackage != null
                    && doesPackageSupportRuntimePermissions(textClassifierPackage)) {
                grantRuntimePermissions(textClassifierPackage, PHONE_PERMISSIONS, false, userId);
                grantRuntimePermissions(textClassifierPackage, SMS_PERMISSIONS, false, userId);
                grantRuntimePermissions(textClassifierPackage, CALENDAR_PERMISSIONS, false, userId);
                grantRuntimePermissions(textClassifierPackage, LOCATION_PERMISSIONS, false, userId);
                grantRuntimePermissions(textClassifierPackage, CONTACTS_PERMISSIONS, false, userId);
            }
        }

        // There is no real "marker" interface to identify the shared storage backup, it is
        // hardcoded in BackupManagerService.SHARED_BACKUP_AGENT_PACKAGE.
        PackageParser.Package sharedStorageBackupPackage = getSystemPackage(
                "com.android.sharedstoragebackup");
        if (sharedStorageBackupPackage != null) {
            grantRuntimePermissions(sharedStorageBackupPackage, STORAGE_PERMISSIONS, true, userId);
        }

        if (mPermissionGrantedCallback != null) {
            mPermissionGrantedCallback.onDefaultRuntimePermissionsGranted(userId);
        }
    }

    private void grantDefaultPermissionsToDefaultSystemDialerApp(
            PackageParser.Package dialerPackage, int userId) {
        if (doesPackageSupportRuntimePermissions(dialerPackage)) {
            boolean isPhonePermFixed =
                    mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH, 0);
            grantRuntimePermissions(
                    dialerPackage, PHONE_PERMISSIONS, isPhonePermFixed, userId);
            grantRuntimePermissions(dialerPackage, CONTACTS_PERMISSIONS, userId);
            grantRuntimePermissions(dialerPackage, SMS_PERMISSIONS, userId);
            grantRuntimePermissions(dialerPackage, MICROPHONE_PERMISSIONS, userId);
            grantRuntimePermissions(dialerPackage, CAMERA_PERMISSIONS, userId);
        }
    }

    private void grantDefaultPermissionsToDefaultSystemSmsApp(
            PackageParser.Package smsPackage, int userId) {
        if (doesPackageSupportRuntimePermissions(smsPackage)) {
            grantRuntimePermissions(smsPackage, PHONE_PERMISSIONS, userId);
            grantRuntimePermissions(smsPackage, CONTACTS_PERMISSIONS, userId);
            grantRuntimePermissions(smsPackage, SMS_PERMISSIONS, userId);
            grantRuntimePermissions(smsPackage, STORAGE_PERMISSIONS, userId);
            grantRuntimePermissions(smsPackage, MICROPHONE_PERMISSIONS, userId);
            grantRuntimePermissions(smsPackage, CAMERA_PERMISSIONS, userId);
        }
    }

    private void grantDefaultPermissionsToDefaultSystemUseOpenWifiApp(
            PackageParser.Package useOpenWifiPackage, int userId) {
        if (doesPackageSupportRuntimePermissions(useOpenWifiPackage)) {
            grantRuntimePermissions(useOpenWifiPackage, COARSE_LOCATION_PERMISSIONS, userId);
        }
    }

    public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
        Log.i(TAG, "Granting permissions to default sms app for user:" + userId);
        if (packageName == null) {
            return;
        }
        PackageParser.Package smsPackage = getPackage(packageName);
        if (smsPackage != null && doesPackageSupportRuntimePermissions(smsPackage)) {
            grantRuntimePermissions(smsPackage, PHONE_PERMISSIONS, false, true, userId);
            grantRuntimePermissions(smsPackage, CONTACTS_PERMISSIONS, false, true, userId);
            grantRuntimePermissions(smsPackage, SMS_PERMISSIONS, false, true, userId);
            grantRuntimePermissions(smsPackage, STORAGE_PERMISSIONS, false, true, userId);
            grantRuntimePermissions(smsPackage, MICROPHONE_PERMISSIONS, false, true, userId);
            grantRuntimePermissions(smsPackage, CAMERA_PERMISSIONS, false, true, userId);
        }
    }

    public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
        Log.i(TAG, "Granting permissions to default dialer app for user:" + userId);
        if (packageName == null) {
            return;
        }
        PackageParser.Package dialerPackage = getPackage(packageName);
        if (dialerPackage != null
                && doesPackageSupportRuntimePermissions(dialerPackage)) {
            grantRuntimePermissions(dialerPackage, PHONE_PERMISSIONS, false, true, userId);
            grantRuntimePermissions(dialerPackage, CONTACTS_PERMISSIONS, false, true, userId);
            grantRuntimePermissions(dialerPackage, SMS_PERMISSIONS, false, true, userId);
            grantRuntimePermissions(dialerPackage, MICROPHONE_PERMISSIONS, false, true, userId);
            grantRuntimePermissions(dialerPackage, CAMERA_PERMISSIONS, false, true, userId);
        }
    }

    public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
        Log.i(TAG, "Granting permissions to default Use Open WiFi app for user:" + userId);
        if (packageName == null) {
            return;
        }
        PackageParser.Package useOpenWifiPackage = getPackage(packageName);
        if (useOpenWifiPackage != null
                && doesPackageSupportRuntimePermissions(useOpenWifiPackage)) {
            grantRuntimePermissions(
                    useOpenWifiPackage, COARSE_LOCATION_PERMISSIONS, false, true, userId);
        }
    }

    private void grantDefaultPermissionsToDefaultSimCallManager(
            PackageParser.Package simCallManagerPackage, int userId) {
        Log.i(TAG, "Granting permissions to sim call manager for user:" + userId);
        if (doesPackageSupportRuntimePermissions(simCallManagerPackage)) {
            grantRuntimePermissions(simCallManagerPackage, PHONE_PERMISSIONS, userId);
            grantRuntimePermissions(simCallManagerPackage, MICROPHONE_PERMISSIONS, userId);
        }
    }

    public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
        if (packageName == null) {
            return;
        }
        PackageParser.Package simCallManagerPackage = getPackage(packageName);
        if (simCallManagerPackage != null) {
            grantDefaultPermissionsToDefaultSimCallManager(simCallManagerPackage, userId);
        }
    }

    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
        Log.i(TAG, "Granting permissions to enabled carrier apps for user:" + userId);
        if (packageNames == null) {
            return;
        }
        for (String packageName : packageNames) {
            PackageParser.Package carrierPackage = getSystemPackage(packageName);
            if (carrierPackage != null
                    && doesPackageSupportRuntimePermissions(carrierPackage)) {
                grantRuntimePermissions(carrierPackage, PHONE_PERMISSIONS, userId);
                grantRuntimePermissions(carrierPackage, LOCATION_PERMISSIONS, userId);
                grantRuntimePermissions(carrierPackage, SMS_PERMISSIONS, userId);
            }
        }
    }

    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
        Log.i(TAG, "Granting permissions to enabled ImsServices for user:" + userId);
        if (packageNames == null) {
            return;
        }
        for (String packageName : packageNames) {
            PackageParser.Package imsServicePackage = getSystemPackage(packageName);
            if (imsServicePackage != null
                    && doesPackageSupportRuntimePermissions(imsServicePackage)) {
                grantRuntimePermissions(imsServicePackage, PHONE_PERMISSIONS, userId);
                grantRuntimePermissions(imsServicePackage, MICROPHONE_PERMISSIONS, userId);
                grantRuntimePermissions(imsServicePackage, LOCATION_PERMISSIONS, userId);
                grantRuntimePermissions(imsServicePackage, CAMERA_PERMISSIONS, userId);
                grantRuntimePermissions(imsServicePackage, CONTACTS_PERMISSIONS, userId);
            }
        }
    }

    public void grantDefaultPermissionsToEnabledTelephonyDataServices(
            String[] packageNames, int userId) {
        Log.i(TAG, "Granting permissions to enabled data services for user:" + userId);
        if (packageNames == null) {
            return;
        }
        for (String packageName : packageNames) {
            PackageParser.Package dataServicePackage = getSystemPackage(packageName);
            if (dataServicePackage != null
                    && doesPackageSupportRuntimePermissions(dataServicePackage)) {
                // Grant these permissions as system-fixed, so that nobody can accidentally
                // break cellular data.
                grantRuntimePermissions(dataServicePackage, PHONE_PERMISSIONS, true, userId);
                grantRuntimePermissions(dataServicePackage, LOCATION_PERMISSIONS, true, userId);
            }
        }
    }

    public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
            String[] packageNames, int userId) {
        Log.i(TAG, "Revoking permissions from disabled data services for user:" + userId);
        if (packageNames == null) {
            return;
        }
        for (String packageName : packageNames) {
            PackageParser.Package dataServicePackage = getSystemPackage(packageName);
            if (dataServicePackage != null
                    && doesPackageSupportRuntimePermissions(dataServicePackage)) {
                revokeRuntimePermissions(dataServicePackage, PHONE_PERMISSIONS, true, userId);
                revokeRuntimePermissions(dataServicePackage, LOCATION_PERMISSIONS, true, userId);
            }
        }
    }

    public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
        Log.i(TAG, "Granting permissions to active LUI app for user:" + userId);
        if (packageName == null) {
            return;
        }
        PackageParser.Package luiAppPackage = getSystemPackage(packageName);
        if (luiAppPackage != null
                && doesPackageSupportRuntimePermissions(luiAppPackage)) {
            grantRuntimePermissions(luiAppPackage, CAMERA_PERMISSIONS, true, userId);
        }
    }

    public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
        Log.i(TAG, "Revoke permissions from LUI apps for user:" + userId);
        if (packageNames == null) {
            return;
        }
        for (String packageName : packageNames) {
            PackageParser.Package luiAppPackage = getSystemPackage(packageName);
            if (luiAppPackage != null
                    && doesPackageSupportRuntimePermissions(luiAppPackage)) {
                revokeRuntimePermissions(luiAppPackage, CAMERA_PERMISSIONS, true, userId);
            }
        }
    }

    public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
        Log.i(TAG, "Granting permissions to default browser for user:" + userId);
        if (packageName == null) {
            return;
        }
        PackageParser.Package browserPackage = getSystemPackage(packageName);
        if (browserPackage != null
                && doesPackageSupportRuntimePermissions(browserPackage)) {
            grantRuntimePermissions(browserPackage, LOCATION_PERMISSIONS, false, false, userId);
        }
    }

    private PackageParser.Package getDefaultSystemHandlerActivityPackage(
            Intent intent, int userId) {
        ResolveInfo handler = mServiceInternal.resolveIntent(intent,
                intent.resolveType(mContext.getContentResolver()), DEFAULT_FLAGS, userId, false,
                Binder.getCallingUid());
        if (handler == null || handler.activityInfo == null) {
            return null;
        }
        if (mServiceInternal.isResolveActivityComponent(handler.activityInfo)) {
            return null;
        }
        return getSystemPackage(handler.activityInfo.packageName);
    }

    private PackageParser.Package getDefaultSystemHandlerServicePackage(
            Intent intent, int userId) {
        List<ResolveInfo> handlers = mServiceInternal.queryIntentServices(
                intent, DEFAULT_FLAGS, Binder.getCallingUid(), userId);
        if (handlers == null) {
            return null;
        }
        final int handlerCount = handlers.size();
        for (int i = 0; i < handlerCount; i++) {
            ResolveInfo handler = handlers.get(i);
            PackageParser.Package handlerPackage = getSystemPackage(
                    handler.serviceInfo.packageName);
            if (handlerPackage != null) {
                return handlerPackage;
            }
        }
        return null;
    }

    private List<PackageParser.Package> getHeadlessSyncAdapterPackages(
            String[] syncAdapterPackageNames, int userId) {
        List<PackageParser.Package> syncAdapterPackages = new ArrayList<>();

        Intent homeIntent = new Intent(Intent.ACTION_MAIN);
        homeIntent.addCategory(Intent.CATEGORY_LAUNCHER);

        for (String syncAdapterPackageName : syncAdapterPackageNames) {
            homeIntent.setPackage(syncAdapterPackageName);

            ResolveInfo homeActivity = mServiceInternal.resolveIntent(homeIntent,
                    homeIntent.resolveType(mContext.getContentResolver()), DEFAULT_FLAGS,
                    userId, false, Binder.getCallingUid());
            if (homeActivity != null) {
                continue;
            }

            PackageParser.Package syncAdapterPackage = getSystemPackage(syncAdapterPackageName);
            if (syncAdapterPackage != null) {
                syncAdapterPackages.add(syncAdapterPackage);
            }
        }

        return syncAdapterPackages;
    }

    private PackageParser.Package getDefaultProviderAuthorityPackage(
            String authority, int userId) {
        ProviderInfo provider =
                mServiceInternal.resolveContentProvider(authority, DEFAULT_FLAGS, userId);
        if (provider != null) {
            return getSystemPackage(provider.packageName);
        }
        return null;
    }

    private PackageParser.Package getPackage(String packageName) {
        return mServiceInternal.getPackage(packageName);
    }

    private PackageParser.Package getSystemPackage(String packageName) {
        PackageParser.Package pkg = getPackage(packageName);
        if (pkg != null && pkg.isSystem()) {
            return !isSysComponentOrPersistentPlatformSignedPrivApp(pkg) ? pkg : null;
        }
        return null;
    }

    private void grantRuntimePermissions(PackageParser.Package pkg, Set<String> permissions,
            int userId) {
        grantRuntimePermissions(pkg, permissions, false, false, userId);
    }

    private void grantRuntimePermissions(PackageParser.Package pkg, Set<String> permissions,
            boolean systemFixed, int userId) {
        grantRuntimePermissions(pkg, permissions, systemFixed, false, userId);
    }

    private void revokeRuntimePermissions(PackageParser.Package pkg, Set<String> permissions,
            boolean systemFixed, int userId) {
        if (pkg.requestedPermissions.isEmpty()) {
            return;
        }
        Set<String> revokablePermissions = new ArraySet<>(pkg.requestedPermissions);

        for (String permission : permissions) {
            // We can't revoke what wasn't requested.
            if (!revokablePermissions.contains(permission)) {
                continue;
            }

            final int flags = mServiceInternal.getPermissionFlagsTEMP(
                    permission, pkg.packageName, userId);

            // We didn't get this through the default grant policy. Move along.
            if ((flags & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) == 0) {
                continue;
            }
            // We aren't going to clobber device policy with a DefaultGrant.
            if ((flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
                continue;
            }
            // Do not revoke system fixed permissions unless caller set them that way;
            // there is no refcount for the number of sources of this, so there
            // should be at most one grantor doing SYSTEM_FIXED for any given package.
            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0 && !systemFixed) {
                continue;
            }
            mServiceInternal.revokeRuntimePermission(pkg.packageName, permission, userId, false);

            if (DEBUG) {
                Log.i(TAG, "revoked " + (systemFixed ? "fixed " : "not fixed ")
                        + permission + " to " + pkg.packageName);
            }

            // Remove the GRANTED_BY_DEFAULT flag without touching the others.
            // Note that we do not revoke FLAG_PERMISSION_SYSTEM_FIXED. That bit remains
            // sticky once set.
            mServiceInternal.updatePermissionFlagsTEMP(permission, pkg.packageName,
                    PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, 0, userId);
        }
    }

    private void grantRuntimePermissions(PackageParser.Package pkg, Set<String> permissions,
            boolean systemFixed, boolean ignoreSystemPackage, int userId) {
        if (pkg.requestedPermissions.isEmpty()) {
            return;
        }

        List<String> requestedPermissions = pkg.requestedPermissions;
        Set<String> grantablePermissions = null;

        // In some cases, like for the Phone or SMS app, we grant permissions regardless
        // of if the version on the system image declares the permission as used since
        // selecting the app as the default for that function the user makes a deliberate
        // choice to grant this app the permissions needed to function. For all other
        // apps, (default grants on first boot and user creation) we don't grant default
        // permissions if the version on the system image does not declare them.
        if (!ignoreSystemPackage && pkg.isUpdatedSystemApp()) {
            final PackageParser.Package disabledPkg =
                    mServiceInternal.getDisabledPackage(pkg.packageName);
            if (disabledPkg != null) {
                if (disabledPkg.requestedPermissions.isEmpty()) {
                    return;
                }
                if (!requestedPermissions.equals(disabledPkg.requestedPermissions)) {
                    grantablePermissions = new ArraySet<>(requestedPermissions);
                    requestedPermissions = disabledPkg.requestedPermissions;
                }
            }
        }

        final int grantablePermissionCount = requestedPermissions.size();
        for (int i = 0; i < grantablePermissionCount; i++) {
            String permission = requestedPermissions.get(i);

            // If there is a disabled system app it may request a permission the updated
            // version ot the data partition doesn't, In this case skip the permission.
            if (grantablePermissions != null && !grantablePermissions.contains(permission)) {
                continue;
            }

            if (permissions.contains(permission)) {
                final int flags = mServiceInternal.getPermissionFlagsTEMP(
                        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.
                // Unless the caller wants to override user choices. The override is
                // to make sure we can grant the needed permission to the default
                // sms and phone apps after the user chooses this in the UI.
                if (flags == 0 || ignoreSystemPackage) {
                    // Never clobber policy fixed permissions.
                    // We must allow the grant of a system-fixed permission because
                    // system-fixed is sticky, but the permission itself may be revoked.
                    if ((flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
                        continue;
                    }

                    mServiceInternal.grantRuntimePermission(
                            pkg.packageName, permission, userId, false);
                    if (DEBUG) {
                        Log.i(TAG, "Granted " + (systemFixed ? "fixed " : "not fixed ")
                                + permission + " to default handler " + pkg.packageName);
                    }

                    int newFlags = PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
                    if (systemFixed) {
                        newFlags |= PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
                    }

                    mServiceInternal.updatePermissionFlagsTEMP(permission, pkg.packageName,
                            newFlags, newFlags, userId);
                }

                // If a component gets a permission for being the default handler A
                // and also default handler B, we grant the weaker grant form.
                if ((flags & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0
                        && (flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
                        && !systemFixed) {
                    if (DEBUG) {
                        Log.i(TAG, "Granted not fixed " + permission + " to default handler "
                                + pkg.packageName);
                    }
                    mServiceInternal.updatePermissionFlagsTEMP(permission, pkg.packageName,
                            PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, 0, userId);
                }
            }
        }
    }

    private boolean isSysComponentOrPersistentPlatformSignedPrivApp(PackageParser.Package pkg) {
        if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) {
            return true;
        }
        if (!pkg.isPrivileged()) {
            return false;
        }
        final PackageParser.Package disabledPkg =
                mServiceInternal.getDisabledPackage(pkg.packageName);
        if (disabledPkg != null) {
            if ((disabledPkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) {
                return false;
            }
        } else if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) {
            return false;
        }
        final String systemPackageName = mServiceInternal.getKnownPackageName(
                PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
        final PackageParser.Package systemPackage = getPackage(systemPackageName);
        return pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
                || systemPackage.mSigningDetails.checkCapability(pkg.mSigningDetails,
                        PackageParser.SigningDetails.CertCapabilities.PERMISSION);
    }

    private void grantDefaultPermissionExceptions(int userId) {
        mHandler.removeMessages(MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS);

        synchronized (mLock) {
            // mGrantExceptions is null only before the first read and then
            // it serves as a cache of the default grants that should be
            // performed for every user. If there is an entry then the app
            // is on the system image and supports runtime permissions.
            if (mGrantExceptions == null) {
                mGrantExceptions = readDefaultPermissionExceptionsLocked();
            }
        }

        Set<String> permissions = null;
        final int exceptionCount = mGrantExceptions.size();
        for (int i = 0; i < exceptionCount; i++) {
            String packageName = mGrantExceptions.keyAt(i);
            PackageParser.Package pkg = getSystemPackage(packageName);
            List<DefaultPermissionGrant> permissionGrants = mGrantExceptions.valueAt(i);
            final int permissionGrantCount = permissionGrants.size();
            for (int j = 0; j < permissionGrantCount; j++) {
                DefaultPermissionGrant permissionGrant = permissionGrants.get(j);
                if (permissions == null) {
                    permissions = new ArraySet<>();
                } else {
                    permissions.clear();
                }
                permissions.add(permissionGrant.name);
                grantRuntimePermissions(pkg, permissions,
                        permissionGrant.fixed, userId);
            }
        }
    }

    private File[] getDefaultPermissionFiles() {
        ArrayList<File> ret = new ArrayList<File>();
        File dir = new File(Environment.getRootDirectory(), "etc/default-permissions");
        if (dir.isDirectory() && dir.canRead()) {
            Collections.addAll(ret, dir.listFiles());
        }
        dir = new File(Environment.getVendorDirectory(), "etc/default-permissions");
        if (dir.isDirectory() && dir.canRead()) {
            Collections.addAll(ret, dir.listFiles());
        }
        dir = new File(Environment.getOdmDirectory(), "etc/default-permissions");
        if (dir.isDirectory() && dir.canRead()) {
            Collections.addAll(ret, dir.listFiles());
        }
        dir = new File(Environment.getProductDirectory(), "etc/default-permissions");
        if (dir.isDirectory() && dir.canRead()) {
            Collections.addAll(ret, dir.listFiles());
        }
        // For IoT devices, we check the oem partition for default permissions for each app.
        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_EMBEDDED, 0)) {
            dir = new File(Environment.getOemDirectory(), "etc/default-permissions");
            if (dir.isDirectory() && dir.canRead()) {
                Collections.addAll(ret, dir.listFiles());
            }
        }
        return ret.isEmpty() ? null : ret.toArray(new File[0]);
    }

    private @NonNull ArrayMap<String, List<DefaultPermissionGrant>>
            readDefaultPermissionExceptionsLocked() {
        File[] files = getDefaultPermissionFiles();
        if (files == null) {
            return new ArrayMap<>(0);
        }

        ArrayMap<String, List<DefaultPermissionGrant>> grantExceptions = new ArrayMap<>();

        // Iterate over the files in the directory and scan .xml files
        for (File file : files) {
            if (!file.getPath().endsWith(".xml")) {
                Slog.i(TAG, "Non-xml file " + file
                        + " in " + file.getParent() + " directory, ignoring");
                continue;
            }
            if (!file.canRead()) {
                Slog.w(TAG, "Default permissions file " + file + " cannot be read");
                continue;
            }
            try (
                InputStream str = new BufferedInputStream(new FileInputStream(file))
            ) {
                XmlPullParser parser = Xml.newPullParser();
                parser.setInput(str, null);
                parse(parser, grantExceptions);
            } catch (XmlPullParserException | IOException e) {
                Slog.w(TAG, "Error reading default permissions file " + file, e);
            }
        }

        return grantExceptions;
    }

    private void parse(XmlPullParser parser, Map<String, List<DefaultPermissionGrant>>
            outGrantExceptions) throws IOException, XmlPullParserException {
        final int outerDepth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                continue;
            }
            if (TAG_EXCEPTIONS.equals(parser.getName())) {
                parseExceptions(parser, outGrantExceptions);
            } else {
                Log.e(TAG, "Unknown tag " + parser.getName());
            }
        }
    }

    private void parseExceptions(XmlPullParser parser, Map<String, List<DefaultPermissionGrant>>
            outGrantExceptions) throws IOException, XmlPullParserException {
        final int outerDepth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                continue;
            }
            if (TAG_EXCEPTION.equals(parser.getName())) {
                String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);

                List<DefaultPermissionGrant> packageExceptions =
                        outGrantExceptions.get(packageName);
                if (packageExceptions == null) {
                    // The package must be on the system image
                    PackageParser.Package pkg = getSystemPackage(packageName);
                    if (pkg == null) {
                        Log.w(TAG, "Unknown package:" + packageName);
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    }

                    // The package must support runtime permissions
                    if (!doesPackageSupportRuntimePermissions(pkg)) {
                        Log.w(TAG, "Skipping non supporting runtime permissions package:"
                                + packageName);
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    }
                    packageExceptions = new ArrayList<>();
                    outGrantExceptions.put(packageName, packageExceptions);
                }

                parsePermission(parser, packageExceptions);
            } else {
                Log.e(TAG, "Unknown tag " + parser.getName() + "under <exceptions>");
            }
        }
    }

    private void parsePermission(XmlPullParser parser, List<DefaultPermissionGrant>
            outPackageExceptions) throws IOException, XmlPullParserException {
        final int outerDepth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                continue;
            }

            if (TAG_PERMISSION.contains(parser.getName())) {
                String name = parser.getAttributeValue(null, ATTR_NAME);
                if (name == null) {
                    Log.w(TAG, "Mandatory name attribute missing for permission tag");
                    XmlUtils.skipCurrentTag(parser);
                    continue;
                }

                final boolean fixed = XmlUtils.readBooleanAttribute(parser, ATTR_FIXED);

                DefaultPermissionGrant exception = new DefaultPermissionGrant(name, fixed);
                outPackageExceptions.add(exception);
            } else {
                Log.e(TAG, "Unknown tag " + parser.getName() + "under <exception>");
            }
        }
    }

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

    private static final class DefaultPermissionGrant {
        final String name;
        final boolean fixed;

        public DefaultPermissionGrant(String name, boolean fixed) {
            this.name = name;
            this.fixed = fixed;
        }
    }
}
