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分析