上次Android源码分析开机动画退出(《》),今天就看一下Intent.ACTION_BOOT_COMPLETED广播啥时候发送的。
记录于此,方便自己查阅。
正文
回到上一篇的finishBooting()中。
ActivityManagerService.java
finishBooting()
/** * 系统启动流程的最终阶段: * 当开机动画结束、系统核心服务就绪后,AMS 在此完成启动收尾工作。 * * 主要职责: * 1. 等待 boot animation 真正完成 * 2. 通知 ART / Zygote 启动完成 * 3. 注册关键广播监听 * 4. 通知 StorageManager / SystemServiceManager * 5. 启动被挂起的进程 * 6. 设置 boot_completed 系统属性 * 7. 发送 BOOT_COMPLETED 相关广播 */ final void finishBooting() { synchronized (this) { // 如果开机动画还没结束,先标记“需要补调用 finishBooting” // 等动画结束后再真正执行后续逻辑 if (!mBootAnimationComplete) { mCallFinishBooting = true; t.traceEnd(); return; } // 动画已完成,清除标记 mCallFinishBooting = false; } // ==================== 通知运行时 ==================== // 告诉 Zygote 和系统 Server 的 ART 虚拟机:系统启动完成 // 用于触发 JIT 编译、堆整理、预加载优化等 ZYGOTE_PROCESS.bootCompleted(); VMRuntime.bootCompleted(); // ==================== 注册包重启查询广播 ==================== // 用于判断某个 package 是否可以被安全地 force-stop // 例如:ANR / 低内存清理前做安全检查 IntentFilter pkgFilter = new IntentFilter(); pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); pkgFilter.addDataScheme("package"); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); if (pkgs != null) { for (String pkg : pkgs) { synchronized (ActivityManagerService.this) { // 如果包可以被 force-stop,则返回 OK if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, "query restart")) { setResultCode(Activity.RESULT_OK); return; } } } } } }, pkgFilter); // ==================== 存储 Checkpoint 提交 ==================== // 用于 FBE(文件级加密)或 A/B 更新后的数据一致性保障 try { IStorageManager storageManager = InstallLocationUtils.getStorageManager(); storageManager.commitChanges(); } catch (Exception e) { // 如果提交失败,直接重启设备以保证数据安全 PowerManager pm = (PowerManager) mInjector.getContext().getSystemService(Context.POWER_SERVICE); pm.reboot("Checkpoint commit failed"); } // ==================== 通知所有 SystemService ==================== // 触发 PHASE_BOOT_COMPLETED // 各服务(WMS / PMS / PKMS 等)在此阶段完成最后初始化 mSystemServiceManager.startBootPhase(t, SystemService.PHASE_BOOT_COMPLETED); synchronized (this) { // ==================== 启动被挂起的进程 ==================== // 某些进程在启动早期被放入 mProcessesOnHold // 现在统一批量启动 final int NP = mProcessesOnHold.size(); if (NP > 0) { ArrayList<ProcessRecord> procs = new ArrayList<>(mProcessesOnHold); for (int ip = 0; ip < NP; ip++) { if (DEBUG_PROCESSES) { Slog.v(TAG_PROCESSES, "Starting process on hold: " + procs.get(ip)); } mProcessList.startProcessLocked( procs.get(ip), new HostingRecord(HostingRecord.HOSTING_TYPE_ON_HOLD), ZYGOTE_POLICY_FLAG_BATCH_LAUNCH); } } // ==================== 功耗监控 ==================== // 启动后开始监控异常 WakeLock 使用 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG); mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL); // ==================== Userspace Reboot 处理 ==================== // 如果是用户空间重启,记录成功事件 if (InitProperties.userspace_reboot_in_progress().orElse(false)) { UserspaceRebootLogger.noteUserspaceRebootSuccess(); } // ==================== 设置 boot_completed 属性 ==================== // sys.boot_completed = 1 是系统启动完成的“黄金标志” // init / native 进程都会监听这个属性 SystemProperties.set("sys.boot_completed", "1"); // dev.bootcomplete = 1 用于更早阶段的服务判断 if (!"trigger_restart_min_framework".equals(VoldProperties.decrypt().orElse("")) || "".equals(VoldProperties.encrypt_progress().orElse(""))) { SystemProperties.set("dev.bootcomplete", "1"); } // ==================== 发送 BOOT_COMPLETED ==================== // 通知所有用户、所有应用:系统启动完成 // 这是第三方应用收到的最重要的启动广播 mUserController.sendBootCompleted( new IIntentReceiver.Stub() { @Override public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) { synchronized (mProcLock) { // 广播发送后,立即收集一次所有进程的 PSS 信息 mAppProfiler.requestPssAllProcsLPr( SystemClock.uptimeMillis(), true, false); } } }); // 记录 userspace reboot 相关指标 maybeLogUserspaceRebootEvent(); // 启动用户 profile(多用户场景) mUserController.scheduleStartProfiles(); } // ==================== 控制台 / MTE 警告 ==================== // 如果 UART console 开启,发出安全提醒 showConsoleNotificationIfActive(); showMteOverrideNotificationIfActive(); t.traceEnd(); }
上面有个关注点,
mUserController.sendBootCompleted(...);这个是用户相关控制类。
UserController.java
sendBootCompleted()
/** * 向指定用户发送启动完成信号。 * * 该方法在用户解锁(unlocked)后被调用, * 负责完成用户级初始化,并最终发送 {@link Intent#ACTION_BOOT_COMPLETED} 广播。 * * 本方法直接影响: * - 应用首次启动时机 * - 开机动画结束后的桌面首帧时间 * - 多用户场景下的应用可见性 */ /* private */ void sendBootCompleted(UserState uss) { final int userId = uss.mHandle.getIdentifier(); synchronized (mLock) { // 防御性校验:防止用户已被移除,避免操作过期对象 if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) { return; } } UserInfo userInfo = getUserInfo(userId); if (userInfo == null) { return; } // ==================== FBE 安全校验 ==================== // 文件级加密(FBE)场景下,用户密钥必须已解锁 // 否则不能访问用户数据,也不能继续初始化 if (!StorageManager.isUserKeyUnlocked(userId)) { return; } // 记录用户登录状态(用于最近登录用户、多用户切换等) mInjector.getUserManager().onUserLoggedIn(userId); // 用户初始化任务:仅执行一次 Runnable initializeUser = () -> mInjector.getUserManager().makeInitialized(userInfo.id); // ==================== 用户首次初始化 ==================== // 某些用户配置(铃声、时区、默认应用)只在首次启动时设置 if (!userInfo.isInitialized()) { Slogf.d(TAG, "Initializing user #" + userId); if (userInfo.preCreated) { // 预创建用户:直接同步初始化 initializeUser.run(); } else if (userId != UserHandle.USER_SYSTEM) { // 非系统用户:通过 ACTION_USER_INITIALIZE 通知系统组件 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); mInjector.broadcastIntent(intent, null, new IIntentReceiver.Stub() { @Override public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) { // 广播处理完成后,正式标记用户已初始化 initializeUser.run(); } }, 0, null, null, null, AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), userId); } } // ==================== 预创建用户特殊处理 ==================== // 预创建用户仅用于提前加载服务,并非真实可用用户 // 初始化完成后立即停掉,避免占用资源 if (userInfo.preCreated) { Slogf.i(TAG, "Stopping pre-created user " + userInfo.toFullString()); stopUser(userInfo.id, /* force= */ true, /* allowDelayedLocking= */ false, /* stopUserCallback= */ null, /* keyEvictedCallback= */ null); return; } // ==================== 启动 AppWidget ==================== // 在 BOOT_COMPLETED 之前启动 widget, // 确保桌面组件(时钟、天气等)及时就绪 // 【Unisoc 优化点】widget 越早启动,桌面首帧越快 mInjector.startUserWidgets(userId); // 通知内部状态机:用户已解锁 mHandler.obtainMessage(USER_UNLOCKED_MSG, userId, 0).sendToTarget(); Slogf.i(TAG, "Posting BOOT_COMPLETED user #" + userId); // ==================== 系统启动耗时统计 ==================== // 仅统计系统用户、非 runtime restart、非首次开机/OTA 场景 if (userId == UserHandle.USER_SYSTEM && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) { final long elapsedTimeMs = SystemClock.elapsedRealtime(); FrameworkStatsLog.write( FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED, FrameworkStatsLog .BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__FRAMEWORK_BOOT_COMPLETED, elapsedTimeMs); } // ==================== 发送 ACTION_BOOT_COMPLETED ==================== // 这是应用层能收到的“系统启动完成”最关键信号 // 直接影响: // - 第三方应用启动时机 // - JobScheduler / AlarmManager 首次运行 // - 开机自启类应用的执行时间 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); bootIntent.addFlags( Intent.FLAG_RECEIVER_NO_ABORT // 不允许拦截,保证必达 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND // 允许后台应用接收 | Intent.FLAG_RECEIVER_OFFLOAD); // Android 13+:广播卸载优化 final int callingUid = Binder.getCallingUid(); final int callingPid = Binder.getCallingPid(); // 【关键顺序保证】 // Widget 广播通过 FgThread 发送, // 为保证 widget → boot_completed 的顺序一致性, // BOOT_COMPLETED 也通过 FgThread 发送 FgThread.getHandler().post(() -> { mInjector.broadcastIntent(bootIntent, null, new IIntentReceiver.Stub() { @Override public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) throws RemoteException { Slogf.i(UserController.TAG,"Finished processing BOOT_COMPLETED for u" + userId); // 标记 AMS 内部状态:BOOT_COMPLETED 已处理完成 // 影响后续开机阶段判断、应用启动策略 mBootCompleted = true; } }, 0, null, null, new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED}, AppOpsManager.OP_NONE, getTemporaryAppAllowlistBroadcastOptions(REASON_BOOT_COMPLETED).toBundle(), true, false, MY_PID, SYSTEM_UID, callingUid, callingPid, userId); }); }
参考文章
AI
《

