[Android][Framework]PackageManagerService处理应用权限流程
- 2020 年 1 月 21 日
- 笔记
app种类
1、system app (有ApplicationInfo.FLAG_SYSTEM标记)
2、privileged app (有ApplicationInfo.FLAG_SYSTEM和ApplicationInfo.PRIVATE_FLAG_PRIVILEGE两个标记)
system app
system app 定义很明了,就是在PMS初始化安装app的时候赋予了ApplicationInfo.FLAG_SYSTEM这个标记
1、特定shareUID的app 代码在PMS的构造函数中
mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2、扫描安装特定目录的app 代码在PMS的构造函数中,扫描安装时给予PackageParser.PARSE_IS_SYSTEM标记的app,例如/vendor/overlay,/system/framework,/system/priv-app,/system/app,/vendor/app,/oem/app等,给予的PackageParser.PARSE_IS_SYSTEM最终会转换为ApplicationInfo.FLAG_SYSTEM,部分代码如下
File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); scanDirTracedLI(vendorOverlayDir, mDefParseFlags | PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0); File customFrameworkDir = new File("/custom/framework"); scanDirLI(customFrameworkDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_NO_DEX, 0); scanDirTracedLI(frameworkDir, mDefParseFlags | PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanFlags | SCAN_NO_DEX, 0);
flag转换的过程大致如下
-> scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) -> scanPackageTracedLI(PackageParser.Package pkg, final int policyFlags, int scanFlags, long currentTime, UserHandle user) -> scanPackageLI(PackageParser.Package pkg, final int policyFlags, int scanFlags, long currentTime, UserHandle user) -> scanPackageDirtyLI(PackageParser.Package pkg, final int policyFlags, final int scanFlags, long currentTime, UserHandle user) //在scanPackageDirtyLI方法中将flag转换 // Apply policy if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; ... }
privileged app
privileged app在ApplicationInfo.FLAG_SYSTEM基础上还必须有ApplicationInfo.PRIVATE_FLAG_PRIVILEGED标记
1、特定shareUID的app 特定shareUID的app有ApplicationInfo.FLAG_SYSTEM的同时都有ApplicationInfo.PRIVATE_FLAG_PRIVILEGED
2、扫描特定目录app时,给予了PackageParser.PARSE_IS_SYSTEM标记和PackageParser.PARSE_IS_PRIVILEGED标记,目录有三个:system/framework,system/priv-app,vendor/priv-app 例如:
//vender/framework目录下有PackageParser.PARSE_IS_SYSTEM没有PackageParser.PARSE_IS_PRIVILEGED标记 File vendorFrameworkDir = new File(Environment.getVendorDirectory(), "framework"); scanDirTracedLI(vendorFrameworkDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_NO_DEX, 0); //system/framework目录下两个标记都有 scanDirTracedLI(frameworkDir, mDefParseFlags | PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanFlags | SCAN_NO_DEX, 0);
PackageParser.PARSE_IS_PRIVILEGED也是在scanPackageDirtyLI方法中转换的
if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; }
PMS赋予apk的runtime权限
入口
PMS(PackageManagerService)在SystemServer中初始化完成最后调用PMS::systemReady,在systemReady方法中开始授予默认权限
final DefaultPermissionGrantPolicy mDefaultPermissionPolicy; for (int userId : grantPermissionsUserIds) { mDefaultPermissionPolicy.grantDefaultPermissions(userId); }
DefaultPermissionGrantPolicy这个类就是管理默认权限的,最终的实现都是在PMS代码中
public void grantDefaultPermissions(int userId) { // 系统组件赋予Dangerous权限 grantPermissionsToSysComponentsAndPrivApps(userId); // 指定app的指定权限 grantDefaultSystemHandlerPermissions(userId); }
系统组件赋予Dangerous权限
private void grantPermissionsToSysComponentsAndPrivApps(int userId) { Log.i(TAG, "Granting permissions to platform components for user " + userId); synchronized (mService.mPackages) { for (PackageParser.Package pkg : mService.mPackages.values()) { // 过滤掉privileged app , FLAG_PERSISTENT标记app ,系统签名相同的app if (!isSysComponentOrPersistentPlatformSignedPrivAppLPr(pkg) // 判断targetSdkVersion > 22 || !doesPackageSupportRuntimePermissions(pkg) // 请求权限列表为空 || pkg.requestedPermissions.isEmpty()) { continue; } Set<String> permissions = new ArraySet<>(); 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); // 权限为Dangerous权限 if (bp != null && bp.isRuntime()) { permissions.add(permission); } } if (!permissions.isEmpty()) { // 添加权限 grantRuntimePermissionsLPw(pkg, permissions, true, userId); } } } }
接下来看下isSysComponentOrPersistentPlatformSignedPrivAppLPr和isRuntime的内容
private boolean isSysComponentOrPersistentPlatformSignedPrivAppLPr(PackageParser.Package pkg) { // UserID 小于10000 if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) { return true; } // privileged app过滤 if (!pkg.isPrivilegedApp()) { return false; } // 这两个判断过滤掉FLAG_PERSISTENT PackageSetting sysPkg = mService.mSettings.getDisabledSystemPkgLPr(pkg.packageName); if (sysPkg != null && sysPkg.pkg != null) { if ((sysPkg.pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) { return false; } } else if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) { return false; } // 过滤掉系统签名相同的apk return PackageManagerService.compareSignatures(mService.mPlatformPackage.mSignatures, pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; } public boolean isRuntime() { // protectionLevel & PermissionInfo.PROTECTION_MASK_BASE 表示当前等级 return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) == PermissionInfo.PROTECTION_DANGEROUS; }
指定app的指定权限
这里是给指定某个app,给予它指定的几个权限,这里的代码十分类似,截取片段如下
private void grantDefaultSystemHandlerPermissions(int userId) { ... // Dialer if (dialerAppPackageNames == null) { Intent dialerIntent = new Intent(Intent.ACTION_DIAL); PackageParser.Package dialerPackage = getDefaultSystemHandlerActivityPackageLPr( dialerIntent, userId); if (dialerPackage != null) { grantDefaultPermissionsToDefaultSystemDialerAppLPr(dialerPackage, userId); } } else { for (String dialerAppPackageName : dialerAppPackageNames) { PackageParser.Package dialerPackage = getSystemPackageLPr(dialerAppPackageName); if (dialerPackage != null) { grantDefaultPermissionsToDefaultSystemDialerAppLPr(dialerPackage, userId); } } } // SMS if (smsAppPackageNames == null) { Intent smsIntent = new Intent(Intent.ACTION_MAIN); smsIntent.addCategory(Intent.CATEGORY_APP_MESSAGING); PackageParser.Package smsPackage = getDefaultSystemHandlerActivityPackageLPr( smsIntent, userId); if (smsPackage != null) { grantDefaultPermissionsToDefaultSystemSmsAppLPr(smsPackage, userId); } } else { for (String smsPackageName : smsAppPackageNames) { PackageParser.Package smsPackage = getSystemPackageLPr(smsPackageName); if (smsPackage != null) { grantDefaultPermissionsToDefaultSystemSmsAppLPr(smsPackage, userId); } } } ... } private void grantDefaultPermissionsToDefaultSystemDialerAppLPr( PackageParser.Package dialerPackage, int userId) { if (doesPackageSupportRuntimePermissions(dialerPackage)) { boolean isPhonePermFixed = mService.hasSystemFeature(PackageManager.FEATURE_WATCH, 0); grantRuntimePermissionsLPw( dialerPackage, PHONE_PERMISSIONS, isPhonePermFixed, userId); grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId); grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId); grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId); } }
两种添加最后都走到了grantRuntimePermissionsLPw,我们接着分析grantRuntimePermissionsLPw函数
添加权限grantRuntimePermissionsLPw
grantRuntimePermissionsLPw赋予权限的代码,最终是交给PMS来处理,经过一些列判断后调用关键方法mService.grantRuntimePermission和mService.updatePermissionFlags,代码片段如下
private final PackageManagerService mService; private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions, boolean systemFixed, boolean isDefaultPhoneOrSms, int userId) { ... mService.grantRuntimePermission(pkg.packageName, permission, userId); ... mService.updatePermissionFlags(permission, pkg.packageName, newFlags, newFlags, userId); ... }
接着看PMS的grantRuntimePermission如何添加权限
public void grantRuntimePermission(String packageName, String name, final int userId) { ... // 要添加权限,也需要“添加”权限 mContext.enforceCallingOrSelfPermission( android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, "grantRuntimePermission"); enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */, true /* checkShell */, "grantRuntimePermission"); ... // 添加权限 final int result = permissionsState.grantRuntimePermission(bp, userId); switch (result) { case PermissionsState.PERMISSION_OPERATION_FAILURE: { return; } case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); mHandler.post(new Runnable() { @Override public void run() { killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); } }); } break; } // PermissionsChanged监听 mOnPermissionChangeListeners.onPermissionsChanged(uid); // 把数据更新到runtime-permissions.xml中 mSettings.writeRuntimePermissionsForUserLPr(userId, false); }
最后grantRuntimePermission就是把permission存到mPermissions数据map中,再把数据跟新到/data/system/users/0/runtime-permissions.xml中,片段如下
<pkg name="com.google.android.apps.messaging"> <item name="android.permission.READ_SMS" granted="true" flags="20" /> <item name="android.permission.RECEIVE_WAP_PUSH" granted="true" flags="20" /> <item name="android.permission.RECEIVE_MMS" granted="true" flags="20" /> <item name="android.permission.RECEIVE_SMS" granted="true" flags="20" /> <item name="android.permission.READ_PHONE_STATE" granted="true" flags="20" /> <item name="android.permission.SEND_SMS" granted="true" flags="20" /> <item name="android.permission.CALL_PHONE" granted="true" flags="20" /> <item name="android.permission.WRITE_CONTACTS" granted="true" flags="20" /> <item name="android.permission.READ_CONTACTS" granted="true" flags="20" /> </pkg> <pkg name="com.google.android.setupwizard"> <item name="android.permission.ACCESS_COARSE_LOCATION" granted="true" flags="20" /> <item name="android.permission.CALL_PHONE" granted="true" flags="20" /> <item name="android.permission.WRITE_CONTACTS" granted="true" flags="20" /> <item name="android.permission.CAMERA" granted="true" flags="20" /> <item name="android.permission.PROCESS_OUTGOING_CALLS" granted="true" flags="20" /> <item name="android.permission.READ_CONTACTS" granted="true" flags="20" /> </pkg>
PMS赋予apk安装权限
过程精简如下:
-> scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) -> scanPackageTracedLI(PackageParser.Package pkg, final int policyFlags, int scanFlags, long currentTime, UserHandle user) -> scanPackageLI(PackageParser.Package pkg, final int policyFlags, int scanFlags, long currentTime, UserHandle user) -> scanPackageDirtyLI(PackageParser.Package pkg, final int policyFlags, final int scanFlags, long currentTime, UserHandle user) -> updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, int[] allUsers, PackageInstalledInfo res, UserHandle user) -> updateSettingsInternalLI(PackageParser.Package newPackage, String installerPackageName, int[] allUsers, int[] installedForUsers, PackageInstalledInfo res, UserHandle user) -> updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, int flags) -> updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) -> grantPermissionsLPw(PackageParser.Package pkg, boolean replace, String packageOfInterest)
在grantPermissionsLPw函数中做最后权限赋予操作,代码片段如下:
private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, String packageOfInterest) { for (int i=0; i<N; i++) { final String name = pkg.requestedPermissions.get(i); // 权限名字 final BasePermission bp = mSettings.mPermissions.get(name); // 权限信息 ... final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; // 权限级别ProtectionLevel final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M; // 根据权限级别定义grant switch (level) { case PermissionInfo.PROTECTION_NORMAL: { // For all apps normal permissions are install time ones. grant = GRANT_INSTALL; } break; case PermissionInfo.PROTECTION_DANGEROUS: { if (!appSupportsRuntimePermissions && !Build.isPermissionReviewRequired()) { // For legacy apps dangerous permissions are install time ones. grant = GRANT_INSTALL; } else if (origPermissions.hasInstallPermission(bp.name)) { // For legacy apps that became modern, install becomes runtime. grant = GRANT_UPGRADE; } else if (mPromoteSystemApps && isSystemApp(ps) && mExistingSystemPackages.contains(ps.name)) { // For legacy system apps, install becomes runtime. // We cannot check hasInstallPermission() for system apps since those // permissions were granted implicitly and not persisted pre-M. grant = GRANT_UPGRADE; } else { // For modern apps keep runtime permissions unchanged. grant = GRANT_RUNTIME; } } break; case PermissionInfo.PROTECTION_SIGNATURE: { // For all apps signature permissions are install time ones. allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); if (allowedSig) { grant = GRANT_INSTALL; } } break; } ... if (grant != GRANT_DENIED) { if (!isSystemApp(ps) && ps.installPermissionsFixed) { // If this is an existing, non-system package, then // we can't add any new permissions to it. if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { // Except... if this is a permission that was added // to the platform (note: need to only do this when // updating the platform). if (!isNewPlatformPermissionForPackage(perm, pkg)) { grant = GRANT_DENIED; } } } // 根据grant 选择权限给予方式 switch (grant) { case GRANT_INSTALL: { for (int userId : UserManagerService.getInstance().getUserIds()) { if (origPermissions.getRuntimePermissionState( bp.name, userId) != null) { // Revoke the runtime permission and clear the flags. origPermissions.revokeRuntimePermission(bp, userId); origPermissions.updatePermissionFlags(bp, userId, PackageManager.MASK_PERMISSION_FLAGS, 0); // If we revoked a permission permission, we have to write. changedRuntimePermissionUserIds = ArrayUtils.appendInt( changedRuntimePermissionUserIds, userId); } } // install权限 if (permissionsState.grantInstallPermission(bp) != PermissionsState.PERMISSION_OPERATION_FAILURE) { changedInstallPermission = true; } } break; case GRANT_RUNTIME: { // Grant previously granted runtime permissions. for (int userId : UserManagerService.getInstance().getUserIds()) { PermissionState permissionState = origPermissions .getRuntimePermissionState(bp.name, userId); int flags = permissionState != null ? permissionState.getFlags() : 0; if (origPermissions.hasRuntimePermission(bp.name, userId)) { if (permissionsState.grantRuntimePermission(bp, userId) == PermissionsState.PERMISSION_OPERATION_FAILURE) { // If we cannot put the permission as it was, we have to write. changedRuntimePermissionUserIds = ArrayUtils.appendInt( changedRuntimePermissionUserIds, userId); } // If the app supports runtime permissions no need for a review. /// M: CTA requirement - permission control if (Build.isPermissionReviewRequired() && appSupportsRuntimePermissions && (flags & PackageManager .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; // Since we changed the flags, we have to write. changedRuntimePermissionUserIds = ArrayUtils.appendInt( changedRuntimePermissionUserIds, userId); } /// M: CTA requirement - permission control } else if (Build.isPermissionReviewRequired() && !appSupportsRuntimePermissions) { if (CtaUtils.isPlatformPermission(bp.sourcePackage, bp.name) && pkgReviewRequired) { if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { /// M: CTA requirement - review UI for all apps @{ Slog.d(TAG, "add review UI for legacy pkg = " + pkg.packageName + ", permission = " + bp.name + ", userId = " + userId + ", uid = " + pkg.mSharedUserId); ///@} flags |= FLAG_PERMISSION_REVIEW_REQUIRED; // We changed the flags, hence have to write. changedRuntimePermissionUserIds = ArrayUtils.appendInt( changedRuntimePermissionUserIds, userId); } } // runtime权限 if (permissionsState.grantRuntimePermission(bp, userId) != PermissionsState.PERMISSION_OPERATION_FAILURE) { // We changed the permission, hence have to write. changedRuntimePermissionUserIds = ArrayUtils.appendInt( changedRuntimePermissionUserIds, userId); } /// M: CTA requirement - review UI for all apps @{ } else if (appSupportsRuntimePermissions && pkgReviewRequired) { if (CtaUtils.isPlatformPermission(bp.sourcePackage, bp.name)) { if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0 && (flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) == 0) { Slog.d(TAG, "add review UI for non-legacy pkg = " + pkg.packageName + ", permission = " + bp.name + ", userId = " + userId + ", uid = " + pkg.mSharedUserId); flags |= FLAG_PERMISSION_REVIEW_REQUIRED; // We changed the flags, hence have to write. changedRuntimePermissionUserIds = ArrayUtils.appendInt( changedRuntimePermissionUserIds, userId); } } } ///@} // Propagate the permission flags. permissionsState.updatePermissionFlags(bp, userId, flags, flags); } } break; case GRANT_UPGRADE: { // Grant runtime permissions for a previously held install permission. PermissionState permissionState = origPermissions .getInstallPermissionState(bp.name); final int flags = permissionState != null ? permissionState.getFlags() : 0; if (origPermissions.revokeInstallPermission(bp) != PermissionsState.PERMISSION_OPERATION_FAILURE) { // 跟新应用的权限 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, PackageManager.MASK_PERMISSION_FLAGS, 0); changedInstallPermission = true; } // If the permission runtime-permissions.xmlis not to be promoted to runtime we ignore it and // also its other flags as they are not applicable to install permissions. if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { for (int userId : currentUserIds) { if (permissionsState.grantRuntimePermission(bp, userId) != PermissionsState.PERMISSION_OPERATION_FAILURE) { // Transfer the permission flags. permissionsState.updatePermissionFlags(bp, userId, flags, flags); // If we granted the permission, we have to write. changedRuntimePermissionUserIds = ArrayUtils.appendInt( changedRuntimePermissionUserIds, userId); } } } } break; default: { if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { Slog.w(TAG, "Not granting permission " + perm + " to package " + pkg.packageName + " because it was previously installed without"); } } break; } } else { if (permissionsState.revokeInstallPermission(bp) != PermissionsState.PERMISSION_OPERATION_FAILURE) { // Also drop the permission flags. permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, PackageManager.MASK_PERMISSION_FLAGS, 0); changedInstallPermission = true; Slog.i(TAG, "Un-granting permission " + perm + " from package " + pkg.packageName + " (protectionLevel=" + bp.protectionLevel + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) + ")"); } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { // Don't print warning for app op permissions, since it is fine for them // not to be granted, there is a UI for the user to decide. if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { Slog.w(TAG, "Not granting permission " + perm + " to package " + pkg.packageName + " (protectionLevel=" + bp.protectionLevel + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) + ")"); } } } } if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && !isSystemApp(ps) || isUpdatedSystemApp(ps)){ // This is the first that we have heard about this package, so the // permissions we have now selected are fixed until explicitly // changed. ps.installPermissionsFixed = true; } // 把runtime权限跟新到runtime-permissions.xml中 for (int userId : changedRuntimePermissionUserIds) { mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); } Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); }
grantPermissionsLPw函数根据权限等级,来赋予权限。注意:这里的安装时赋予的runtime权限是之前已经赋予过此apk的权限才会执行到GRANT_RUNTIME 回到上面的精简过程: updateSettingsInternalLI方法中调用updatePermissionsLPw后,最后会调用mSettings.writeLPr(); 这些权限信息就被写到data/system/packages.xml中了,举例片段代码:
... <package name="com.android.settings" codePath="/system/priv-app/Settings" nativeLibraryPath="/system/priv-app/Settings/lib" primaryCpuAbi="arm64-v8a" publicFlags="944258629" privateFlags="8" ft="15f7a5ec8a8" it="15f7a5ec8a8" ut="15f7a5ec8a8" version="25" sharedUserId="1000" isOrphaned="true"> <sigs count="1"> <cert index="1" /> </sigs> <perms> <item name="android.permission.BIND_INCALL_SERVICE" granted="true" flags="0" /> <item name="android.permission.WRITE_SETTINGS" granted="true" flags="0" /> <item name="com.google.android.gm.permission.WRITE_GMAIL" granted="true" flags="0" /> <item name="android.permission.CONFIGURE_WIFI_DISPLAY" granted="true" flags="0" /> <item name="android.permission.CONFIGURE_DISPLAY_COLOR_MODE" granted="true" flags="0" /> <item name="android.permission.ACCESS_WIMAX_STATE" granted="true" flags="0" /> <item name="com.qualcomm.permission.READPROC" granted="true" flags="0" /> <item name="android.permission.RESTART_PACKAGES" granted="true" flags="0" /> <item name="android.permission.USE_CREDENTIALS" granted="true" flags="0" /> <item name="android.permission.MODIFY_AUDIO_SETTINGS" granted="true" flags="0" /> <item name="android.permission.ACCESS_CHECKIN_PROPERTIES" granted="true" flags="0" /> <item name="android.permission.MODIFY_AUDIO_ROUTING" granted="true" flags="0" /> ...
小结
1、PMS扫描安装时赋予安装权限
2、PMS在systemReady函数中调用mDefaultPermissionPolicy.grantDefaultPermissions来赋予运行权限即dangerous权限