Android PMS赋予应用权限流程---安装默认赋予流程

base/services/core/java/com/android/server/pm/PackageManagerService.java

    @Override
    public void systemReady() {
        enforceSystemOrRoot("Only the system can claim the system is ready");

        ......

        mUserManager.systemReady();

        // Watch for external volumes that come and go over time
        final StorageManager storage = mInjector.getSystemService(StorageManager.class);
        storage.registerListener(mStorageListener);

        mInstallerService.systemReady();
        mPackageDexOptimizer.systemReady();

        // Now that we're mostly running, clean up stale users and apps
        mUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);

        mPermissionManager.onSystemReady();

        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
        final List<UserInfo> livingUsers = mInjector.getUserManagerInternal().getUsers(
                /* excludePartial= */ true,
                /* excludeDying= */ true,
                /* excludePreCreated= */ false);
        final int livingUserCount = livingUsers.size();
        for (int i = 0; i < livingUserCount; i++) {
            final int userId = livingUsers.get(i).id;
             if (mPmInternal.isPermissionUpgradeNeeded(userId)) {
                grantPermissionsUserIds = ArrayUtils.appendInt(
                        grantPermissionsUserIds, userId);
             }
        }//权限处理
        // If we upgraded grant all default permissions before kicking off.
        for (int userId : grantPermissionsUserIds) {
            mLegacyPermissionManager.grantDefaultPermissions(userId);
        }
        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
            // If we did not grant default permissions, we preload from this the
            // default permission exceptions lazily to ensure we don't hit the
            // disk on a new user creation.
            mLegacyPermissionManager.scheduleReadDefaultPermissionExceptions();
        }

        if (mInstantAppResolverConnection != null) {
            mContext.registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    mInstantAppResolverConnection.optimisticBind();
                    mContext.unregisterReceiver(this);
                }
            }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
        }

        ......
    }

base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java

grantPermissionsToSysComponentsAndPrivApps(pm, userId);//为sys组件和private-app赋予权限

    public void grantDefaultPermissions(int userId) {
        Log.d(TAG,  " grantDefaultPermissions: " + Log.getStackTraceString(new Throwable()));
        Log.d(TAG, "grantDefaultPermissions " + userId);

        DelayingPackageManagerCache pm = new DelayingPackageManagerCache();

        grantPermissionsToSysComponentsAndPrivApps(pm, userId);
        grantDefaultSystemHandlerPermissions(pm, userId);
        grantDefaultPermissionExceptions(pm, userId);

        // Apply delayed state
        pm.apply();
    }

/*********************************************************************************/

    private void grantPermissionsToSysComponentsAndPrivApps(DelayingPackageManagerCache pm,
            int userId) {
        Log.i(TAG, "Granting permissions to platform components for user " + userId);
        List<PackageInfo> packages = mContext.getPackageManager().getInstalledPackagesAsUser(
                DEFAULT_PACKAGE_INFO_QUERY_FLAGS, UserHandle.USER_SYSTEM);//获取包的相关信息
        for (PackageInfo pkg : packages) {
            if (pkg == null) {
                continue;
            }

            // Package info is already loaded, cache it
            Log.d(TAG, "pkg.packageNamer " + pkg.packageName);

            pm.addPackageInfo(pkg.packageName, pkg);

            if (!pm.isSysComponentOrPersistentPlatformSignedPrivApp(pkg)
                    || !doesPackageSupportRuntimePermissions(pkg)
                    || ArrayUtils.isEmpty(pkg.requestedPermissions)) {
                continue;
            }
            grantRuntimePermissionsForSystemPackage(pm, userId, pkg);//赋予权限
        }

        // Grant READ_PHONE_STATE to all system apps that have READ_PRIVILEGED_PHONE_STATE
        // R: CTA requirement - permission control
        if(!CTA_MANAGER.isCtaSupported()) {
           // Re-grant READ_PHONE_STATE as non-fixed to all system apps that have
           // READ_PRIVILEGED_PHONE_STATE and READ_PHONE_STATE granted -- this is to undo the fixed
           // grant from R.
           for (PackageInfo pkg : packages) {
               if (pkg == null
                       || !doesPackageSupportRuntimePermissions(pkg)
                       || ArrayUtils.isEmpty(pkg.requestedPermissions)
                       || !pm.isGranted(Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
                               pkg, UserHandle.of(userId))
                       || !pm.isGranted(Manifest.permission.READ_PHONE_STATE, pkg,
                               UserHandle.of(userId))) {
                   continue;
               }

               pm.updatePermissionFlags(Manifest.permission.READ_PHONE_STATE, pkg,
                       PackageManager.FLAG_PERMISSION_SYSTEM_FIXED,
                       0,
                       UserHandle.of(userId));
           }
        }
    }

/*******************************************************************************/

   private void grantRuntimePermissionsForSystemPackage(PackageManagerWrapper pm,
            int userId, PackageInfo pkg) {
        Set<String> permissions = new ArraySet<>();
        for (String permission : pkg.requestedPermissions) {
            final PermissionInfo perm = pm.getPermissionInfo(permission);
            if (perm == null) {
                continue;
            }
            Log.d(TAG,"protectionLevel perm.protectionLevel: " +  perm.protectionLevel);
            Log.d(TAG,"permission: " +  permission);

            if (perm.isRuntime()) {
                permissions.add(permission);
            }
        }
        if (!permissions.isEmpty()) {
            grantRuntimePermissions(pm, pkg, permissions, true /*systemFixed*/, userId);//权限
        }
    }

