首先,作者巧妙的以應(yīng)用安裝作為切入點(diǎn)引入了包管理的話題。
進(jìn)而介紹了第一個(gè)關(guān)鍵類:PackageManager。
PackageManager是一個(gè)抽象類,具體實(shí)現(xiàn)類是ApplicationPackageManager。
PackageManager提供了以下幾個(gè)主要功能:
1.獲取一個(gè)應(yīng)用程序的所有信息
2.獲取四大組件的信息
3.查詢permission的相關(guān)信息
4.獲取包的信息
5.安裝、卸載apk
尋找PackageInstaller入口,
當(dāng)我們?cè)诔绦蛑姓{(diào)用以下代碼時(shí)(7.0以前):
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse("file://" + path), "application/vnd.android.package-archive");
startActivity(intent);
或者(7.0及以后)
因?yàn)?.0以后,Android要求使用ContentProvider替代原有的直接暴露Uri的方式訪問(wèn)文件。
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(xxx, "application/vnd.android.package-archive");
startActivity(intent);
最終我們都是跳轉(zhuǎn)到一個(gè)Activity去進(jìn)行安裝應(yīng)用,那這個(gè)Activity到底是哪個(gè)Activity呢?因?yàn)槭请[式跳轉(zhuǎn),所以我們要找到對(duì)應(yīng)匹配的Activity。
通過(guò)閱讀源碼,我們發(fā)現(xiàn)在7.0及以前能隱式匹配的Activity為PackageInstallerActivity,而在8.0及以后能匹配到的是InstallStart。
那就以InstallStart為入口跟蹤整個(gè)流程吧!
InstallStart是PackageInstaller中的入口Activity,其中PackageInstaller是系統(tǒng)內(nèi)置的應(yīng)用程序,用于安裝和卸載應(yīng)用。
進(jìn)入到InstallStart以后經(jīng)過(guò)對(duì)安裝路徑的解析,最終將其傳給InstallStaging頁(yè)面,在InstallStaging頁(yè)面中會(huì)開啟一個(gè)StagingAsyncTask任務(wù)。這個(gè)任務(wù)會(huì)將傳入的packageUri的內(nèi)容寫入到mStagedFile中,寫入成功的話,則將mStagedFile傳入到PackageInstallerActivity中,開啟PackageInstallerActivity頁(yè)面。所以,最終還是回到了PackageInstallerActivity里。
所以,你看人家google工程師就是牛逼,在寫代碼的時(shí)候就考慮到了代碼的可擴(kuò)展性。在7.0之后加入ContentProvider讀取文件信息的時(shí)候,也同樣可以復(fù)用之前PackageInstallerActivity的流程。
進(jìn)入到PackageInstallerActivity中,首先初始化了一堆安裝應(yīng)用所需要的對(duì)象:PackageManager、IPackageManager、UserManager等。然后,經(jīng)過(guò)解析PackageInfo等信息,最終調(diào)用checkIfAllowedAndInitiateInstall方法。
private void checkIfAllowedAndInitiateInstall() {
// Check for install apps user restriction first.
final int installAppsRestrictionSource = mUserManager.getUserRestrictionSource(
UserManager.DISALLOW_INSTALL_APPS, Process.myUserHandle());
if ((installAppsRestrictionSource & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) {
showDialogInner(DLG_INSTALL_APPS_RESTRICTED_FOR_USER);
return;
} else if (installAppsRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
startActivity(new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS));
finish();
return;
}
if (mAllowUnknownSources || !isInstallRequestFromUnknownSource(getIntent())) {
initiateInstall();
} else {
// Check for unknown sources restrictions.
final int unknownSourcesRestrictionSource = mUserManager.getUserRestrictionSource(
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, Process.myUserHandle());
final int unknownSourcesGlobalRestrictionSource = mUserManager.getUserRestrictionSource(
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, Process.myUserHandle());
final int systemRestriction = UserManager.RESTRICTION_SOURCE_SYSTEM
& (unknownSourcesRestrictionSource | unknownSourcesGlobalRestrictionSource);
if (systemRestriction != 0) {
showDialogInner(DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER);
} else if (unknownSourcesRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
startAdminSupportDetailsActivity(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
} else if (unknownSourcesGlobalRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
startAdminSupportDetailsActivity(
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY);
} else {
handleUnknownSources();
}
}
}
大概看一下這個(gè)方法,主要是判斷是不是允許安裝未知來(lái)源應(yīng)用或者判斷是不是未知來(lái)源應(yīng)用,如果不是的話進(jìn)入正常安裝流程即走initiateInstall方法,如果是未知來(lái)源應(yīng)用則會(huì)提示跳轉(zhuǎn)到設(shè)置頁(yè)面去開啟允許安裝未知來(lái)源應(yīng)用的開關(guān)。
下面就進(jìn)入到初始化安裝的確認(rèn)頁(yè)面了,即走startInstallConfirm方法。
這個(gè)方法會(huì)初始化安裝確認(rèn)頁(yè)面,然后會(huì)列出安裝apk需要訪問(wèn)的系統(tǒng)權(quán)限。
至此,PackageInstaller初始化的工作就完成了。
簡(jiǎn)單總結(jié)一下PackageInstaller初始化的過(guò)程:
1.根據(jù)Uri的scheme協(xié)議的不同,跳轉(zhuǎn)到不同的頁(yè)面。如果是Content協(xié)議,也就是走ContentProvider類型的則跳轉(zhuǎn)InstallStart頁(yè)面,其他的則跳轉(zhuǎn)的PackageInstallerActivity頁(yè)面。不過(guò)最終都會(huì)進(jìn)入到PackageInstallerActivity頁(yè)面進(jìn)行安裝的初始化流程。
2.PackageInstallerActivity會(huì)對(duì)package協(xié)議和file協(xié)議進(jìn)行分別處理,如果是file協(xié)議,會(huì)解析apk文件進(jìn)而得到包信息PackageInfo。
3.PackageInstallerActivity會(huì)對(duì)未知來(lái)源的APK進(jìn)行處理,如果允許未知來(lái)源的應(yīng)用或者APK不屬于未知來(lái)源則會(huì)初始化安裝確認(rèn)頁(yè)面。否則,彈出提示對(duì)話框或者跳轉(zhuǎn)到設(shè)置頁(yè)面。
ok,準(zhǔn)備工作已經(jīng)做完了,那正式進(jìn)入到安裝流程了。
當(dāng)我們點(diǎn)擊安裝確認(rèn)頁(yè)面的確認(rèn)按鈕時(shí),我們就正式進(jìn)入了安裝流程了。
private void startInstall() {
// Start subactivity to actually install the application
Intent newIntent = new Intent();
newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO,
mPkgInfo.applicationInfo);
newIntent.setData(mPackageURI);
newIntent.setClass(this, InstallInstalling.class);
String installerPackageName = getIntent().getStringExtra(
Intent.EXTRA_INSTALLER_PACKAGE_NAME);
if (mOriginatingURI != null) {
newIntent.putExtra(Intent.EXTRA_ORIGINATING_URI, mOriginatingURI);
}
if (mReferrerURI != null) {
newIntent.putExtra(Intent.EXTRA_REFERRER, mReferrerURI);
}
if (mOriginatingUid != PackageInstaller.SessionParams.UID_UNKNOWN) {
newIntent.putExtra(Intent.EXTRA_ORIGINATING_UID, mOriginatingUid);
}
if (installerPackageName != null) {
newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME,
installerPackageName);
}
if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
}
newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
if(localLOGV) Log.i(TAG, "downloaded app uri="+mPackageURI);
startActivity(newIntent);
finish();
}
可以看出會(huì)跳轉(zhuǎn)到InstallInstalling這個(gè)Activity中,并關(guān)閉當(dāng)前PackageInstallerActivity。
在InstallInstalling中,會(huì)注冊(cè)一個(gè)廣播來(lái)監(jiān)聽安裝apk最后的結(jié)果。即InstallEventReceiver。然后會(huì)開啟一個(gè)InstallingAsyncTask任務(wù),執(zhí)行這個(gè)任務(wù)即是安裝apk的過(guò)程。
@Override
protected void onResume() {
super.onResume();
// This is the first onResume in a single life of the activity
if (mInstallingTask == null) {
PackageInstaller installer = getPackageManager().getPackageInstaller();
PackageInstaller.SessionInfo sessionInfo = installer.getSessionInfo(mSessionId);
if (sessionInfo != null && !sessionInfo.isActive()) {
mInstallingTask = new InstallingAsyncTask();
mInstallingTask.execute();
} else {
// we will receive a broadcast when the install is finished
mCancelButton.setEnabled(false);
setFinishOnTouchOutside(false);
}
}
}
我們看一下InstallingAsyncTask最終的執(zhí)行結(jié)果,
@Override
protected void onPostExecute(PackageInstaller.Session session) {
if (session != null) {
Intent broadcastIntent = new Intent(BROADCAST_ACTION);
broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
broadcastIntent.setPackage(getPackageName());
broadcastIntent.putExtra(EventResultPersister.EXTRA_ID, mInstallId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
InstallInstalling.this,
mInstallId,
broadcastIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
session.commit(pendingIntent.getIntentSender());
mCancelButton.setEnabled(false);
setFinishOnTouchOutside(false);
} else {
getPackageManager().getPackageInstaller().abandonSession(mSessionId);
if (!isCancelled()) {
launchFailure(PackageManager.INSTALL_FAILED_INVALID_APK, null);
}
}
}
最終調(diào)用的session.commit方法,將這個(gè)intent發(fā)出去了。
而這個(gè)session其實(shí)是PackageInstallerSession,最終調(diào)用的是PMS的installState方法。
那么現(xiàn)在我們就來(lái)到了我們的主角PMS了。
上面我們分析到,最終是調(diào)用到PMS的installStage了。
void installStage(ActiveInstallSession activeInstallSession) {
if (DEBUG_INSTANT) {
if ((activeInstallSession.getSessionParams().installFlags
& PackageManager.INSTALL_INSTANT_APP) != 0) {
Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
}
}
final Message msg = mHandler.obtainMessage(INIT_COPY);
final InstallParams params = new InstallParams(activeInstallSession);
params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
msg.obj = params;
Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
System.identityHashCode(msg.obj));
Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
System.identityHashCode(msg.obj));
mHandler.sendMessage(msg);
}
可以發(fā)現(xiàn),其實(shí)是向mHandler發(fā)送了一個(gè)INIT_COPY的message。而這個(gè)mHandler其實(shí)是PackageHandler。它繼承自Handler,我們大概看一下對(duì)INIT_COPY消息的處理。
[圖片上傳失敗...(image-9176ee-1608472714341)]
那我們知道,其實(shí)安裝apk的過(guò)程就是將對(duì)應(yīng)的apk的文件解壓并copy到指定目錄的過(guò)程。在copy的過(guò)程當(dāng)中實(shí)際上是將對(duì)應(yīng)的文件存儲(chǔ)到了臨時(shí)的一個(gè)目錄當(dāng)中。

