Android 11.0源码系列之PMSPackageManagerService的创建
Posted bubbleben
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 11.0源码系列之PMSPackageManagerService的创建相关的知识,希望对你有一定的参考价值。
本篇涉及到的主要代码:
frameworks\\base\\services\\core\\java\\com\\android\\server\\pm
frameworks\\native\\cmds\\installd\\
frameworks\\base\\core\\java\\android\\content\\pm
众所周知Android系统框架提供了众多的系统服务,比如管理四大组件的AMS(ActivityManagerService),管理窗口的WMS(WindowManagerService),管理应用安装, 卸载和更新的PMS(PackageManagerService),管理输入事件和输入设备的IMS(InputManagerService)等等,本系列将基于Android 11.0.0_r1代码,从上到下(java->jni->native)对这几大服务进行逐一解读,旨在加深对Android体系结构的理解,了解框架层各组件的运行原理,为以后深入性能分析/系统优化/架构设计等打下坚实的基础。
上一篇我们介绍了PackageManagerService
所依赖的守护进程installd
的创建,这篇文章我们将继续PackageManagerService
的创建过程。
1.1 PackageManagerService的创建
[-> PackageManagerService.java]
PackageManagerService
的构造函数比较长,我们会省略部分无关代码,然后在接下来的小节中分别介绍一些重点流程的作用;
public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
// 在PackageManagerService构造函数执行完成后,就可以查询ApplicationInfo和PackageInfo
// 清空sApplicationInfoCache的缓存,它用于查询ApplicationInfo并缓存查询到的结果
PackageManager.disableApplicationInfoCache();
// 清空sPackageInfoCache的缓存,它用于查询PackageInfo并缓存查询到的结果
PackageManager.disablePackageInfoCache();
// 持有对Injector的引用
mInjector = injector;
// Injector持有对PackageManagService的引用
mInjector.bootstrap(this);
// mLock是PackageManagerService.main中传入Injector的lock
mLock = injector.getLock();
// mInstallLock是PackageManagerService.main中传入Injector的installLock
mInstallLock = injector.getInstallLock();
// SystemServer在PackageManagerService.main时传给它的system context
mContext = injector.getContext();
// 根据解锁状态来判断是否仅启动核心功能
mOnlyCore = onlyCore;
// PackageManagerService.main中传入Injector的Installer
mInstaller = injector.getInstaller();
// Expose private service for system components to use.
// 创建PackageManagerInternalImpl并将其添加到LocalServices中[见1.2小节]
mPmInternal = new PackageManagerInternalImpl();
LocalServices.addService(PackageManagerInternal.class, mPmInternal);
// PackageManagerService.main中传入Injector的Settings[见1.3小节]
mSettings = injector.getSettings();
mPermissionManagerService = (IPermissionManager) ServiceManager.getService("permissionmgr");
// 每个UID都有唯一的名称和对应的数值(比如SYSTEM_UID为1000)
// 加上统一的flag以及private flag来创建SharedUserSetting[见1.4小节]
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);
mSettings.addSharedUserLPw("android.uid.se", SE_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
// 创建PackageDexOptimizer:它的主要作用是通过installd来完成dex的优化
mPackageDexOptimizer = new PackageDexOptimizer(mInstaller, mInstallLock, mContext,
"*dexopt*");
// 创建DexManager:用来管理dex文件,其主要也是通过installd来完成dex的优化
mDexManager =
new DexManager(mContext, this, mPackageDexOptimizer, mInstaller, mInstallLock);
// 创建ArtManagerService:作为binder服务端提供访问runtime的途径
mArtManagerService = new ArtManagerService(mContext, this, mInstaller, mInstallLock);
// MoveCallbacks是一个Handler,它绑定了android.fg线程的Looper
mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
// 创建SystemConfig:用来加载全局系统配置信息[见1.5小节]
SystemConfig systemConfig = SystemConfig.getInstance();
// 获取在1.4.1小节加载出来的mAvailableFeatures
mAvailableFeatures = systemConfig.getAvailableFeatures();
// 作为客户端提供访问服务端IApexService的能力
mApexManager = ApexManager.getInstance();
mAppsFilter = mInjector.getAppsFilter();
final List<ScanPartition> scanPartitions = new ArrayList<>();
// 通过ApexManager.getActiveApexInfos()获取ActiveApexInfo,并将其解析成scanPartition
final List<ApexManager.ActiveApexInfo> activeApexInfos = mApexManager.getActiveApexInfos();
for (int i = 0; i < activeApexInfos.size(); i++) {
final ScanPartition scanPartition = resolveApexToScanPartition(activeApexInfos.get(i));
if (scanPartition != null) {
scanPartitions.add(scanPartition);
}
}
mDirsToScanAsSystem = new ArrayList<>();
// 将SYSTEM_PARTITIONS加入到待扫描的系统分区列表中[见1.6小节]
mDirsToScanAsSystem.addAll(SYSTEM_PARTITIONS);
// 将scanPartitions加入到待扫描的系统分区列表中
mDirsToScanAsSystem.addAll(scanPartitions);
// CHECKSTYLE:OFF IndentationCheck
synchronized (mInstallLock) {
// writer
synchronized (mLock) {
// 创建并启动一个名为"PackageManager"的HandlerThread
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();
// 创建PackageHandler并让其绑定该线程的Looper
mHandler = new PackageHandler(mHandlerThread.getLooper());
// 对PackageHandler增加WatchDog超时监听
Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
// 获取在1.4小节中读取的SharedLibraryEntry
ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig
= systemConfig.getSharedLibraries();
final int builtInLibCount = libConfig.size();
for (int i = 0; i < builtInLibCount; i++) {
String name = libConfig.keyAt(i);
SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
// 将其转化为SharedLibraryInfo并将其保存到mSharedLibraries
addBuiltInSharedLibraryLocked(entry.filename, name);
}
// Now that we have added all the libraries, iterate again to add dependency
// information IFF their dependencies are added.
long undefinedVersion = SharedLibraryInfo.VERSION_UNDEFINED;
// 同样添加依赖信息
for (int i = 0; i < builtInLibCount; i++) {
String name = libConfig.keyAt(i);
SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
final int dependencyCount = entry.dependencies.length;
for (int j = 0; j < dependencyCount; j++) {
final SharedLibraryInfo dependency =
getSharedLibraryInfoLPr(entry.dependencies[j], undefinedVersion);
if (dependency != null) {
getSharedLibraryInfoLPr(name, undefinedVersion).addDependency(dependency);
}
}
}
// 读取/system/etc/selinux下的Mandatory Access Control策略
SELinuxMMAC.readInstallPolicy();
// 这里的mSettings是在PackageManagerService.main里创建并传入Injector的[见1.7小节]
mFirstBoot = !mSettings.readLPw(mInjector.getUserManagerInternal().getUsers(false));
long startTime = SystemClock.uptimeMillis();
final String bootClassPath = System.getenv("BOOTCLASSPATH");
final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
// 创建/system/framework目录
File frameworkDir = new File(Environment.getRootDirectory(), "framework");
final VersionInfo ver = mSettings.getInternalVersion();
// 判断是否是升级
mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
// 创建/data/system/package_cache目录
mCacheDir = preparePackageParserCache();
// Set flag to monitor and not change apk file paths when
// scanning install directories.
int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
if (mIsUpgrade || mFirstBoot) {
scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
}
final int systemParseFlags = mDefParseFlags | PackageParser.PARSE_IS_SYSTEM_DIR;
final int systemScanFlags = scanFlags | SCAN_AS_SYSTEM;
// 创建PackageParser2
PackageParser2 packageParser = new PackageParser2(mSeparateProcesses, mOnlyCore,
mMetrics, mCacheDir, mPackageParserCallback);
// 固定线程的线程池
ExecutorService executorService = ParallelPackageParser.makeExecutorService();
// Collect vendor/product/system_ext overlay packages. (Do this before scanning
// any apps.)
// For security and version matching reason, only consider overlay packages if they
// reside in the right directory.
// 扫描/system,/vendor,/product,/oem,/odm,/system_ext分区下的overlay目录[见1.8小节]
for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
final ScanPartition partition = mDirsToScanAsSystem.get(i);
if (partition.getOverlayFolder() == null) {
continue;
}
scanDirTracedLI(partition.getOverlayFolder(), systemParseFlags,
systemScanFlags | partition.scanFlag, 0,
packageParser, executorService);
}
// 扫描/system/framework目录
scanDirTracedLI(frameworkDir, systemParseFlags,
systemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0,
packageParser, executorService);
for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
final ScanPartition partition = mDirsToScanAsSystem.get(i);
if (partition.getPrivAppFolder() != null) {
// 扫描/system,/vendor,/product,/oem,/odm,/system_ext分区下的priv-app目录
scanDirTracedLI(partition.getPrivAppFolder(), systemParseFlags,
systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0,
packageParser, executorService);
}
// 扫描/system,/vendor,/product,/oem,/odm,/system_ext分区下的app目录
scanDirTracedLI(partition.getAppFolder(), systemParseFlags,
systemScanFlags | partition.scanFlag, 0,
packageParser, executorService);
}
// Parse overlay configuration files to set default enable state, mutability, and
// priority of system overlays.
mOverlayConfig = OverlayConfig.initializeSystemInstance(
consumer -> mPmInternal.forEachPackage(
pkg -> consumer.accept(pkg, pkg.isSystem())));
final int cachedSystemApps = PackageCacher.sCachedPackageReadCount.get();
// Remove any shared userIDs that have no associated packages
mSettings.pruneSharedUsersLPw();
final long systemScanTime = SystemClock.uptimeMillis() - startTime;
final int systemPackagesCount = mPackages.size();
if (!mOnlyCore) {
// 扫描/data/app目录
scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0,
packageParser, executorService);
}
packageParser.close();
// Resolve the storage manager.
mStorageManagerPackage = getStorageManagerPackageName();
// Now that we know all of the shared libraries, update all clients to have
// the correct library paths.
updateAllSharedLibrariesLocked(null, null, Collections.unmodifiableMap(mPackages));
for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
// NOTE: We ignore potential failures here during a system scan (like
// the rest of the commands above) because there's precious little we
// can do about it. A settings error is reported, though.
final List<String> changedAbiCodePath =
applyAdjustedAbiToSharedUser(setting, null /*scannedPackage*/,
mInjector.getAbiHelper().getAdjustedAbiForSharedUser(
setting.packages, null /*scannedPackage*/));
if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
final String codePathString = changedAbiCodePath.get(i);
try {
mInstaller.rmdex(codePathString,
getDexCodeInstructionSet(getPreferredInstructionSet()));
} catch (InstallerException ignored) {
}
}
}
// Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
// SELinux domain.
setting.fixSeInfoLocked();
setting.updateProcesses();
}
// Now that we know all the packages we are keeping,
// read and update their last usage times.
mPackageUsage.read(mSettings.mPackages);
mCompilerStats.read();
// If the platform SDK has changed since the last time we booted,
// we need to re-grant app permission to catch any new ones that
// appear. This is really a hack, and means that apps can in some
// cases get permissions that the user didn't initially explicitly
// allow... it would be nice to have some better way to handle
// this situation.
final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
mPermissionManager.updateAllPermissions(
StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated);
ver.sdkVersion = mSdkVersion;
// If this is the first boot or an update from pre-M, and it is a normal
// boot, then we need to initialize the default preferred apps across
// all defined users.
if (!mOnlyCore && (mPromoteSystemApps || mFirstBoot)) {
for (UserInfo user : mInjector.getUserManagerInternal().getUsers(true)) {
mSettings.applyDefaultPreferredAppsLPw(user.id);
primeDomainVerificationsLPw(user.id);
}
}
// clear only after permissions and other defaults have been updated
mPromoteSystemApps = false;
// All the changes are done during package scanning.
ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
// can downgrade to reader
t.traceBegin("write settings");
//
mSettings.writeLPr();
t.traceEnd();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
SystemClock.uptimeMillis());
// PermissionController hosts default permission granting and role management, so it's a
// critical part of the core system.
mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();
mSettings.setPermissionControllerVersion(
getPackageInfo(mRequiredPermissionControllerPackage, 0,
UserHandle.USER_SYSTEM).getLongVersionCode());
// Read and update the usage of dex files.
// Do this at the end of PM init so that all the packages have their
// data directory reconciled.
// At this point we know the code paths of the packages, so we can validate
// the disk file and build the internal cache.
// The usage file is expected to be small so loading and verifying it
// should take a fairly small time compare to the other activities (e.g. package
// scanning).
final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
for (int userId : userIds) {
userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
}
mDexManager.load(userPackages);
} // synchronized (mLock)
} // synchronized (mInstallLock)
// CHECKSTYLE:ON IndentationCheck
mModuleInfoProvider = new ModuleInfoProvider(mContext, this);
// Uncork cache invalidations and allow clients to cache package information.
PackageManager.uncorkPackageInfoCache();
// Now after opening every single application zip, make sure they
// are all flushed. Not really needed, but keeps things nice and
// tidy.
t.traceBegin("GC");
Runtime.getRuntime().gc();
t.traceEnd();
// The initial scanning above does many calls into installd while
// holding the mPackages lock, but we're mostly interested in yelling
// once we have a booted system.
mInstaller.setWarnIfHeld(mLock);
PackageParser.readConfigUseRoundIcon(mContext.getResources());
mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
}
1.2 PackageManagerInternalImpl的创建
[-> PackageManagerService.java]
private class PackageManagerInternalImpl extends PackageManagerInternal {
@Override
public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
int callingUid) {
return PackageManagerService.this.getInstalledApplicationsListInternal(flags, userId,
callingUid);
}
......
}
PackageManagerInternalImpl
继承于PackageManagerInternal
,以getInstalledApplications
为例可以看出它只是对PackageManagerService
的接口做了一层封装;
/**
*Package manager local system service interface.
*@hide Only for use within the system server.
*/
public abstract class PackageManagerInternal {
public abstract List<ApplicationInfo> getInstalledApplications(
@ApplicationInfoFlags int flags, @UserIdInt int userId, int callingUid);
......
}
PackageManagerInternal
是一个抽象类,提供了很多抽象方法由其子类PackageManagerInternalImpl
去实现,它作为系统服务的接口仅在system_server
内部使用;
1.3 Settings
[-> Settings.java]
Settings(File dataDir, PermissionSettings permission,
Object lock) {
mLock = lock;
mPermissions = permission;
mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);
// 创建/data/system目录
mSystemDir = new File(dataDir, "system");
mSystemDir.mkdirs();
FileUtils.setPermissions(mSystemDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
// 创建/data/system/packages.xml
mSettingsFilename = new File(mSystemDir, "packages.xml");
// 创建/data/system/packages-backup.xml
mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
// 创建/data/system/packages.list
mPackageListFilename = new File(mSystemDir, "packages.list");
FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);
final File kernelDir = new File("/config/sdcardfs");
mKernelMappingFilename = kernelDir.exists() ? kernelDir : null;
// Deprecated: Needed for migration
// 创建/data/system/packages-stopped.xml
mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
// 创建/data/system/packages-stopped-backup.xml
mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
}
1.4 Settings.addSharedUserLPw
[-> Settings.java]
final ArrayMap<String, SharedUserSetting> mSharedUsers = new ArrayMap<>();
SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) {
SharedUserSetting s = mSharedUsers.get(name);
if (s != null) {
if (s.userId == uid) {
return s;
}
PackageManagerService.reportSettingsProblem(Log.ERROR,
"Adding duplicate shared user, keeping first: " + name);
return null;
}
// 根据传入的uid名称,flag和private flag构造SharedUserSetting
s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
s.userId = uid;
if (registerExistingAppIdLPw(uid, s, name)) {
mSharedUsers.put(name, s);
return s;
}
return null;
}
private boolean registerExistingAppIdLPw(int appId, SettingBase obj, Object name) {
if (appId > Process.LAST_APPLICATION_UID) {
return false;
}
// 应用程序的UID保存到mAppIds中
if (appId >= Process.FIRST_APPLICATION_UID) {
int size = mAppIds.size();
final int index = appId - Process.FIRST_APPLICATION_UID;
// fill the array until our index becomes valid
while (index >= size) {
mAppIds.add(null);
size++;
}
if (mAppIds.get(index) != null) {
PackageManagerService.reportSettingsProblem(Log.ERROR,
"Adding duplicate app id: " + appId
+ " name=" + name);
return false;
}
mAppIds.set(index, obj);
} else {
// 非应用程序的UID保存到mOtherAppIds中(比如SYSTEM_UID,RADIO_UID,LOG_UID,
// NFC_UID,BLUETOOTH_UID,SHELL_UID,SE_UID和NETWORKSTACK_UID)
if (mOtherAppIds.get(appId) != null) {
PackageManagerService.reportSettingsProblem(Log.ERROR,
"Adding duplicate shared id: " + appId
+ " name=" + name);
return false;
}
mOtherAppIds.put(appId, obj);
}
return true;
}
public final class SharedUserSetting extends SettingBase {
// 保存共享当前uid的所有应用的PackageSetting
final ArraySet<PackageSetting> packages = new ArraySet<>();
// 保存共享当前uid的所有应用的名称和进程的键值对
ArrayMap<String, ParsedProcess> processes;
SharedUserSetting(String _name, int _pkgFlags, int _pkgPrivateFlags) {
super(_pkgFlags, _pkgPrivateFlags);
uidFlags = _pkgFlags;
uidPrivateFlags = _pkgPrivateFlags;
name = _name;
seInfoTargetSdkVersion = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
}
}
我们都知道Android中的不同进程之间是相互隔离的,资源也是不共享的,但是可以通过shared user id的方式(在AndroidManifest.xml中配置android:sharedUserId),让拥有同一个user id的多个应用可以配置成运行在同一个进程中互相访问数据,在这里我们将由SYSTEM_UID,RADIO_UID,LOG_UID,NFC_UID,BLUETOOTH_UID,SHELL_UID,SE_UID和NETWORKSTACK_UID这8个UID构造的SharedUserSetting添加到mSharedUsers进行管理;
1.5 SystemConfig
[-> SystemConfig.java]
SystemConfig() {
log.traceBegin("readAllPermissions");
try {
// 读取所有权限配置[见1.5.1小节]
readAllPermissions();
} finally {
log.traceEnd();
}
}
public static SystemConfig getInstance() {
// 只能由系统进程来获取
if (!isSystemProcess()) {
Slog.wtf(TAG, "SystemConfig is being accessed by a process other than "
+ "system_server.");
}
synchronized (SystemConfig.class) {
if (sInstance == null) {
// 创建SystemConfig
sInstance = new SystemConfig();
}
return sInstance;
}
}
1.5.1 SystemConfig.readAllPermissions
[-> SystemConfig.java]
private void readAllPermissions() {
// Read configuration from system
// 读取/system/etc/sysconfig目录下的配置文件[见1.5.2小节]
readPermissions(Environment.buildPath(
Environment.getRootDirectory(), "etc", "sysconfig"), ALLOW_ALL);
// Read configuration from the old permissions dir
// 读取/system/etc/permissions目录下的配置文件
readPermissions(Environment.buildPath(
Environment.getRootDirectory(), "etc", "permissions"), ALLOW_ALL);
}
readAllPermissions
会调用readPermissions
读取不同路径(包括/vendor/etc,/odm/ect,/oem/etc,/product/etc,/system_ext/etc,/apex/etc下的sysconfig或permissions目录)下的配置文件,由于读取的逻辑都是相同的,所以我们就以/system/etc/sysconfig和/system/etc/permissions为例来分析整个读取过程;
1.5.2 SystemConfig.readPermissions
[-> SystemConfig.java]
public void readPermissions(File libraryDir, int permissionFlag) {
// Iterate over the files in the directory and scan .xml files
File platformFile = null;
for (File f : libraryDir.listFiles()) {
// We'll read platform.xml last
// 获取/system/etc/permissions/platforms.xml文件
if (f.getPath().endsWith("etc/permissions/platform.xml")) {
platformFile = f;
continue;
}
// 读取除/system/etc/permissions/platforms.xml外的其他所有配置文件[见1.5.3小节]
readPermissionsFromXml(f, permissionFlag);
}
// Read platform permissions last so it will take precedence
if (platformFile != null) {
// 读取/system/etc/permissions/platforms.xml文件
readPermissionsFromXml(platformFile, permissionFlag);
}
}
1.5.3 SystemConfig.readPermissionsFromXml
[-> SystemConfig.java]
private void readPermissionsFromXml(File permFile, int permissionFlag) {
FileReader permReader = null;
try {
permReader = new FileReader(permFile);
} catch (FileNotFoundException e) {
Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
return;
}
try {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(permReader);
while (true) {
XmlUtils.nextElement(parser);
String name = parser.getName();
switch (name) {
case "group":
break;
// 读取权限
case "permission": {
String perm = parser.getAttributeValue(null, "name");
perm = perm.intern();
// 将permission的name,perUser和group封装成PermissionEntry保存到mPermissions
readPermission(parser, perm);
} break;
case "assign-permission":
break;
case "split-permission":
break;
// 读取共享库
case "library": {
String lname = parser.getAttributeValue(null, "name");
String lfile = parser.getAttributeValue(null, "file");
String ldependency = parser.getAttributeValue(null, "dependency");
SharedLibraryEntry entry = new SharedLibraryEntry(lname, lfile,
ldependency == null ? new String[0] : ldependency.split(":"));
// 将library的name,file和依赖封装成SharedLibraryEntry保存到mSharedLibraries
mSharedLibraries.put(lname, entry);
} break;
// 读取feature
case "feature": {
String fname = parser.getAttributeValue(null, "name");
int fversion = XmlUtils.readIntAttribute(parser, "version", 0);
// 将feature name和version封装为FeatureInfo保存到mAvailableFeatures
addFeature(fname, fversion);
} break;
case "unavailable-feature":
break;
case "allow-in-power-save-except-idle":
break;
case "allow-in-power-save":
break;
case "allow-in-data-usage-save":
break;
case "allow-unthrottled-location":
break;
case "allow-ignore-location-settings":
break;
// 读取显示广播白名单
case "allow-implicit-broadcast": {
String action = parser.getAttributeValue(null, "action");
mAllowImplicitBroadcasts.add(action);
} break;
case "app-link":
break;
case "system-user-whitelisted-app":
break;
case "system-user-blacklisted-app":
break;
case "default-enabled-vr-app":
break;
case "component-override":
break;
case "backup-transport-whitelisted-service":
break;
case "disabled-until-used-preinstalled-carrier-associated-app":
break;
case "disabled-until-used-preinstalled-carrier-app":
break;
case "privapp-permissions":
break;
case "oem-permissions":
break;
case "hidden-api-whitelisted-app":
break;
case "allow-association":
break;
case "app-data-isolation-whitelisted-app":
break;
case "bugreport-whitelisted":
break;
case "install-in-user-type":
break;
case "named-actor":
break;
case "rollback-whitelisted-app":
break;
case "whitelisted-staged-installer":
break;
default:
break;
}
}
} catch (XmlPullParserException e) {
Slog.w(TAG, "Got exception parsing permissions.", e);
} catch (IOException e) {
Slog.w(TAG, "Got exception parsing permissions.", e);
} finally {
IoUtils.closeQuietly(permReader);
}
// Some devices can be field-converted to FBE, so offer to splice in
// those features if not already defined by the static config
if (StorageManager.isFileEncryptedNativeOnly()) {
addFeature(PackageManager.FEATURE_FILE_BASED_ENCRYPTION, 0);
addFeature(PackageManager.FEATURE_SECURELY_REMOVES_USERS, 0);
}
// Help legacy devices that may not have updated their static config
if (StorageManager.hasAdoptable()) {
addFeature(PackageManager.FEATURE_ADOPTABLE_STORAGE, 0);
}
if (ActivityManager.isLowRamDeviceStatic()) {
addFeature(PackageManager.FEATURE_RAM_LOW, 0);
} else {
addFeature(PackageManager.FEATURE_RAM_NORMAL, 0);
}
if (IncrementalManager.isFeatureEnabled()) {
addFeature(PackageManager.FEATURE_INCREMENTAL_DELIVERY, 0);
}
if (PackageManager.APP_ENUMERATION_ENABLED_BY_DEFAULT) {
addFeature(PackageManager.FEATURE_APP_ENUMERATION, 0);
}
if (Build.VERSION.FIRST_SDK_INT >= Build.VERSION_CODES.Q) {
addFeature(PackageManager.FEATURE_IPSEC_TUNNELS, 0);
}
for (String featureName : mUnavailableFeatures) {
removeFeature(featureName);
}
}
readPermissionsFromXml
会从xml文件中读取不同节点的内容,这些节点大体上可以分为三类:权限类(比如读取permission节点),配置类(比如读取feature节点)和白名单类(比如读取显示广播白名单的allow-implicit-broadcast),读取出来的内容会保存到内存中,供后续其他系统服务调用;
1.6 SYSTEM_PARTITIONS
[-> SystemConfig.java]
public static final List<ScanPartition> SYSTEM_PARTITIONS = Collections.unmodifiableList(
PackagePartitions.getOrderedPartitions(ScanPartition::new));
通过PackagePartitions.getOrderedPartitions获取所有待扫描的系统分区列表;
[-> PackagePartitions.java]
private static final ArrayList<SystemPartition> SYSTEM_PARTITIONS =
new ArrayList<>(Arrays.asList(
// /system分区,包含/priv-app文件夹,不包含/overlay文件夹
new SystemPartition(Environment.getRootDirectory(), PARTITION_SYSTEM,
true /* containsPrivApp */, false /* containsOverlay */),
// /vendor分区,包含/priv-app文件夹,包含/overlay文件夹
new SystemPartition(Environment.getVendorDirectory(), PARTITION_VENDOR,
true /* containsPrivApp */, true /* containsOverlay */),
// /odm分区,包含/priv-app文件夹,包含/overlay文件夹
new SystemPartition(Environment.getOdmDirectory(), PARTITION_ODM,
true /* containsPrivApp */, true /* containsOverlay */),
// /oem分区,不包含/priv-app文件夹,包含/overlay文件夹
new SystemPartition(Environment.getOemDirectory(), PARTITION_OEM,
false /* containsPrivApp */, true /* containsOverlay */),
// /product分区,包含/priv-app文件夹,包含/overlay文件夹
new SystemPartition(Environment.getProductDirectory(), PARTITION_PRODUCT,
true /* containsPrivApp */, true /* containsOverlay */),
// /system_ext分区,包含/priv-app文件夹,包含/overlay文件夹
new SystemPartition(Environment.getSystemExtDirectory(), PARTITION_SYSTEM_EXT,
true /* containsPrivApp */, true /* containsOverlay */)));
public static <T> ArrayList<T> getOrderedPartitions(
@NonNull Function<SystemPartition, T> producer) {
final ArrayList<T> out = new ArrayList<>();
for (int i = 0, n = SYSTEM_PARTITIONS.size(); i < n; i++) {
final T v = producer.apply(SYSTEM_PARTITIONS.get(i));
if (v != null) {
out.add(v);
}
}
return out;
}
PackageManagerService
会根据这里创建的SystemPartition
来扫描各个分区(包括/system,/vendor,/product,/oem,/odm,/system_ext)文件夹(比如/system/app和/system/priv-app)里的应用;
1.7 Settings.readLPw
[-> Settings.java]
Settings(File dataDir, PermissionSettings permission, Object lock) {
mLock = lock;
mPermissions = permission;
mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);
// 创建/data/system目录
mSystemDir = new File(dataDir, "system");
mSystemDir.mkdirs();
FileUtils.setPermissions(mSystemDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
// 创建/data/system/packages.xml文件
mSettingsFilename = new File(mSystemDir, "packages.xml");
// 创建/data/system/packages-backup.xml文件
mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
// 创建/dasta/system/packages.list文件
mPackageListFilename = new File(mSystemDir, "packages.list");
FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);
final File kernelDir = new File("/config/sdcardfs");
mKernelMappingFilename = kernelDir.exists() ? kernelDir : null;
// Deprecated: Needed for migration
// 创建/dasta/system/packages-stopped.xml文件
mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
// 创建/dasta/system/packages-stopped-backup.xml文件
mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
}
Settings的构造函数主要完成与package相关的一些文件的创建,这些文件保存了系统所有安装包的信息;
// 读取所有active的用户目录下的package文件相关信息
boolean readLPw(@NonNull List<UserInfo> users) {
FileInputStream str = null;
mPendingPackages.clear();
mPastSignatures.clear();
mKeySetRefs.clear();
mInstallerPackages.clear();
try {
if (str == null) {
str = new FileInputStream(mSettingsFilename);
}
// 解析/data/system/packages.xml
XmlPullParser parser = Xml.newPullParser();
parser.setInput(str, StandardCharsets.UTF_8.name());
int type;
int outerDepth = parser.getDepth();
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
String tagName = parser.getName();
// 读取package:解析package节点的各属性值,创建PackageSetting并将其添加到mPackages
if (tagName.equals("package")) {
readPackageLPw(parser);
// 读取permissions:解析permissions节点,创建BasePermission并将其添加到mPermissions
} else if (tagName.equals("permissions")) {
mPermissions.readPermissions(parser);
// 读取shared-user:解析shared-user节点,创建SharedUserSetting并将其添加到mSharedUsers
} else if (tagName.equals("shared-user")) {
readSharedUserLPw(parser);
}
}
str.close();
}
// 如果/dasta/system/packages-stopped.xml或者/dasta/system/packages-stopped-backup.xml存在的话
// 就加载解析文件并更新对应的PackageSetting值
if (mBackupStoppedPackagesFilename.exists()
|| mStoppedPackagesFilename.exists()) {
// Read old file
readStoppedLPw();
mBackupStoppedPackagesFilename.delete();
mStoppedPackagesFilename.delete();
// Migrate to new file format
writePackageRestrictionsLPr(UserHandle.USER_SYSTEM);
} else {
// 否则如果/data/system/users/userid/package-restrictions-backup.xml存在就读取它
// 否则就读取/data/system/users/userid/package-restrictions.xml
for (UserInfo user : users) {
readPackageRestrictionsLPr(user.id);
}
}
return true;
}
1.8 scanDirTracedLI
[-> PackageManagerService.java]
private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags,
long currentTime, PackageParser2 packageParser, ExecutorService executorService) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
try {
scanDirLI(scanDir, parseFlags, scanFlags, currentTime, packageParser, executorService);
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime,
PackageParser2 packageParser, ExecutorService executorService) {
final File[] files = scanDir.listFiles();
// 创建ParallelPackageParser:通过线程池并行解析
ParallelPackageParser parallelPackageParser =
new ParallelPackageParser(packageParser, executorService);
// Submit files for parsing in parallel
int fileCount = 0;
// 遍历目录下的所有文件
for (File file : files) {
final boolean isPackage = (isApkFile(file) || file.isDirectory())
&& !PackageInstallerService.isStageName(file.getName());
if (!isPackage) {
// Ignore entries which are not packages
continue;
}
// 提交一个文件扫描的任务[见1.8.1小节]
parallelPackageParser.submit(file, parseFlags);
fileCount++;
}
// Process results one by one
for (; fileCount > 0; fileCount--) {
// 获取扫描结果
ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
Throwable throwable = parseResult.throwable;
int errorCode = PackageManager.INSTALL_SUCCEEDED;
if (throwable == null) {
// TODO(toddke): move lower in the scan chain
// Static shared libraries have synthetic package names
if (parseResult.parsedPackage.isStaticSharedLibrary()) {
renameStaticSharedLibraryPackage(parseResult.parsedPackage);
}
try {
addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
currentTime, null);
} catch (PackageManagerException e) {
errorCode = e.error;
Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
}
} else if (throwable instanceof PackageParserException) {
PackageParserException e = (PackageParserException)
throwable;
errorCode = e.error;
Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
}
}
}
1.8.1 ParallelPackageParser.submit
[-> ParallelPackageParser.java]
ParallelPackageParser(PackageParser2 packageParser, ExecutorService executorService) {
// 1.2小节中创建的PackageParser2
mPackageParser = packageParser;
// 1.2小节中创建的固定线程的线程池
mExecutorService = executorService;
}
public void submit(File scanFile, int parseFlags) {
// 往线程池提交一个任务
mExecutorService.submit(() -> {
ParseResult pr = new ParseResult();
try {
pr.scanFile = scanFile;
// 解析文件[见1.8.2小节]
pr.parsedPackage = parsePackage(scanFile, parseFlags);
} catch (Throwable e) {
pr.throwable = e;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
try {
mQueue.put(pr);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
// Propagate result to callers of take().
// This is helpful to prevent main thread from getting stuck waiting on
// ParallelPackageParser to finish in case of interruption
mInterruptedInThread = Thread.currentThread().getName();
}
});
}
1.8.2 ParallelPackageParser.parsePackage
[-> PackageParser2.java]
protected ParsedPackage parsePackage(File scanFile, int parseFlags)
throws PackageParser.PackageParserException {
// 利用PackageParser2解析扫描文件[见1.9小节]
return mPackageParser.parsePackage(scanFile, parseFlags, true);
}
1.9 PackageParser2.parsePackage
[-> ParallelPackageParser.java]
public PackageParser2(String[] separateProcesses, boolean onlyCoreApps,
DisplayMetrics displayMetrics, @Nullable File cacheDir, @NonNull Callback callback) {
// 创建PackageCacher, 并传入/system/package_cache目录
mCacher = cacheDir == null ? null : new PackageCacher(cacheDir);
// 创建ParsingPackageUtils
parsingUtils = new ParsingPackageUtils(onlyCoreApps, separateProcesses, displayMetrics,
callback);
ParseInput.Callback enforcementCallback = (changeId, packageName, targetSdkVersion) -> {
ApplicationInfo appInfo = mSharedAppInfo.get();
//noinspection ConstantConditions
appInfo.packageName = packageName;
appInfo.targetSdkVersion = targetSdkVersion;
return callback.isChangeEnabled(changeId, appInfo);
};
mSharedResult = ThreadLocal.withInitial(() -> new ParseTypeImpl(enforcementCallback));
}
public ParsedPackage parsePackage(File packageFile, int flags, boolean useCaches)
throws PackageParserException {
if (useCaches && mCacher != null) {
// 从PackageCacher中查找如果有缓存则直接返回缓存结果[见1.9.1小节]
ParsedPackage parsed = mCacher.getCachedResult(packageFile, flags);
if (parsed != null) {
return parsed;
}
}
long parseTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0;
ParseInput input = mSharedResult.get().reset();
// 通过ParsingUtils.parsePackage扫描文件[见1.10小节]
ParseResult<ParsingPackage> result = parsingUtils.parsePackage(input, packageFile, flags);
if (result.isError()) {
throw new PackageParserException(result.getErrorCode(), result.getErrorMessage(),
result.getException());
}
ParsedPackage parsed = (ParsedPackage) result.getResult().hideAsParsed();
long cacheTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0;
// 将扫描结果进行缓存[见1.8.1小节]
if (mCacher != null) {
mCacher.cacheResult(packageFile, flags, parsed);
}
return parsed;
}
1.9.1 PackageCacher.getCachedResult
[-> PackageCacher.java]
public ParsedPackage getCachedResult(File packageFile, int flags) {
// 通过StringBuilder创建连接文件名和flag的字符串的cacheKey
final String cacheKey = getCacheKey(packageFile, flags);
// 在/system/package_cache目录下创建以cacheKey命名的文件
final File cacheFile = new File(mCacheDir, cacheKey);
try {
// If the cache is not up to date, return null.
if (!isCacheUpToDate(packageFile, cacheFile)) {
return null;
}
// 读取缓存文件的字节数组
final byte[] bytes = IoUtils.readFileAsByteArray(cacheFile.getAbsolutePath());
// 将字节数组转换为ParsedPackage
return fromCacheEntry(bytes);
} catch (Throwable e) {
Slog.w(TAG, "Error reading package cache: ", e);
// If something went wrong while reading the cache entry, delete the cache file
// so that we regenerate it the next time.
cacheFile.delete();
return null;
}
}
public void cacheResult(File packageFile, int flags, ParsedPackage parsed) {
try {
final String cacheKey = getCacheKey(packageFile, flags);
final File cacheFile = new File(mCacheDir, cacheKey);
// 先删除原始缓存
if (cacheFile.exists()) {
if (!cacheFile.delete()) {
Slog.e(TAG, "Unable to delete cache file: " + cacheFile);
}
}
// 将扫描结果ParsedPackage转换为字节数组
final byte[] cacheEntry = toCacheEntry(parsed);
if (cacheEntry == null) {
return;
}
try (FileOutputStream fos = new FileOutputStream(cacheFile)) {
// 将字节数组写入文件
fos.write(cacheEntry);
} catch (IOException ioe) {
Slog.w(TAG, "Error writing cache entry.", ioe);
cacheFile.delete();
}
} catch (Throwable e) {
Slog.w(TAG, "Error saving package cache.", e);
}
}
1.10 ParsingPackageUtils.parsePackage
[-> ParsingPackageUtils.java]
public ParseResult<ParsingPackage> parsePackage(ParseInput input, File packageFile,
int flags)
throws PackageParserException {
if (packageFile.isDirectory()) {
return parseClusterPackage(input, packageFile, flags);
} else {
// 扫描文件[见1.10.1小节]
return parseMonolithicPackage(input, packageFile, flags);
}
}
1.10.1 ParsingPackageUtils.parseMonolithicPackage
[-> ParsingPackageUtils.java]
private ParseResult<ParsingPackage> parseMonolithicPackage(ParseInput input, File apkFile,
int flags) throws PackageParserException {
ParseResult<PackageParser.PackageLite> liteResult =
ApkLiteParseUtils.parseMonolithicPackageLite(input, apkFile, flags);
final PackageParser.PackageLite lite = liteResult.getResult();
final SplitAssetLoader assetLoader = new DefaultSplitAssetLoader(lite, flags);
try {
// 解析AndroidManifest.xml[见1.12小节]
ParseResult<ParsingPackage> result = parseBaseApk(input,
apkFile,
apkFile.getCanonicalPath(),
assetLoader.getBaseAssetManager(), flags);
if (result.isError()) {
return input.error(result);
}
return input.success(result.getResult()
.setUse32BitAbi(lite.use32bitAbi));
}
}
1.11 ApkLiteParseUtils.parseMonolithicPackageLite
[-> ApkLiteParseUtils.java]
public static ParseResult<PackageParser.PackageLite> parseMonolithicPackageLite(
ParseInput input, File packageFile, int flags) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parseApkLite");
try {
// 轻量级解析[见1.11.1小节]
ParseResult<PackageParser.ApkLite> result = parseApkLite(input, packageFile, flags);
if (result.isError()) {
return input.error(result);
}
final PackageParser.ApkLite baseApk = result.getResult();
final String packagePath = packageFile.getAbsolutePath();
return input.success(
new PackageParser.PackageLite(packagePath, baseApk, null, null, null, null,
null, null));
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
1.11.1 ApkLiteParseUtils.parseApkLite
[-> ApkLiteParseUtils.java]
public static ParseResult<PackageParser.ApkLite> parseApkLite(ParseInput input, File apkFile,
int flags) {
return parseApkLiteInner(input, apkFile, null, null, flags);
}
private static ParseResult<PackageParser.ApkLite> parseApkLiteInner(ParseInput input,
File apkFile, FileDescriptor fd, String debugPathName, int flags) {
final String apkPath = fd != null ? debugPathName : apkFile.getAbsolutePath();
XmlResourceParser parser = null;
ApkAssets apkAssets = null;
try {
try {
// 创建ApkAssets
apkAssets = fd != null
? ApkAssets.loadFromFd(fd, debugPathName, 0 /* flags */, null /* assets */)
: ApkAssets.loadFromPath(apkPath);
}
// 解析AndroidManifest.xml
parser = apkAssets.openXml(PackageParser.ANDROID_MANIFEST_FILENAME);
final PackageParser.SigningDetails signingDetails;
if ((flags & PackageParser.PARSE_COLLECT_CERTIFICATES) != 0) {
final boolean skipVerify = (flags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
try {
ParseResult<PackageParser.SigningDetails> result =
ParsingPackageUtils.getSigningDetails(input,
apkFile.getAbsolutePath(), skipVerify, false,
PackageParser.SigningDetails.UNKNOWN,
DEFAULT_TARGET_SDK_VERSION);
if (result.isError()) {
return input.error(result);
}
signingDetails = result.getResult();
}
} else {
signingDetails = PackageParser.SigningDetails.UNKNOWN;
}
final AttributeSet attrs = parser;
// [见1.11.2小节]
return parseApkLite(input, apkPath, parser, attrs, signingDetails);
}
}
1.11.2 ApkLiteParseUtils.parseApkLite
[-> ApkLiteParseUtils.java]
private static ParseResult<PackageParser.ApkLite> parseApkLite(ParseInput input,
String codePath, XmlPullParser parser, AttributeSet attrs,
PackageParser.SigningDetails signingDetails)
throws IOException, XmlPullParserException {
ParseResult<Pair<String, String>> result = parsePackageSplitNames(input, parser, attrs);
if (result.isError()) {
return input.error(result);
}
Pair<String, String> packageSplit = result.getResult();
int installLocation = PARSE_DEFAULT_INSTALL_LOCATION;
int versionCode = 0;
int versionCodeMajor = 0;
int targetSdkVersion = DEFAULT_TARGET_SDK_VERSION;
int minSdkVersion = DEFAULT_MIN_SDK_VERSION;
int revisionCode = 0;
boolean coreApp = false;
boolean debuggable = false;
boolean profilableByShell = false;
boolean multiArch = false;
boolean use32bitAbi = false;
boolean extractNativeLibs = true;
boolean isolatedSplits = false;
boolean isFeatureSplit = false;
boolean isSplitRequired = false;
boolean useEmbeddedDex = false;
String configForSplit = null;
String usesSplitName = null;
String targetPackage = null;
boolean overlayIsStatic = false;
int overlayPriority = 0;
String requiredSystemPropertyName = null;
String requiredSystemPropertyValue = null;
for (int i = 0; i < attrs.getAttributeCount(); i++) {
final String attr = attrs.getAttributeName(i);
switch (attr) {
case "installLocation":
installLocation = attrs.getAttributeIntValue(i,
PARSE_DEFAULT_INSTALL_LOCATION);
break;
case "versionCode":
versionCode = attrs.getAttributeIntValue(i, 0);
break;
case "versionCodeMajor":
versionCodeMajor = attrs.getAttributeIntValue(i, 0);
break;
case "revisionCode":
revisionCode = attrs.getAttributeIntValue(i, 0);
break;
case "coreApp":
coreApp = attrs.getAttributeBooleanValue(i, false);
break;
case "isolatedSplits":
isolatedSplits = attrs.getAttributeBooleanValue(i, false);
break;
case "configForSplit":
configForSplit = attrs.getAttributeValue(i);
break;
case "isFeatureSplit":
isFeatureSplit = attrs.getAttributeBooleanValue(i, false);
break;
case "isSplitRequired":
isSplitRequired = attrs.getAttributeBooleanValue(i, false);
break;
}
}
// Only search the tree when the tag is the direct child of <manifest> tag
int type;
final int searchDepth = parser.getDepth() + 1;
final List<VerifierInfo> verifiers = new ArrayList<>();
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() >= searchDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
if (parser.getDepth() != searchDepth) {
continue;
}
if (PackageParser.TAG_PACKAGE_VERIFIER.equals(parser.getName())) {
final VerifierInfo verifier = parseVerifier(attrs);
if (verifier != null) {
verifiers.add(verifier);
}
} else if (PackageParser.TAG_APPLICATION.equals(parser.getName())) {
for (int i = 0; i < attrs.getAttributeCount(); ++i) {
final String attr = attrs.getAttributeName(i);
switch (attr) {
case "debuggable":
debuggable = attrs.getAttributeBooleanValue(i, false);
if (debuggable) {
// Debuggable implies profileable
profilableByShell = true;
}
break;
case "multiArch":
multiArch = attrs.getAttributeBooleanValue(i, false);
break;
case "use32bitAbi":
use32bitAbi = attrs.getAttributeBooleanValue(i, false);
break;
case "extractNativeLibs":
extractNativeLibs = attrs.getAttributeBooleanValue(i, true);
break;
case "useEmbeddedDex":
useEmbeddedDex = attrs.getAttributeBooleanValue(i, false);
break;
}
}
} else if (PackageParser.TAG_OVERLAY.equals(parser.getName())) {
for (int i = 0; i < attrs.getAttributeCount(); ++i) {
final String attr = attrs.getAttributeName(i);
if ("requiredSystemPropertyName".equals(attr)) {
requiredSystemPropertyName = attrs.getAttributeValue(i);
} else if ("requiredSystemPropertyValue".equals(attr)) {
requiredSystemPropertyValue = attrs.getAttributeValue(i);
} else if ("targetPackage".equals(attr)) {
targetPackage = attrs.getAttributeValue(i);;
} else if ("isStatic".equals(attr)) {
overlayIsStatic = attrs.getAttributeBooleanValue(i, false);
} else if ("priority".equals(attr)) {
overlayPriority = attrs.getAttributeIntValue(i, 0);
}
}
} else if (PackageParser.TAG_USES_SPLIT.equals(parser.getName())) {
if (usesSplitName != null) {
Slog.w(TAG, "Only one <uses-split> permitted. Ignoring others.");
continue;
}
usesSplitName = attrs.getAttributeValue(PackageParser.ANDROID_RESOURCES, "name");
if (usesSplitName == null) {
return input.error(PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
"<uses-split> tag requires 'android:name' attribute");
}
} else if (PackageParser.TAG_USES_SDK.equals(parser.getName())) {
for (int i = 0; i < attrs.getAttributeCount(); ++i) {
final String attr = attrs.getAttributeName(i);
if ("targetSdkVersion".equals(attr)) {
targetSdkVersion = attrs.getAttributeIntValue(i,
DEFAULT_TARGET_SDK_VERSION);
}
if ("minSdkVersion".equals(attr)) {
minSdkVersion = attrs.getAttributeIntValue(i, DEFAULT_MIN_SDK_VERSION);
}
}
} else if (PackageParser.TAG_PROFILEABLE.equals(parser.getName())) {
for (int i = 0; i < attrs.getAt以上是关于Android 11.0源码系列之PMSPackageManagerService的创建的主要内容,如果未能解决你的问题,请参考以下文章
Android 11.0源码系列之IMSInputManagerService
Android 11.0源码系列之IMSInputManager
Android 11.0源码系列之IMSInputDispatcher