PackageManagerService(PKMS)是Android操作系统的核心服务之一,它承载了丰富的功能模块。它的启动是在SystemServer启动PKMS,在 startBootstrapServices 中启动PKMS服务,再调用 startOtherServices 函数通过调用 updatePackagesIfNeeded 执行DEX优化操作,调用 performFstrimIfNeeded 执行磁盘管理,调用 systemReady 让PKMS进入SystemReady状态。
本文以android 13代码为例进行分析。
SystemServer 进程是由 Zygote 进程创建的,在 ZygoteInit 通过调用 Zygote.forkSystemServer 函数创建 systemServer 进程,经过一步步的执行流程,会走到 SystemServer 的 main 函数中。
1,在frameworks/base/services/java/com/android/server/SystemServer.java中
private PackageManagerService mPackageManagerService;
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
Looper.prepareMainLooper();
// Initialize the system context.
createSystemContext(); //加载系统资源
mSystemServiceManager = new SystemServiceManager(mSystemContext);
startBootstrapServices(t); //启动引导服务
startCoreServices(t); //启动核心服务
startOtherServices(t);
startApexServices(t);
Looper.loop();
}
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
IPackageManager iPackageManager;
t.traceBegin("StartPackageManagerService");
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain"); //调用了Watchdog的实例来暂停对当前线程的监控,避免在PackageManagerService启动过程中因为操作时间过长而被系统认为是无响应(ANR)
//通过调用PackageManagerService.main(...)方法启动PMS
Pair<PackageManagerService, IPackageManager> pmsPair = PackageManagerService.main(
mSystemContext, installer, domainVerificationService,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mPackageManagerService = pmsPair.first; //将Pair对象的first(即PackageManagerService的实例)保存到mPackageManagerService变量中。
iPackageManager = pmsPair.second; //将Pair对象的second(即IPackageManager的实现)保存到iPackageManager变量中,用于后续跨进程通信。
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain"); //在PMS启动完毕后,恢复对当前线程的监控。
}
}
上面的 startBootstrapServices 函数代码中调用 PackageManagerService 类的 main 函数。
2,在frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java中
public class PackageManagerService implements PackageSender, TestUtilityService {
public static Pair<PackageManagerService, IPackageManager> main(Context context,
Installer installer, @NonNull DomainVerificationService domainVerificationService,
boolean factoryTest, boolean onlyCore) {
// Self-check for initial settings.
PackageManagerServiceCompilerMapping.checkProperties(); // 用于自我检查初始设置
// 创建一个TimingsTraceAndSlog实例t,用于跟踪和记录性能时间,这里特别关注包管理器相关的性能。
final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
Trace.TRACE_TAG_PACKAGE_MANAGER);
t.traceBegin("create package manager");
// 创建一个PackageManagerTracedLock实例lock,用于在包管理器操作中提供线程安全,同时支持性能跟踪。
final PackageManagerTracedLock lock = new PackageManagerTracedLock();
// 创建一个普通的Object锁installLock,用于控制安装过程中的同步。
final Object installLock = new Object();
// 创建一个HandlerThread实例backgroundThread,命名为“PackageManagerBg”,设置为后台优先级,并允许IO操作。
//ServiceThread 继承自 HandlerThread,即public class ServiceThread extends HandlerThread
HandlerThread backgroundThread = new ServiceThread("PackageManagerBg",
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
// 启动backgroundThread线程。
backgroundThread.start();
// 创建一个Handler实例backgroundHandler,与backgroundThread的Looper关联,用于在该线程上执行任务。
Handler backgroundHandler = new Handler(backgroundThread.getLooper());
// PackageManagerServiceInjector是一个依赖注入容器,用于提供PackageManagerService所需的各种服务和组件。
PackageManagerServiceInjector injector = new PackageManagerServiceInjector(
context, lock, installer, installLock, new PackageAbiHelperImpl(),backgroundHandler,SYSTEM_PARTITIONS,
(i, pm) -> new ComponentResolver(i.getUserManagerService(), pm.mUserNeedsBadging),
(i, pm) -> PermissionManagerService.create(context,
i.getSystemConfig().getAvailableFeatures()),
(i, pm) -> new UserManagerService(context, pm,
new UserDataPreparer(installer, installLock, context, onlyCore),
lock),
(i, pm) -> new Settings(Environment.getDataDirectory(),
RuntimePermissionsPersistence.createInstance(),
i.getPermissionManagerServiceInternal(),
domainVerificationService, backgroundHandler, lock),
...
(i, pm) -> {
HandlerThread thread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);
thread.start();
return new PackageHandler(thread.getLooper(), pm);
},
...
(i, pm) -> new SharedLibrariesImpl(pm, i)
);
// 创建一个PackageManagerService的实例 m,传入多个参数。
PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest,
PackagePartitions.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG,
Build.VERSION.SDK_INT, Build.VERSION.INCREMENTAL);
t.traceEnd(); // "create package manager"
// 定义了一个CompatChange.ChangeListener的匿名类实例selinuxChangeListener,这个监听器用于监听SELinux安全上下文信息的变化。
final CompatChange.ChangeListener selinuxChangeListener = packageName -> { // packageName -> { ... }:这是一个Lambda表达式,用于处理变化的包名(packageName)。
...
};
// 注册了一个监听器selinuxChangeListener,用于监听SELinux策略的最新变化(SELinuxMMAC.SELINUX_LATEST_CHANGES)。这意味着当SELinux策略发生更新时,selinuxChangeListener将被通知并执行相应的操作。
injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_LATEST_CHANGES,
selinuxChangeListener);
injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_R_CHANGES,
selinuxChangeListener);
// 安装允许列表中的系统包。这些系统包通常是系统启动时必须存在的关键应用或服务。
m.installAllowlistedSystemPackages();
// 通过 PackageManagerService 实例 m 创建一个 IPackageManagerImpl 的实例 iPackageManager。
// IPackageManagerImpl 是一个接口实现,提供了远程服务调用的接口,允许其他应用或服务通过 Binder 机制与包管理器服务进行通信。
IPackageManagerImpl iPackageManager = m.new IPackageManagerImpl();
// 将iPackageManager服务添加到系统服务管理器(ServiceManager)中,并命名为"package"。这样,系统中的其他组件就可以通过ServiceManager获取到这个服务的引用,并与包管理器服务进行交互。
ServiceManager.addService("package", iPackageManager);
// 创建一个 PackageManagerNative 的实例 pmn,传入 PackageManagerService 实例 m 作为参数。
// PackageManagerNative 是一个封装了Binder通信机制的类,用于提供跨进程的包管理器服务。
final PackageManagerNative pmn = new PackageManagerNative(m);
// 将pmn服务添加到系统服务管理器中,并命名为"package_native"。这样,其他进程就可以通过Binder机制与这个服务进行通信,执行包管理相关的操作。
ServiceManager.addService("package_native", pmn);
// 将一个PackageManagerLocalImpl的实例添加到本地管理器注册表中,并与PackageManagerLocal.class关联。这允许在同一进程内的其他组件通过本地接口与包管理器服务进行交互,而不需要通过Binder机制进行跨进程通信。
LocalManagerRegistry.addManager(PackageManagerLocal.class, m.new PackageManagerLocalImpl());
//这行代码创建了一个包含PackageManagerService实例m和IPackageManagerImpl实例iPackageManager的对,并将其返回。这样,调用者就可以同时获得包管理器服务的本地实例和远程接口实例。
return Pair.create(m, iPackageManager);
}
}
上面代码中 main 函数主要处理的内容有:创建 PackageManagerServiceInjector 对象;创建 PackageManagerService 对象;创建 IPackageManagerImpl 对象;创建 PackageManagerNative 对象。
上面分析了在 startBootstrapServices 函数中启动PMS,在 startOtherServices 函数中仍有对 mPackageManagerService 的相关处理,接着分析。
3,在frameworks/base/services/java/com/android/server/SystemServer.java中
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
if (!mOnlyCore) {
t.traceBegin("UpdatePackagesIfNeeded");
try {
// 调用Watchdog.getInstance().pauseWatchingCurrentThread("dexopt")。
// Watchdog是一个监控机制,用于检测系统是否因为某些原因(如死锁)而停止响应。这里,它暂停了对当前线程的监控,并给出了一个原因标签"dexopt",这通常指的是Dalvik Executable (DEX) 文件优化过程。
Watchdog.getInstance().pauseWatchingCurrentThread("dexopt");
// 检查并更新系统上的应用程序包。如果检测到有包需要更新(比如因为安装、卸载或更新应用程序),则执行相应的操作。
mPackageManagerService.updatePackagesIfNeeded();
} catch (Throwable e) {
// reportWtf是“What a Terrible Failure”的缩写,用于报告严重的、不可恢复的错误。这里,它报告了一个与更新包相关的错误,并附带了异常对象e。
reportWtf("update packages", e);
} finally {
// 恢复对当前线程的监控。这确保了即使在发生异常的情况下,监控机制也能继续工作。
Watchdog.getInstance().resumeWatchingCurrentThread("dexopt");
}
t.traceEnd();
}
// 使用t.traceBegin("PerformFstrimIfNeeded")开始一个性能追踪,这个追踪的标签是"PerformFstrimIfNeeded"。这表示接下来的代码块是执行文件系统修剪操作(如果需要的话)的开始,并且这个操作的性能将被追踪。
// 文件系统修剪是一种优化操作,用于通知存储设备(如SSD)哪些数据块已经不再被使用,可以被回收或擦除以提高性能和寿命。
t.traceBegin("PerformFstrimIfNeeded");
try {
// performFstrimIfNeeded 方法的作用是检查是否需要执行文件系统修剪操作,并在需要时执行它。
mPackageManagerService.performFstrimIfNeeded(); // 执行磁盘清理,释放空间
} catch (Throwable e) {
reportWtf("performing fstrim", e);
}
t.traceEnd();
t.traceBegin("MakePackageManagerServiceReady");
mPackageManagerService.systemReady(); // 执行一些默认权限的检查和package信息更新操作以及进行一些相关服务的状态通知(*.systemReady())
t.traceEnd();
t.traceBegin("MakePackageManagerServiceReady");
mPackageManagerService.systemReady();
t.traceEnd();
}
上面的 startOtherServices 函数分别调用了PMS的 updatePackagesIfNeeded、performFstrimIfNeeded、systemReady 等函数。 首先分析下 updatePackagesIfNeeded 函数。
4,在frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java中
private final DexOptHelper mDexOptHelper; // 在 PackageManagerService 构造函数中初始化,即 mDexOptHelper = new DexOptHelper(this);
public void updatePackagesIfNeeded() {
mDexOptHelper.performPackageDexOptUpgradeIfNeeded();
}
上面的代码调用了 DexOptHelper 类的 performPackageDexOptUpgradeIfNeeded 函数。
5,在frameworks/base/services/core/java/com/android/server/pm/DexOptHelper.java中
@RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) // 注解表明调用这个方法需要READ_DEVICE_CONFIG权限。这个权限允许应用读取设备上的配置信息。
public void performPackageDexOptUpgradeIfNeeded() {
// 使用PackageManagerServiceUtils.enforceSystemOrRoot方法检查调用者是否是系统或root用户。如果不是,将抛出异常。
PackageManagerServiceUtils.enforceSystemOrRoot(
"Only the system can request package update");
// The default is "true".
if (!"false".equals(DeviceConfig.getProperty("runtime", "dexopt_system_ui_on_boot"))) { // 通过DeviceConfig.getProperty方法检查一个名为dexopt_system_ui_on_boot的设备配置属性。
// System UI is important to user experience, so we check it after a mainline update or
// an OTA. It may need to be re-compiled in these cases.
if (hasBcpApexesChanged() || mPm.isDeviceUpgrading()) {
checkAndDexOptSystemUi();
}
}
// We need to re-extract after an OTA.
boolean causeUpgrade = mPm.isDeviceUpgrading();
// First boot or factory reset.
// Note: we also handle devices that are upgrading to N right now as if it is their
// first boot, as they do not have profile data.
boolean causeFirstBoot = mPm.isFirstBoot() || mPm.isPreNUpgrade();
if (!causeUpgrade && !causeFirstBoot) {
return;
}
final Computer snapshot = mPm.snapshotComputer();
// 通过调用 getPackagesForDexopt 方法获取需要DEX优化的包列表。
List<PackageStateInternal> pkgSettings =
getPackagesForDexopt(snapshot.getPackageStates().values(), mPm);
List<AndroidPackage> pkgs = new ArrayList<>(pkgSettings.size());
for (int index = 0; index < pkgSettings.size(); index++) {
pkgs.add(pkgSettings.get(index).getPkg());
}
final long startTime = System.nanoTime();
// 调用 performDexOptUpgrade 方法执行DEX优化操作。这个方法接受一个包列表、是否显示对话框(对于旧版本Android的升级情况)、优化原因(首次启动或OTA后的启动)以及是否完成启动作为参数。
final int[] stats = performDexOptUpgrade(pkgs, mPm.isPreNUpgrade() /* showDialog */,
causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT_AFTER_OTA,
false /* bootComplete */);
final int elapsedTimeSeconds =
(int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
final Computer newSnapshot = mPm.snapshotComputer();
// 使用MetricsLogger.histogram方法记录DEX优化的性能指标,包括优化的包数量、跳过的包数量、失败的包数量、总包数量以及优化操作所花费的时间。
MetricsLogger.histogram(mPm.mContext, "opt_dialog_num_dexopted", stats[0]);
MetricsLogger.histogram(mPm.mContext, "opt_dialog_num_skipped", stats[1]);
MetricsLogger.histogram(mPm.mContext, "opt_dialog_num_failed", stats[2]);
MetricsLogger.histogram(mPm.mContext, "opt_dialog_num_total",
getOptimizablePackages(newSnapshot).size());
MetricsLogger.histogram(mPm.mContext, "opt_dialog_time_s", elapsedTimeSeconds);
}
上面的代码调用 performDexOptUpgrade 方法执行DEX优化操作。
下面分析下 performFstrimIfNeeded 函数。
public void performFstrimIfNeeded() {
// 通过调用PackageManagerServiceUtils.enforceSystemOrRoot方法,确保只有系统或root用户才能请求执行fstrim操作。
PackageManagerServiceUtils.enforceSystemOrRoot("Only the system can request fstrim");
// Before everything else, see whether we need to fstrim.
try {
// 获取IStorageManager接口的实例,这个接口用于与存储管理服务进行交互。
IStorageManager sm = InstallLocationUtils.getStorageManager();
if (sm != null) {
boolean doTrim = false;
// 从系统设置中读取FSTRIM_MANDATORY_INTERVAL的值,即两次强制fstrim操作之间的时间间隔。如果没有设置,则使用默认值 DEFAULT_MANDATORY_FSTRIM_INTERVAL。
// DEFAULT_MANDATORY_FSTRIM_INTERVAL是预先定义的,即private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
final long interval = android.provider.Settings.Global.getLong(
mContext.getContentResolver(),
android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
DEFAULT_MANDATORY_FSTRIM_INTERVAL);
// 如果时间间隔大于0,计算自上次维护以来的时间。如果这个时间超过了设定的间隔,则设置doTrim为true,表示需要执行fstrim。
if (interval > 0) {
final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
if (timeSinceLast > interval) {
doTrim = true;
Slog.w(TAG, "No disk maintenance in " + timeSinceLast
+ "; running immediately");
}
}
// 如果doTrim为true,则检查是否是首次启动(isFirstBoot()方法返回false),以及是否显示了DEX优化对话框(isDexOptDialogShown()方法返回true)。
// 如果是,尝试通过ActivityManager.getService().showBootMessage方法显示一条消息,告知用户正在执行fstrim操作。
if (doTrim) {
if (!isFirstBoot()) {
if (mDexOptHelper.isDexOptDialogShown()) {
try {
ActivityManager.getService().showBootMessage(
mContext.getResources().getString(
R.string.android_upgrading_fstrim), true);
} catch (RemoteException e) {
}
}
}
// runMaintenance先通过sm的发送H_FSTRIM消息给Handler,然后mVold对象通过binder调用vold进程的fstrim函数
sm.runMaintenance();
}
} else {
Slog.e(TAG, "storageManager service unavailable!");
}
} catch (RemoteException e) {
// Can't happen; StorageManagerService is local
}
}
上面的代码中通过 IStorageManager 跨进程调用 StorageManagerService 类的 runMaintenance 函数。
6,在frameworks/base/services/core/java/com/android/server/StorageManagerService.java中
// IStorageManager 是一个接口,定义了存储管理服务应该提供的功能。
// Stub 是AIDL(Android Interface Definition Language)中用于实现远程服务调用的一个类。
// 通过继承 IStorageManager.Stub,StorageManagerService 类能够作为服务端实现这些接口方法,允许其他应用或服务通过IPC(进程间通信)机制调用这些方法。
class StorageManagerService extends IStorageManager.Stub implements Watchdog.Monitor, ScreenObserver {
private final Handler mHandler;
private static final int H_FSTRIM = 4;
public void runMaintenance() {
// 通过调用 enforcePermission 方法,该方法检查当前调用者是否具有 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS 权限。
// 这是一个系统级权限,通常仅对系统应用或具有root权限的应用开放。如果调用者没有此权限,enforcePermission 方法将抛出一个 SecurityException 异常,阻止后续代码的执行。
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
runIdleMaintenance(null);
}
void runIdleMaintenance(Runnable callback) {
mHandler.sendMessage(mHandler.obtainMessage(H_FSTRIM, callback));
}
class StorageManagerServiceHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case H_FSTRIM: {
Slog.i(TAG, "Running fstrim idle maintenance");
// Remember when we kicked it off
try {
// 获取当前时间的毫秒数,并将其存储在 mLastMaintenance 变量中,以记录维护任务开始的时间。
mLastMaintenance = System.currentTimeMillis();
// 尝试将文件mLastMaintenanceFile的最后修改时间设置为维护任务开始的时间。
mLastMaintenanceFile.setLastModified(mLastMaintenance);
} catch (Exception e) {
Slog.e(TAG, "Unable to record last fstrim!");
}
// TODO: Reintroduce shouldBenchmark() test
fstrim(0, null); // 调用 fstrim 方法执行文件系统修剪操作。这里的 0 和 null 参数可能分别表示修剪的优先级和特定的挂载点(在这个例子中,使用默认值或对所有挂载点进行修剪)。
// invoke the completion callback, if any
// TODO: fstrim is non-blocking, so remove this useless callback
Runnable callback = (Runnable) msg.obj;
if (callback != null) {
callback.run();
}
break;
}
}
}
}
}
上面分析了 updatePackagesIfNeeded 和 performFstrimIfNeeded 函数,下面分析下 systemReady 函数。
7,在frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java中
public void systemReady() {
// 执行权限检查,确保只有系统或具有root权限的进程才能调用此方法。这是一种安全措施,用于防止未经授权的进程声明系统已准备就绪。
PackageManagerServiceUtils.enforceSystemOrRoot(
"Only the system can claim the system is ready");
// 获取内容解析器(ContentResolver)实例,它允许访问系统提供的内容提供者(如设置、全局配置等)。
final ContentResolver resolver = mContext.getContentResolver();
if (mReleaseOnSystemReady != null) {
for (int i = mReleaseOnSystemReady.size() - 1; i >= 0; --i) {
final File dstCodePath = mReleaseOnSystemReady.get(i);
F2fsUtils.releaseCompressedBlocks(resolver, dstCodePath);
}
mReleaseOnSystemReady = null;
}
// 将 mSystemReady 标记为 true,表示系统现在已准备就绪。
mSystemReady = true;
// 创建一个 ContentObserver 的匿名子类实例,并覆盖 onChange 方法。这个观察者将监听系统配置的变化
ContentObserver co = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
final boolean ephemeralFeatureDisabled =
Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0;
for (int userId : UserManagerService.getInstance().getUserIds()) {
final boolean instantAppsDisabledForUser =
ephemeralFeatureDisabled || Secure.getIntForUser(resolver,
Secure.INSTANT_APPS_ENABLED, 1, userId) == 0;
mWebInstantAppsDisabled.put(userId, instantAppsDisabledForUser);
}
}
};
// 通过 mContext.getContentResolver().registerContentObserver 方法注册了两个内容观察者 co,
// 分别监听全局设置(Global.ENABLE_EPHEMERAL_FEATURE)和安全设置(Secure.INSTANT_APPS_ENABLED)的变化。这些设置的变化可能会影响即时应用和临时功能的启用状态。
mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
.getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
false, co, UserHandle.USER_ALL); // UserHandle.USER_ALL 参数表示这些观察者将监听所有用户的变化。
mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
.getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
co.onChange(true); // 手动调用内容观察者的 onChange 方法,传入 true 作为参数,可能是为了立即应用当前的配置状态,而不需要等待实际的变化发生。
// 调用应用过滤器的 onSystemReady 方法,并传入包管理器的内部服务实例。
mAppsFilter.onSystemReady(LocalServices.getService(PackageManagerInternal.class));
// Disable any carrier apps. We do this very early in boot to prevent the apps from being
// disabled after already being started.
CarrierAppUtils.disableCarrierAppsUntilPrivileged(
mContext.getOpPackageName(), UserHandle.USER_SYSTEM, mContext); // 在系统启动早期禁用运营商应用,以防止它们在获得特权之前被启动。这是为了安全考虑。
disableSkuSpecificApps(); // 调用一个方法来禁用与特定SKU(库存单位)相关的应用。这可能是因为某些应用只适用于特定的硬件或配置。
// Read the compatibilty setting when the system is ready.
boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
mContext.getContentResolver(),
android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
ParsingPackageUtils.setCompatibilityModeEnabled(compatibilityModeEnabled);
if (DEBUG_SETTINGS) {
Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
}
synchronized (mLock) {
// 调用 mSettings.systemReady(mComponentResolver) 方法,该方法可能返回一些在系统就绪时需要更新的设置项。然后,遍历这些设置项,并调用 mSettings.writePackageRestrictionsLPr 方法来应用这些更改。
ArrayList<Integer> changed = mSettings.systemReady(mComponentResolver);
for (int i = 0; i < changed.size(); i++) {
mSettings.writePackageRestrictionsLPr(changed.get(i));
}
}
// 调用用户管理器的 systemReady 方法,可能是为了在系统准备就绪时执行一些用户相关的初始化或更新操作。
mUserManager.systemReady();
// Watch for external volumes that come and go over time
final StorageManager storage = mInjector.getSystemService(StorageManager.class);
// 通过 StorageManager 的实例 storage 注册了一个监听器 mStorageEventHelper,用于监听外部存储卷的连接和断开事件。这对于管理外部存储设备(如SD卡)上的应用和数据至关重要。
storage.registerListener(mStorageEventHelper);
// 分别调用安装服务和包DEX优化器的 systemReady 方法。这可能是为了在系统启动时初始化这些服务,或者应用一些启动时的配置。
mInstallerService.systemReady();
mPackageDexOptimizer.systemReady();
// Now that we're mostly running, clean up stale users and apps
// 分别调用用户管理器和存储事件帮助器的方法,用于清理不再需要的用户和应用。这可能涉及到删除未使用的用户数据或应用数据。
mUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
mStorageEventHelper.reconcileApps(snapshotComputer(), StorageManager.UUID_PRIVATE_INTERNAL);
// 调用权限管理器的 onSystemReady 方法,可能是为了在系统启动时初始化权限设置或应用一些权限策略。
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 (mSettings.isPermissionUpgradeNeeded(userId)) { // 检查每个活跃用户是否需要权限升级
grantPermissionsUserIds = ArrayUtils.appendInt(
grantPermissionsUserIds, userId); // 对于需要升级的用户,将它们添加到 grantPermissionsUserIds 数组中。
}
}
// If we upgraded grant all default permissions before kicking off.
for (int userId : grantPermissionsUserIds) {
// 对于数组中的每个用户ID,调用 mLegacyPermissionManager.grantDefaultPermissions(userId); 授予默认权限。这是为了确保在系统升级后,用户的应用能够继续正常运行,不会因为缺少必要的权限而出现问题。
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();
}
// 如果 mInstantAppResolverConnection 不为空,则注册一个广播接收器,监听 Intent.ACTION_BOOT_COMPLETED 动作。
// 当系统完成启动后,这个接收器会被触发,调用 mInstantAppResolverConnection.optimisticBind(); 方法尝试绑定即时应用解析器连接,并随后注销这个接收器。这是为了确保在系统启动后,即时应用解析器能够正确地连接和初始化。
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));
}
// 创建一个 IntentFilter 对象 overlayFilter,并设置其动作为 Intent.ACTION_OVERLAY_CHANGED。这个动作用于监听应用覆盖层(Overlay)的变化,比如当应用通过APKS(Application Package Signatures)或其他机制被覆盖时。
IntentFilter overlayFilter = new IntentFilter(Intent.ACTION_OVERLAY_CHANGED);
overlayFilter.addDataScheme("package");
// 通过 mContext.registerReceiver 注册一个 BroadcastReceiver,该接收器在接收到 Intent.ACTION_OVERLAY_CHANGED 广播时会被触发。
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null) {
return;
}
Uri data = intent.getData();
if (data == null) {
return;
}
String packageName = data.getSchemeSpecificPart();
if (packageName == null) {
return;
}
final Computer snapshot = snapshotComputer();
AndroidPackage pkg = snapshot.getPackage(packageName);
if (pkg == null) {
return;
}
sendPackageChangedBroadcast(snapshot, pkg.getPackageName(),
true /* dontKillApp */,
new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
pkg.getUid(),
Intent.ACTION_OVERLAY_CHANGED);
}
}, overlayFilter);
mModuleInfoProvider.systemReady();
// Installer service might attempt to install some packages that have been staged for
// installation on reboot. Make sure this is the last component to be call since the
// installation might require other components to be ready.
mInstallerService.restoreAndApplyStagedSessionIfNeeded();
mExistingPackages = null;
// Clear cache on flags changes.
// 使用 DeviceConfig.addOnPropertiesChangedListener 方法添加一个属性变化监听器。
// 当指定的配置属性(如 PROPERTY_INCFS_DEFAULT_TIMEOUTS 或 PROPERTY_KNOWN_DIGESTERS_LIST)发生变化时,会清除 mPerUidReadTimeoutsCache 缓存。这可能是为了确保当相关配置发生变化时,系统能够使用最新的配置信息。
DeviceConfig.addOnPropertiesChangedListener(
NAMESPACE_PACKAGE_MANAGER_SERVICE, mInjector.getBackgroundExecutor(),
properties -> {
final Set<String> keyset = properties.getKeyset();
if (keyset.contains(PROPERTY_INCFS_DEFAULT_TIMEOUTS) || keyset.contains(
PROPERTY_KNOWN_DIGESTERS_LIST)) {
mPerUidReadTimeoutsCache = null;
}
});
// 调用 mBackgroundDexOptService.systemReady(); 方法,可能是为了在系统启动时初始化后台DEX优化服务或应用一些启动时的配置。DEX优化是Android应用安装过程中的一个步骤,用于将DEX文件(Dalvik Executable文件)转换为更高效的格式。
mBackgroundDexOptService.systemReady();
// Prune unused static shared libraries which have been cached a period of time
schedulePruneUnusedStaticSharedLibraries(false /* delay */); // 计划修剪那些已经被缓存了一段时间但未使用的静态共享库。这有助于释放存储空间并优化系统性能。
}
至此,在SystemServer进程中启动PKMS整体流程分析完成,关于PKMS还有其它的内容后续进行分析。