復(fù)制工作完成之后,才最后進(jìn)入到apk的安裝。
先上一張大神的時(shí)序圖,完了我們?cè)賮?lái)跟代碼:

我們上面跟到,handleStartCopy。下面緊接著就調(diào)用handleReturnCode方法。
@Override
void handleReturnCode() {
for (InstallParams params : mChildParams) {
params.handleReturnCode();
if (params.mRet != INSTALL_SUCCEEDED) {
mRet = params.mRet;
}
}
}
最終調(diào)用 processPendingInstall(mArgs, mRet);
// Queue up an async operation since the package installation may take a little while.
private void processInstallRequestsAsync(boolean success,
List<InstallRequest> installRequests) {
mHandler.post(() -> {
if (success) {
for (InstallRequest request : installRequests) {
request.args.doPreInstall(request.installResult.returnCode);
}
synchronized (mInstallLock) {
installPackagesTracedLI(installRequests);
}
for (InstallRequest request : installRequests) {
request.args.doPostInstall(
request.installResult.returnCode, request.installResult.uid);
}
}
for (InstallRequest request : installRequests) {
restoreAndPostInstall(request.args.user.getIdentifier(), request.installResult,
new PostInstallData(request.args, request.installResult, null));
}
});
}
最終調(diào)用的是installPackagesTracedLI方法。
private void installPackagesLI(List<InstallRequest> requests) {
final Map<String, ScanResult> preparedScans = new ArrayMap<>(requests.size());
final Map<String, InstallArgs> installArgs = new ArrayMap<>(requests.size());
final Map<String, PackageInstalledInfo> installResults = new ArrayMap<>(requests.size());
final Map<String, PrepareResult> prepareResults = new ArrayMap<>(requests.size());
final Map<String, VersionInfo> versionInfos = new ArrayMap<>(requests.size());
final Map<String, PackageSetting> lastStaticSharedLibSettings =
new ArrayMap<>(requests.size());
final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
boolean success = false;
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI");
for (InstallRequest request : requests) {
// TODO(b/109941548): remove this once we've pulled everything from it and into
// scan, reconcile or commit.
final PrepareResult prepareResult;
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
prepareResult =
preparePackageLI(request.args, request.installResult);
} catch (PrepareFailure prepareFailure) {
request.installResult.setError(prepareFailure.error,
prepareFailure.getMessage());
request.installResult.origPackage = prepareFailure.conflictingPackage;
request.installResult.origPermission = prepareFailure.conflictingPermission;
return;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
request.installResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
request.installResult.installerPackageName =
request.args.installSource.installerPackageName;
final String packageName = prepareResult.packageToScan.getPackageName();
prepareResults.put(packageName, prepareResult);
installResults.put(packageName, request.installResult);
installArgs.put(packageName, request.args);
try {
final ScanResult result = scanPackageTracedLI(
prepareResult.packageToScan, prepareResult.parseFlags,
prepareResult.scanFlags, System.currentTimeMillis(),
request.args.user, request.args.abiOverride);
if (null != preparedScans.put(result.pkgSetting.pkg.getPackageName(), result)) {
request.installResult.setError(
PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE,
"Duplicate package " + result.pkgSetting.pkg.getPackageName()
+ " in multi-package install request.");
return;
}
createdAppId.put(packageName, optimisticallyRegisterAppId(result));
versionInfos.put(result.pkgSetting.pkg.getPackageName(),
getSettingsVersionForPackage(result.pkgSetting.pkg));
if (result.staticSharedLibraryInfo != null) {
final PackageSetting sharedLibLatestVersionSetting =
getSharedLibLatestVersionSetting(result);
if (sharedLibLatestVersionSetting != null) {
lastStaticSharedLibSettings.put(result.pkgSetting.pkg.getPackageName(),
sharedLibLatestVersionSetting);
}
}
} catch (PackageManagerException e) {
request.installResult.setError("Scanning Failed.", e);
return;
}
}
ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
installResults,
prepareResults,
mSharedLibraries,
Collections.unmodifiableMap(mPackages), versionInfos,
lastStaticSharedLibSettings);
CommitRequest commitRequest = null;
synchronized (mLock) {
Map<String, ReconciledPackage> reconciledPackages;
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
reconciledPackages = reconcilePackagesLocked(
reconcileRequest, mSettings.mKeySetManagerService);
} catch (ReconcileFailure e) {
for (InstallRequest request : requests) {
request.installResult.setError("Reconciliation failed...", e);
}
return;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages");
commitRequest = new CommitRequest(reconciledPackages,
mUserManager.getUserIds());
commitPackagesLocked(commitRequest);
success = true;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
executePostCommitSteps(commitRequest);
} finally {
if (success) {
for (InstallRequest request : requests) {
final InstallArgs args = request.args;
if (args.mDataLoaderType != DataLoaderType.INCREMENTAL) {
continue;
}
if (args.signingDetails.signatureSchemeVersion != SIGNING_BLOCK_V4) {
continue;
}
// For incremental installs, we bypass the verifier prior to install. Now
// that we know the package is valid, send a notice to the verifier with
// the root hash of the base.apk.
final String baseCodePath = request.installResult.pkg.getBaseCodePath();
final String[] splitCodePaths = request.installResult.pkg.getSplitCodePaths();
final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
final int verificationId = mPendingVerificationToken++;
final String rootHashString = PackageManagerServiceUtils
.buildVerificationRootHashString(baseCodePath, splitCodePaths);
broadcastPackageVerified(verificationId, originUri,
PackageManager.VERIFICATION_ALLOW, rootHashString,
args.mDataLoaderType, args.getUser());
}
} else {
for (ScanResult result : preparedScans.values()) {
if (createdAppId.getOrDefault(result.request.parsedPackage.getPackageName(),
false)) {
cleanUpAppIdCreation(result);
}
}
// TODO(patb): create a more descriptive reason than unknown in future release
// mark all non-failure installs as UNKNOWN so we do not treat them as success
for (InstallRequest request : requests) {
if (request.installResult.freezer != null) {
request.installResult.freezer.close();
}
if (request.installResult.returnCode == PackageManager.INSTALL_SUCCEEDED) {
request.installResult.returnCode = PackageManager.INSTALL_UNKNOWN;
}
}
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
大概總結(jié)一下installPackageLI:
1.創(chuàng)建PackageParser,解析APK
2.檢查APK是否存在,如果存在就獲取此前沒(méi)被改名前的包名并在注釋1處賦值給PackageParser.Package類型的pkg。
3.如果Settings中存在要安裝的APK的信息,說(shuō)明此前安裝過(guò)該APK,則需要校驗(yàn)APK的簽名信息,確保替換安裝是安全的
4.重命名臨時(shí)文件。
5.系統(tǒng)App的更新安裝會(huì)有兩個(gè)限制,一個(gè)是系統(tǒng)App不能安裝在sd卡上,另一個(gè)是系統(tǒng)app不能被Instant App替換。
至此,PMS處理APK安裝就完成了。
總結(jié)一下步驟:
1.PackageInstaller安裝APK時(shí)會(huì)將APK的信息交由PMS處理,PMS通過(guò)向PackageHandler發(fā)送消息來(lái)驅(qū)動(dòng)apk的復(fù)制和安裝工作。
2.PMS發(fā)送INIT_COPY和MCS_BOUND類型的消息,控制PackageHandler來(lái)綁定DefaultContainerService,完成復(fù)制APK等工作
3.復(fù)制完APK后,開始進(jìn)行安裝APK的流程,包括安裝前的檢查、安裝APK和安裝后的收尾工作。
后續(xù),作者還介紹了PMS的創(chuàng)建過(guò)程。簡(jiǎn)單的說(shuō)就是在開機(jī)過(guò)程中,由SystemServer完成的啟動(dòng)關(guān)鍵服務(wù)過(guò)程中創(chuàng)建的。具體過(guò)程看如下代碼:
public static void main(String[] args) {
new SystemServer().run();
}
//run方法中
// Start services.
try {
t.traceBegin("StartServices");
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
t.traceEnd(); // StartServices
}
//而PMS就是在startBootstrapServices中
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
t.traceBegin("startBootstrapServices");
// Start the watchdog as early as possible so we can crash the system server
// if we deadlock during early boot
t.traceBegin("StartWatchdog");
final Watchdog watchdog = Watchdog.getInstance();
watchdog.start();
t.traceEnd();
Slog.i(TAG, "Reading configuration...");
final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
t.traceBegin(TAG_SYSTEM_CONFIG);
SystemServerInitThreadPool.submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
t.traceEnd();
// Platform compat service is used by ActivityManagerService, PackageManagerService, and
// possibly others in the future. b/135010838.
t.traceBegin("PlatformCompat");
PlatformCompat platformCompat = new PlatformCompat(mSystemContext);
ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE, platformCompat);
ServiceManager.addService(Context.PLATFORM_COMPAT_NATIVE_SERVICE,
new PlatformCompatNative(platformCompat));
AppCompatCallbacks.install(new long[0]);
t.traceEnd();
// FileIntegrityService responds to requests from apps and the system. It needs to run after
// the source (i.e. keystore) is ready, and before the apps (or the first customer in the
// system) run.
t.traceBegin("StartFileIntegrityService");
mSystemServiceManager.startService(FileIntegrityService.class);
t.traceEnd();
// Wait for installd to finish starting up so that it has a chance to
// create critical directories such as /data/user with the appropriate
// permissions. We need this to complete before we initialize other services.
t.traceBegin("StartInstaller");
Installer installer = mSystemServiceManager.startService(Installer.class);
t.traceEnd();
// In some cases after launching an app we need to access device identifiers,
// therefore register the device identifier policy before the activity manager.
t.traceBegin("DeviceIdentifiersPolicyService");
mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
t.traceEnd();
// Uri Grants Manager.
t.traceBegin("UriGrantsManagerService");
mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class);
t.traceEnd();
// Activity manager runs the show.
t.traceBegin("StartActivityManager");
// TODO: Might need to move after migration to WM.
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mWindowManagerGlobalLock = atm.getGlobalLock();
t.traceEnd();
// Data loader manager service needs to be started before package manager
t.traceBegin("StartDataLoaderManagerService");
mDataLoaderManagerService = mSystemServiceManager.startService(
DataLoaderManagerService.class);
t.traceEnd();
// Incremental service needs to be started before package manager
t.traceBegin("StartIncrementalService");
mIncrementalServiceHandle = startIncrementalService();
t.traceEnd();
// Power manager needs to be started early because other services need it.
// Native daemons may be watching for it to be registered so it must be ready
// to handle incoming binder calls immediately (including being able to verify
// the permissions for those calls).
t.traceBegin("StartPowerManager");
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
t.traceEnd();
t.traceBegin("StartThermalManager");
mSystemServiceManager.startService(ThermalManagerService.class);
t.traceEnd();
// Now that the power manager has been started, let the activity manager
// initialize power management features.
t.traceBegin("InitPowerManagement");
mActivityManagerService.initPowerManagement();
t.traceEnd();
// Bring up recovery system in case a rescue party needs a reboot
t.traceBegin("StartRecoverySystemService");
mSystemServiceManager.startService(RecoverySystemService.Lifecycle.class);
t.traceEnd();
// Now that we have the bare essentials of the OS up and running, take
// note that we just booted, which might send out a rescue party if
// we're stuck in a runtime restart loop.
RescueParty.registerHealthObserver(mSystemContext);
PackageWatchdog.getInstance(mSystemContext).noteBoot();
// Manages LEDs and display backlight so we need it to bring up the display.
t.traceBegin("StartLightsService");
mSystemServiceManager.startService(LightsService.class);
t.traceEnd();
t.traceBegin("StartSidekickService");
// Package manager isn't started yet; need to use SysProp not hardware feature
if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) {
mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS);
}
t.traceEnd();
// Display manager is needed to provide display metrics before package manager
// starts up.
t.traceBegin("StartDisplayManager");
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
t.traceEnd();
// We need the default display before we can initialize the package manager.
t.traceBegin("WaitForDisplay");
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
t.traceEnd();
// Only run "core" apps if we're encrypting the device.
String cryptState = VoldProperties.decrypt().orElse("");
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
mOnlyCore = true;
}
// Start the package manager.
if (!mRuntimeRestart) {
FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
FrameworkStatsLog
.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__PACKAGE_MANAGER_INIT_START,
SystemClock.elapsedRealtime());
}
t.traceBegin("StartPackageManagerService");
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
}
// Now that the package manager has started, register the dex load reporter to capture any
// dex files loaded by system server.
// These dex files will be optimized by the BackgroundDexOptService.
SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
t.traceEnd();
if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
FrameworkStatsLog
.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__PACKAGE_MANAGER_INIT_READY,
SystemClock.elapsedRealtime());
}
// Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
// A/B artifacts after boot, before anything else might touch/need them.
// Note: this isn't needed during decryption (we don't have /data anyways).
if (!mOnlyCore) {
boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
false);
if (!disableOtaDexopt) {
t.traceBegin("StartOtaDexOptService");
try {
Watchdog.getInstance().pauseWatchingCurrentThread("moveab");
OtaDexoptService.main(mSystemContext, mPackageManagerService);
} catch (Throwable e) {
reportWtf("starting OtaDexOptService", e);
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("moveab");
t.traceEnd();
}
}
}
t.traceBegin("StartUserManagerService");
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
t.traceEnd();
// Initialize attribute cache used to cache resources from packages.
t.traceBegin("InitAttributerCache");
AttributeCache.init(mSystemContext);
t.traceEnd();
// Set up the Application instance for the system process and get started.
t.traceBegin("SetSystemProcess");
mActivityManagerService.setSystemProcess();
t.traceEnd();
// Complete the watchdog setup with an ActivityManager instance and listen for reboots
// Do this only after the ActivityManagerService is properly started as a system process
t.traceBegin("InitWatchdog");
watchdog.init(mSystemContext, mActivityManagerService);
t.traceEnd();
// DisplayManagerService needs to setup android.display scheduling related policies
// since setSystemProcess() would have overridden policies due to setProcessGroup
mDisplayManagerService.setupSchedulerPolicies();
// Manages Overlay packages
t.traceBegin("StartOverlayManagerService");
mSystemServiceManager.startService(new OverlayManagerService(mSystemContext));
t.traceEnd();
t.traceBegin("StartSensorPrivacyService");
mSystemServiceManager.startService(new SensorPrivacyService(mSystemContext));
t.traceEnd();
if (SystemProperties.getInt("persist.sys.displayinset.top", 0) > 0) {
// DisplayManager needs the overlay immediately.
mActivityManagerService.updateSystemUiContext();
LocalServices.getService(DisplayManagerInternal.class).onOverlayChanged();
}
// The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
// Start sensor service in a separate thread. Completion should be checked
// before using it.
mSensorServiceStart = SystemServerInitThreadPool.submit(() -> {
TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
traceLog.traceBegin(START_SENSOR_SERVICE);
startSensorService();
traceLog.traceEnd();
}, START_SENSOR_SERVICE);
t.traceEnd(); // startBootstrapServices
}
可以看到,PMS和AMS的初始化都在其中,那還有另一個(gè)常見(jiàn)的WMS在哪里初始化的呢?
WMS以及IMS都是在startOtherServices方法中初始化的。
好了,下次再看WMS和AMS吧?。?!