PMS系列:
1、PackageManagerService服务框架详解
2、本文PackageManagerService启动分析
3、PackageManagerService之app数据类(Settings)分析
4、PackageManagerService扫描安装apk详解
5、PackageManagerService根据权限等级管理权限(默认赋予apk权限)
PackageManagerService初始化过程
简述Android启动
简单说一下Android的启动过程:
Android基于Linux,前面和Linux大致相同
按下电源 -> BIOS自检 -> 引导程序 -> 启动kernel -> 启动Init进程(system\core\init\init.c) -> 开启虚拟机(Zygotes)
然后
Zygote会startSystemServer,而Systemserver就开始启动framework层的各种公共服务,AMS、WMS、PMS等...
Systemserver启动PMS
从Systemserver.run开始,这里开始启动各种服务
private void run() {
...
// 初始化system Context
createSystemContext();
// 创建system manager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
// Start services.
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
// 开始引导Services,Installer创建user/data等目录,
// 以及MessageMonitorService,AMS,PowerManagerService,LightsService,DisplayManagerService,UserManagerService等
startBootstrapServices();
// 核心Services,BatteryService,UsageStatsService,WebViewUpdateService
startCoreServices();
// 其他Services,这里启动的服务最多,TelecomLoaderService,CameraService,AccountManagerService等等一系列Service
startOtherServices();
}
...
// Loop forever.
Looper.loop();
...
}
其他服务的启动这里就不展开了,这里开始看PMS的启动
private void startBootstrapServices() {
...
// 创建PMS
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
...
// 权限检查,启动其他服务需要授予权限,在这之前需要AMS先做权限检查
mPackageManagerService.onAmsAddedtoServiceMgr();
...
}
private void startOtherServices() {
...
//检查system app是否需要更新,需要则更新
mPackageManagerService.updatePackagesIfNeeded();
...
//检查system app是否需要fs裁剪
mPackageManagerService.performFstrimIfNeeded();
...
//最后system Ready通知其他服务ready设置相关信息
mPackageManagerService.systemReady();
...
}
详细过程分析
1、创建
PackageManagerService的main中主要进行new PackageManagerService操作,那么从PackageManagerService构建函数开始,这里进行大量的操作
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
...
mContext = context;
mFactoryTest = factoryTest;
//是否需要dex化
mOnlyCore = onlyCore;
//DisplayMetrics 屏幕信息
mMetrics = new DisplayMetrics();
//这个Settings类保存了apk的各种信息
mSettings = new Settings(mPackages);
//分配UID,方便权限管理
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);
...
mInstaller = installer;
//PackageDexOptimizer初始化,dex优化相关
mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
"*dexopt*");
//移动app的监听
mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
//Permission监听
mOnPermissionChangeListeners = new OnPermissionChangeListeners(
FgThread.get().getLooper());
//获得屏幕信息
getDefaultDisplayMetrics(context, mMetrics);
...
// writer
synchronized (mPackages) {
//消息处理线程
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();
mHandler = new PackageHandler(mHandlerThread.getLooper());
mProcessLoggingHandler = new ProcessLoggingHandler();
Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
//在手机的data目录下创建app、app-lib、app-ephemeral、app-asec、app-private
File dataDir = Environment.getDataDirectory();
mAppInstallDir = new File(dataDir, "app");
mAppLib32InstallDir = new File(dataDir, "app-lib");
mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
mAsecInternalPath = new File(dataDir, "app-asec").getPath();
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
sUserManager = new UserManagerService(context, this, mPackages);
//package manager权限配置
ArrayMap<String, SystemConfig.PermissionEntry> permConfig
= systemConfig.getPermissions();
for (int i=0; i<permConfig.size(); i++) {
SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
BasePermission bp = mSettings.mPermissions.get(perm.name);
if (bp == null) {
bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
mSettings.mPermissions.put(perm.name, bp);
}
if (perm.gids != null) {
bp.setGids(perm.gids, perm.perUser);
}
}
...
//保存lib路径
if (mSharedLibraries.size() > 0) {
...
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
final String lib = libEntry.path;
if (lib == null) {
continue;
}
try {
// Shared libraries do not have profiles so we perform a full
// AOT compilation (if needed).
int dexoptNeeded = DexFile.getDexOptNeeded(
lib, dexCodeInstructionSet,
getCompilerFilterForReason(REASON_SHARED_APK),
false /* newProfile */);
//判断是否需要dex优化
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/,
getCompilerFilterForReason(REASON_SHARED_APK),
StorageManager.UUID_PRIVATE_INTERNAL,
SKIP_SHARED_LIBRARY_CHECK);
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Library not found: " + lib);
} catch (IOException | InstallerException e) {
Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
+ e.getMessage());
}
}
}
}
//创建system/framework
File frameworkDir = new File(Environment.getRootDirectory(), "framework");
...
//从M开始,默认不给权限
if (mPromoteSystemApps) {
Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
while (pkgSettingIter.hasNext()) {
PackageSetting ps = pkgSettingIter.next();
if (isSystemApp(ps)) {
mExistingSystemPackages.add(ps.name);
}
}
}
//手机overlay资源覆盖包
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);
...
//接下来扫描安装apk
//扫描安装/custom/framework下apk
File customFrameworkDir = new File("/custom/framework");
scanDirLI(customFrameworkDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanFlags | SCAN_NO_DEX, 0);
...
//此处省略代码为扫描安装各种路径下的apk,和上面代码类似,e.g:system/priv-app、vender/app/等
...
//扫描安装apk,移除已经不在手机里的apk的信息,
final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
if (!mOnlyCore) {
Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
while (psit.hasNext()) {
PackageSetting ps = psit.next();
...
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
/// M: [Operator] Operator apps are belong to system domain, therefore, need prune.
/// M: [Operator] We should also consider OTA from old version without mtkFlag
if (!isVendorApp(ps) && !locationIsOperator(ps.codePath)) {
continue;
}
}
...
final PackageParser.Package scannedPkg = mPackages.get(ps.name);
if (scannedPkg != null) {
...
if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
logCriticalInfo(Log.WARN, "Expecting better updated system app for "
+ ps.name + "; removing system app. Last known codePath="
+ ps.codePathString + ", installStatus=" + ps.installStatus
+ ", versionCode=" + ps.versionCode + "; scanned versionCode="
+ scannedPkg.mVersionCode);
removePackageLI(scannedPkg, true);
mExpectingBetter.put(ps.name, ps.codePath);
}
continue;
}
if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
psit.remove();
logCriticalInfo(Log.WARN, "System package " + ps.name
+ " no longer exists; it's data will be wiped");
// Actual deletion of code and data will be handled by later
// reconciliation step
} else {
final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
possiblyDeletedUpdatedSystemApps.add(ps.name);
}
}
}
}
//查找未完成安装的apk
ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
for (int i = 0; i < deletePkgsList.size(); i++) {
...
final String packageName = deletePkgsList.get(i).name;
logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
synchronized (mPackages) {
mSettings.removePackageLPw(packageName);
}
}
//删除temp文件
deleteTempPackageFiles();
// 删除没有相关软件包的共享用户ID
mSettings.pruneSharedUsersLPw();
if (!mOnlyCore) {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
SystemClock.uptimeMillis());
//扫描安装/data/app/目录下的apk文件
scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
//扫描安装/data/app/app-private/目录下的apk文件
scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
| PackageParser.PARSE_FORWARD_LOCK,
scanFlags | SCAN_REQUIRE_KNOWN, 0);
//扫描安装/data/app-ephemeral/目录
scanDirLI(mEphemeralInstallDir, mDefParseFlags
| PackageParser.PARSE_IS_EPHEMERAL,
scanFlags | SCAN_REQUIRE_KNOWN, 0);
/**
* Remove disable package settings for any updated system
* apps that were removed via an OTA. If they're not a
* previously-updated app, remove them completely.
* Otherwise, just revoke their system-level permissions.
*/
for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
mSettings.removeDisabledSystemPackageLPw(deletedAppName);
String msg;
if (deletedPkg == null) {
msg = "Updated system package " + deletedAppName
+ " no longer exists; it's data will be wiped";
// Actual deletion of code and data will be handled by later
// reconciliation step
} else {
msg = "Updated system app + " + deletedAppName
+ " no longer present; removing system privileges for "
+ deletedAppName;
deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
/// M: [Operator] Revoke operator permissions for the original operator package
/// under operator folder was gone due to OTA
deletedPkg.applicationInfo.flagsEx &= ~ApplicationInfo.FLAG_EX_OPERATOR;
PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
/// M: [Operator] Revoke vendor permissions
deletedPs.pkgFlagsEx &= ~ApplicationInfo.FLAG_EX_OPERATOR;
}
logCriticalInfo(Log.WARN, msg);
}
/**
* Make sure all system apps that we expected to appear on
* the userdata partition actually showed up. If they never
* appeared, crawl back and revive the system version.
*/
for (int i = 0; i < mExpectingBetter.size(); i++) {
final String packageName = mExpectingBetter.keyAt(i);
if (!mPackages.containsKey(packageName)) {
final File scanFile = mExpectingBetter.valueAt(i);
logCriticalInfo(Log.WARN, "Expected better " + packageName
+ " but never showed up; reverting to system");
int reparseFlags = mDefParseFlags;
if (FileUtils.contains(privilegedAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED;
} else if (FileUtils.contains(systemAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR;
} else if (FileUtils.contains(vendorAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR;
} else if (FileUtils.contains(oemAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR;
} else {
Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
continue;
}
mSettings.enableSystemPackageLPw(packageName);
try {
scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse original system package: "
+ e.getMessage());
}
}
}
}
mExpectingBetter.clear();
//获得开机向导
mSetupWizardPackage = getSetupWizardPackageName();
if (mProtectedFilters.size() > 0) {
...
for (ActivityIntentInfo filter : mProtectedFilters) {
...
filter.setPriority(0);//设置优先级
}
}
...
// 为package更新正确的库文件路径
updateAllSharedLibrariesLPw();
....
// 更新packages最后使用的时间
mPackageUsage.readLP();
...
//white/back list
mForcePermReviewPkgs = new HashSet<String>(
Arrays.asList(mContext.getResources().getStringArray(
com.mediatek.internal.R.array.force_review_pkgs)));
...
mBlockPermReviewPkgs = new HashSet<String>(
Arrays.asList(mContext.getResources().getStringArray(
com.mediatek.internal.R.array.block_review_pkgs)));
...
//如果SDK改变,更新权限
int updateFlags = UPDATE_PERMISSIONS_ALL;
if (ver.sdkVersion != mSdkVersion) {
Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
+ mSdkVersion + "; regranting permissions for internal storage");
updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
}
updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
ver.sdkVersion = mSdkVersion;
...
if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) {
for (UserInfo user : sUserManager.getUsers(true)) {
mSettings.applyDefaultPreferredAppsLPw(this, user.id);
applyFactoryDefaultBrowserLPw(user.id);
primeDomainVerificationsLPw(user.id);
}
}
//为启动系统核心应用准备storage
final int storageFlags;
if (StorageManager.isFileEncryptedNativeOrEmulated()) {
storageFlags = StorageManager.FLAG_STORAGE_DE;
} else {
storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
}
reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM,
storageFlags);
//以ota方式第一次启动,需要清空缓存目录
if (mIsUpgrade && !onlyCore) {
Slog.i(TAG, "Build fingerprint changed; clearing code caches");
for (int i = 0; i < mSettings.mPackages.size(); i++) {
final PackageSetting ps = mSettings.mPackages.valueAt(i);
if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
// No apps are running this early, so no need to freeze
clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
| Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
}
ver.fingerprint = Build.FINGERPRINT;
}
//检查默认浏览器
checkDefaultBrowser();
...
mSettings.writeLPr();
//第一次开机,升级,执行dexopt
if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) {
long start = System.nanoTime();
List<PackageParser.Package> coreApps = new ArrayList<>();
for (PackageParser.Package pkg : mPackages.values()) {
if (pkg.coreApp) {
coreApps.add(pkg);
}
}
int[] stats = performDexOpt(coreApps, false,
getCompilerFilterForReason(REASON_CORE_APP));
final int elapsedTimeSeconds =
(int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds);
...
}
...
//初始化PackageInstallerService
mInstallerService = new PackageInstallerService(context, this);
//为系统组件公开私有服务
LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
//permission记录控制
if (CtaUtils.isCtaSupported()) {
mPermRecordController = new PermissionRecordController(mContext);
}
}
创建过程总结:
1、准备:创建Settings保存apk信息,分配UID,PackageDexOptimizer初始化,移动app的监听,Permission监听,启动消息线程
2、目录创建:data目录创建,保存lib路径,创建system/framework
3、扫描并安装:overlay资源覆盖包,扫描各种路径下的apk信息,安装,删除temp文件
4、更新:获得开机向导,跟新库文件路径,更新package使用时间,更新权限
5、准备完毕:准备storage,检查默认浏览器,执行dexopt,初始化PackageInstallerService,公开私有服务
小结
PMS启动分析到此结束,主要过程就是PMS的创建,这里只是对整个初始化过程进行一个整体的小结。把握PMS的整体流程,后续文章再对PMS进行细节分析。