DefaultPermissionGrantPolicy简介
. Android开机后,除了根据上次开机的记录(runtime-permissions.xml)授予运行时权限外,一些系统重要的组件也需要提前授予运行时权限。例如,系统会为默认的浏览器提前授予位置相关的运行时权限。而这些授权操作,是在DefaultPermissionGrantPolicy类里面进行的。DefaultPermissionGrantPolicy在PermissionManagerService的构造函数中被创建。
frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
PermissionManagerService(Context context,
@NonNull Object externalLock) {
...
mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
context, mHandlerThread.getLooper(), this);
在PMS的systemReady阶段中,会调用DefaultPermissionGrantPolicy#grantDefaultPermissions为每一个修改过运行时权限的userid提前授予运行时权限(创建新用户也会触发授权,此处略过):
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
@Override
public void systemReady() {
...
// If we upgraded grant all default permissions before kicking off.
for (int userId : grantPermissionsUserIds) {
mDefaultPermissionPolicy.grantDefaultPermissions(userId);
}
提前授权的步骤分三步:1.系统特权组件授权;2.系统默认组件授权;3.特定文件指定授权。
frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
public void grantDefaultPermissions(int userId) {
grantPermissionsToSysComponentsAndPrivApps(userId);
grantDefaultSystemHandlerPermissions(userId);
grantDefaultPermissionExceptions(userId);
synchronized (mLock) {
mDefaultPermissionsGrantedUsers.put(userId, userId);
}
}
grantPermissionsToSysComponentsAndPrivApps系统特定组件授权
首先列出主用户下所有已安装的包,过滤掉以下包:1.不支持运行时权限的(targetsdk小于M);2.没有声明申请权限的;3.不属于特权apk的;4.如果是属于更新过后的系统应用,原来的系统应用不是persistent的;5.如果不属于更新过后的系统应用,此应用不是persistent的;
6.没有系统(platform)签名的。其他包和UID小于10000(应用程序的首个UID)的包会被授予运行时权限。
frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
private void grantPermissionsToSysComponentsAndPrivApps(int userId) {
Log.i(TAG, "Granting permissions to platform components for user " + userId);
Listpackages = mContext.getPackageManager().getInstalledPackagesAsUser(
DEFAULT_PACKAGE_INFO_QUERY_FLAGS, UserHandle.USER_SYSTEM);
for (PackageInfo pkg : packages) {
if (pkg == null) {
continue;
}
if (!isSysComponentOrPersistentPlatformSignedPrivApp(pkg)
|| !doesPackageSupportRuntimePermissions(pkg)
|| ArrayUtils.isEmpty(pkg.requestedPermissions)) {
continue;
}
grantRuntimePermissionsForSystemPackage(userId, pkg);
}
}
frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
private boolean isSysComponentOrPersistentPlatformSignedPrivApp(PackageInfo pkg) {
if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) {
return true;
}
if (!pkg.applicationInfo.isPrivilegedApp()) {
return false;
}
final PackageInfo disabledPkg = getSystemPackageInfo(
mServiceInternal.getDisabledSystemPackageName(pkg.applicationInfo.packageName));
if (disabledPkg != null) {
ApplicationInfo disabledPackageAppInfo = disabledPkg.applicationInfo;
if (disabledPackageAppInfo != null
&& (disabledPackageAppInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) {
return false;
}
} else if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) {
return false;
}
return mServiceInternal.isPlatformSigned(pkg.packageName);
}
对于这部分符合要求的系统组件,系统的策略是尽可能授予组件需要的任何运行时权限。
frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
private void grantRuntimePermissionsForSystemPackage(int userId, PackageInfo pkg) {
Setpermissions = 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 /*systemFixed*/, userId);
}
}
grantDefaultSystemHandlerPermissions系统默认组件授权
系统需要相应一部分重要的intent的默认包被授予特定的运行时权限,所以就通过grantDefaultSystemHandlerPermissions为这些包授予特定的运行时权限。
frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
private void grantDefaultSystemHandlerPermissions(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;
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 = (useOpenWifiAppPackag