/*******************************************************************************/


    private void grantRuntimePermissions(PackageManagerWrapper pm, PackageInfo pkg,
            Set<String> permissions, boolean systemFixed, int userId) {
        grantRuntimePermissions(pm, pkg, permissions, systemFixed, false,
                true /*whitelistRestrictedPermissions*/, userId);
    }
/*******************************************************************************/



grantDefaultSystemHandlerPermissions(pm, userId);//为系统的指定的应用提供相应的特殊权限

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

        final PackagesProvider locationPackagesProvider;
        final PackagesProvider locationExtraPackagesProvider;
        final PackagesProvider voiceInteractionPackagesProvider;
        final PackagesProvider smsAppPackagesProvider;
        final PackagesProvider dialerAppPackagesProvider;
        final PackagesProvider simCallManagerPackagesProvider;
        final PackagesProvider useOpenWifiAppPackagesProvider;
        final SyncAdapterPackagesProvider syncAdapterPackagesProvider;
        //config.xml中定义了具体的包名,例如    <string name="config_defaultDialer" translatable="false">com.android.dialer</string>

        synchronized (mLock) {
            locationPackagesProvider = mLocationPackagesProvider;
            locationExtraPackagesProvider = mLocationExtraPackagesProvider;
            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[] locationExtraPackageNames = (locationExtraPackagesProvider != null)
                ? locationExtraPackagesProvider.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
        grantSystemFixedPermissionsToSystemPackage(pm,
                ArrayUtils.firstOrNull(getKnownPackages(
                        PackageManagerInternal.PACKAGE_INSTALLER, userId)),
                userId, STORAGE_PERMISSIONS);//关注最后一个参数,是需要的权限组

......

//其余的不分析,基本调用相似,都是为了给特定的应用赋予特定的权限

}


/******************************************************************************/

    @SafeVarargs
    private final void grantSystemFixedPermissionsToSystemPackage(PackageManagerWrapper pm,
            String packageName, int userId, Set<String>... permissionGroups) {
        grantPermissionsToSystemPackage(pm, packageName, userId, true /* systemFixed */,
                permissionGroups);
    }

/******************************************************************************/
    @SafeVarargs
    private final void grantSystemFixedPermissionsToSystemPackage(PackageManagerWrapper pm,
            String packageName, int userId, Set<String>... permissionGroups) {
        grantPermissionsToSystemPackage(pm, packageName, userId, true /* systemFixed */,
                permissionGroups);
    }

/******************************************************************************/

    @SafeVarargs
    private final void grantPermissionsToSystemPackage(PackageManagerWrapper pm, String packageName,
            int userId, boolean systemFixed, Set<String>... permissionGroups) {
        if (!pm.isSystemPackage(packageName)) {
            return;
        }
        grantPermissionsToPackage(pm, pm.getSystemPackageInfo(packageName),
                userId, systemFixed, false /* ignoreSystemPackage */,
                true /*whitelistRestrictedPermissions*/, permissionGroups);
    }

/******************************************************************************/
    @SafeVarargs
    private final void grantPermissionsToPackage(PackageManagerWrapper pm, PackageInfo packageInfo,
            int userId, boolean systemFixed, boolean ignoreSystemPackage,
            boolean whitelistRestrictedPermissions, Set<String>... permissionGroups) {
        if (packageInfo == null) {
            return;
        }
        if (doesPackageSupportRuntimePermissions(packageInfo)) {
            for (Set<String> permissionGroup : permissionGroups) {
                grantRuntimePermissions(pm, packageInfo, permissionGroup, systemFixed,
                        ignoreSystemPackage, whitelistRestrictedPermissions, userId);//重点此函数
            }
        }
    }



/******************************************************************************/

grantDefaultPermissionExceptions(pm, userId);//从指定文件读取需要赋予的权限

    private void grantDefaultPermissionExceptions(PackageManagerWrapper pm, int userId) {
        mHandler.removeMessages(MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS);
        Log.d(TAG,"grantDefaultPermissionExceptions");
        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(pm);//获取那些权限需要被赋予
            }
        }

        Set<String> permissions = null;
        final int exceptionCount = mGrantExceptions.size();
        for (int i = 0; i < exceptionCount; i++) {
            String packageName = mGrantExceptions.keyAt(i);
            Logd(TAG,"grantDefaultPermissionExceptions packageName: " + packageName);
            PackageInfo pkg = pm.getSystemPackageInfo(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 (!pm.isPermissionDangerous(permissionGrant.name)) {
                    Log.w(TAG, "Ignoring permission " + permissionGrant.name
                            + " which isn't dangerous");
                    continue;
                }
                if (permissions == null) {
                    permissions = new ArraySet<>();
                } else {
                    permissions.clear();
                }
                permissions.add(permissionGrant.name);


                grantRuntimePermissions(pm, pkg, permissions, permissionGrant.fixed,
                        permissionGrant.whitelisted, true /*whitelistRestrictedPermissions*/,
                        userId);//赋予权限
            }
        }
    }


/********************************************************************************/

    private @NonNull ArrayMap<String, List<DefaultPermissionGrant>>
            readDefaultPermissionExceptionsLocked(PackageManagerWrapper pm) {
        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 FileInputStream(file)) {
                TypedXmlPullParser parser = Xml.resolvePullParser(str);
                parse(pm, parser, grantExceptions);
            } catch (XmlPullParserException | IOException e) {
                Slog.w(TAG, "Error reading default permissions file " + file, e);
            }
        }

        return grantExceptions;
    }


/********************************************************************************/

    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());
            Log.d(TAG,"getDefaultPermissionFiles dir.listFiles(): " + dir.listFiles().toString());
        }
        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());
        }
        dir = new File(Environment.getSystemExtDirectory(), "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]);
    }


/********************************************************************************/

grantRuntimePermissions分析

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值