Bootanimation启动后开始运行
首先到frameworks/base/cmds/bootanimation文件夹下:
程序入口文件:bootanimation_main.cpp的main方法
int main()
{
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
bool noBootAnimation = bootAnimationDisabled();
ALOGI_IF(noBootAnimation, "boot animation disabled");
if (!noBootAnimation) {
sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();//启动binder线程池方便跨进程通信
waitForSurfaceFlinger();//等待SurfaceFlinger启动
// create the boot animation object
sp<BootAnimation> boot = new BootAnimation(new AudioAnimationCallbacks());//新建一个BootAnimation对象,它实际是一个线程对象
ALOGV("Boot animation set up. Joining pool.");
IPCThreadState::self()->joinThreadPool();
}
ALOGV("Boot animation exit");
return 0;
}
接下来来到BootAnimation.cpp (mSession属于与SurfaceFlinger通信的Client端对象,通过这个对象来进行对应的Surface创建与申请)
BootAnimation::BootAnimation(sp<Callbacks> callbacks)
: Thread(false), mClockEnabled(true), mTimeIsAccurate(false),
mTimeFormat12Hour(false), mTimeCheckThread(NULL), mCallbacks(callbacks) {
mSession = new SurfaceComposerClient();
.......
}
然后执行
void BootAnimation::onFirstRef() {
status_t err = mSession->linkToComposerDeath(this);
ALOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
if (err == NO_ERROR) {
run("BootAnimation", PRIORITY_DISPLAY);//启动线程进行循环
}
}
在onFirstRef中启动了线程BootAnimation, 第一次执行会运行线程的readyToRun()方法,再执行threadLoop(),所以先看readyToRun:
//启动线程执行前的准备方法
status_t BootAnimation::readyToRun() {
mAssets.addDefaultAssets();
sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain));
DisplayInfo dinfo;
status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);//获取对应的屏幕信息
if (status)
return -1;
// create the native surface
sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
SurfaceComposerClient::openGlobalTransaction();
control->setLayer(0x40000000);
SurfaceComposerClient::closeGlobalTransaction();
sp<Surface> s = control->getSurface();
...
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, 0, 0);
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
surface = eglCreateWindowSurface(display, config, s.get(), NULL);//获取对应的Surface来进行绘制
context = eglCreateContext(display, config, NULL, NULL);
eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h);
.....
for (const char* f : (!mShuttingDown ? bootFiles : shutdownFiles)) {
if (access(f, R_OK) == 0) {
mZipFileName = f;//如果存在,获取对应开机动画制作的Zip信息
return NO_ERROR;
}
}
return NO_ERROR;
}
然后播放开机动画
//进入线程执行端
bool BootAnimation::threadLoop()
{
if (mZipFileName.isEmpty()) {
r = android();//如果不存在zip的动画,则播发默认的android闪光动画
} else {
r = movie();//执行解析zip动画,播发zip动画
}
....
}
开机动画结束流程:
FallbackHome进入Idle(主线程空闲状态)会调用activityIdle方法
/frameworks/base/core/java/android/app/ActivityClient.java
/** Reports the main thread is idle after the activity is resumed. */
public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
try {
getActivityClientController().activityIdle(token, config, stopProfiling);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
/frameworks/base/services/core/java/com/android/server/wm/ActivityClientController.java
public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityIdle");
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r == null) {
return;
}
mTaskSupervisor.activityIdleInternal(r, false /* fromTimeout */,
false /* processPausingActivities */, config);
if (stopProfiling && r.hasProcess()) {
r.app.clearProfilerIfNeeded();
}
}
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
Binder.restoreCallingIdentity(origId);
}
}
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
activityIdleInternal方法里面执行了checkFinishBootingLocked()方法
/**
* Called when all resumed tasks/root-tasks are idle.
* @return the state of mService.mAm.mBooting before this was called.
*/
@GuardedBy("mService")
private boolean checkFinishBootingLocked() {
final boolean booting = mService.isBooting();
boolean enableScreen = false;
mService.setBooting(false);
if (!mService.isBooted()) {
mService.setBooted(true);
enableScreen = true;
}
if (booting || enableScreen) {
mService.postFinishBooting(booting, enableScreen);
}
return booting;
}
这里调用了ATMS的postFinishBooting方法
void postFinishBooting(boolean finishBooting, boolean enableScreen) {
mH.post(() -> {
if (finishBooting) {
mAmInternal.finishBooting();
}
if (enableScreen) {
mInternal.enableScreenAfterBoot(isBooted());
}
});
}
ATMS里面的enableScreenAfterBoot方法调用了WMS的enableScreenAfterBoot()方法
@Override
public void enableScreenAfterBoot(boolean booted) {
writeBootProgressEnableScreen(SystemClock.uptimeMillis());
mWindowManager.enableScreenAfterBoot();
synchronized (mGlobalLock) {
updateEventDispatchingLocked(booted);
}
}
WMS里面的enableScreenAfterBoot方法调用了performEnableScreen()
performEnableScreen方法里面调用了SystemProperties.set(“service.bootanim.exit”, “1”);方法设置属性值来结束开机动画。然后调用了checkBootAnimationCompleteLocked方法
if (!mBootAnimationStopped) {
Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
SystemProperties.set("service.bootanim.exit", "1");
mBootAnimationStopped = true;
}
......
if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) {
ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: Waiting for anim complete");
return;
}
private boolean checkBootAnimationCompleteLocked() {
if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) {
mH.removeMessages(H.CHECK_IF_BOOT_ANIMATION_FINISHED);
mH.sendEmptyMessageDelayed(H.CHECK_IF_BOOT_ANIMATION_FINISHED,
BOOT_ANIMATION_POLL_INTERVAL);
ProtoLog.i(WM_DEBUG_BOOT, "checkBootAnimationComplete: Waiting for anim complete");
return false;
}
ProtoLog.i(WM_DEBUG_BOOT, "checkBootAnimationComplete: Animation complete!");
return true;
}
case CHECK_IF_BOOT_ANIMATION_FINISHED: {
final boolean bootAnimationComplete;
synchronized (mGlobalLock) {
ProtoLog.i(WM_DEBUG_BOOT, "CHECK_IF_BOOT_ANIMATION_FINISHED:");
bootAnimationComplete = checkBootAnimationCompleteLocked();
}
if (bootAnimationComplete) {
performEnableScreen();
}
break;
}
这里会不断循环执行checkBootAnimationCompleteLocked方法,如果是false,performEnableScreen方法会直接return…直到返回true,然后再次执行 performEnableScreen()方法,并且不会中途return
private void performEnableScreen() {
...
// stop boot animation
// formerly we would just kill the process, but we now ask it to exit so it
// can choose where to stop the animation.
SystemProperties.set("service.bootanim.exit", "1");
mBootAnimationStopped = true;
......
IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
if (surfaceFlinger != null) {
ProtoLog.i(WM_ERROR, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
data, null, 0);
data.recycle();
}
} catch (RemoteException ex) {
ProtoLog.e(WM_ERROR, "Boot completed: SurfaceFlinger is dead!");
}
}
......
mActivityManager.bootAnimationComplete();
该方法主要是结束开机动画,并且告诉AMS可以发送开机广播了。
这里跨进程通信,调用SurfaceFlinger.cpp里面的方法,将service.bootanim.exit属性设为1。(实际上前面的SystemProperties.set(“service.bootanim.exit”, “1”);已经让开机动画退出了。这里重复设置了。)
frameworks/ base/services/core/java/com/android/server/wm/WindowManagerService.java
enableScreenAfterBoot() ->
performEnableScreen() ->
surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0); ->
frameworks/native/ services/surfaceflinger/SurfaceFlinger.cpp
bootFinished() ->
property_set("service.bootanim.exit", "1"); //将该属性设为1,开机动画退出。
然后我们来看mActivityManager.bootAnimationComplete();
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public void bootAnimationComplete() {
final boolean callFinishBooting;
synchronized (this) {
callFinishBooting = mCallFinishBooting;
mBootAnimationComplete = true;
}
if (callFinishBooting) {
finishBooting();
}
}
然后调用finishBooting()方法。
final void finishBooting() {
TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
Trace.TRACE_TAG_ACTIVITY_MANAGER);
t.traceBegin("FinishBooting");
synchronized (this) {
if (!mBootAnimationComplete) {
mCallFinishBooting = true;
return;
}
mCallFinishBooting = false;
}
// Let the ART runtime in zygote and system_server know that the boot completed.
ZYGOTE_PROCESS.bootCompleted();
VMRuntime.bootCompleted();
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) {
if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
0, "query restart")) {
setResultCode(Activity.RESULT_OK);
return;
}
}
}
}
}
}, pkgFilter);
// Inform checkpointing systems of success
try {
// This line is needed to CTS test for the correct exception handling
// See b/138952436#comment36 for context
Slog.i(TAG, "About to commit checkpoint");
IStorageManager storageManager = PackageHelper.getStorageManager();
storageManager.commitChanges();
} catch (Exception e) {
PowerManager pm = (PowerManager)
mInjector.getContext().getSystemService(Context.POWER_SERVICE);
pm.reboot("Checkpoint commit failed");
}
// Let system services know.
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_BOOT_COMPLETED);
synchronized (this) {
// Ensure that any processes we had put on hold are now started
// up.
final int NP = mProcessesOnHold.size();
if (NP > 0) {
ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(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("on-hold"),
ZYGOTE_POLICY_FLAG_BATCH_LAUNCH);
}
}
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
return;
}
// Start looking for apps that are abusing wake locks.
Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
// Check if we are performing userspace reboot before setting sys.boot_completed to
// avoid race with init reseting sys.init.userspace_reboot.in_progress once sys
// .boot_completed is 1.
if (InitProperties.userspace_reboot_in_progress().orElse(false)) {
UserspaceRebootLogger.noteUserspaceRebootSuccess();
}
// Tell anyone interested that we are done booting!
SystemProperties.set("sys.boot_completed", "1");
// And trigger dev.bootcomplete if we are not showing encryption progress
if (!"trigger_restart_min_framework".equals(VoldProperties.decrypt().orElse(""))
|| "".equals(VoldProperties.encrypt_progress().orElse(""))) {
SystemProperties.set("dev.bootcomplete", "1");
}
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) {
mAppProfiler.requestPssAllProcsLPr(
SystemClock.uptimeMillis(), true, false);
}
}
});
maybeLogUserspaceRebootEvent();
mUserController.scheduleStartProfiles();
}
// UART is on if init's console service is running, send a warning notification.
showConsoleNotificationIfActive();
t.traceEnd();
}
接下来看UserController.sendBootCompleted:
void sendBootCompleted(IIntentReceiver resultTo) {
// Get a copy of mStartedUsers to use outside of lock
SparseArray<UserState> startedUsers;
synchronized (mLock) {
startedUsers = mStartedUsers.clone();
}
for (int i = 0; i < startedUsers.size(); i++) {
UserState uss = startedUsers.valueAt(i);
if (!UserManager.isHeadlessSystemUserMode()) {
finishUserBoot(uss, resultTo);
} else if (uss.mHandle.isSystem()) {
// In case of headless system user mode, send only locked boot complete broadcast
// for system user since finishUserBoot call will be made using other code path;
// for non-system user, do nothing since finishUserBoot will be called elsewhere.
sendLockedBootCompletedBroadcast(resultTo, uss.mHandle.getIdentifier());
return;
}
}
}
用户未解锁时执行sendLockedBootCompletedBroadcast(resultTo, uss.mHandle.getIdentifier());方法
发送Intent.ACTION_LOCKED_BOOT_COMPLETED广播
private void sendLockedBootCompletedBroadcast(IIntentReceiver receiver, @UserIdInt int userId) {
final Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
| Intent.FLAG_RECEIVER_OFFLOAD
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
mInjector.broadcastIntent(intent, null, receiver, 0, null, null,
new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
AppOpsManager.OP_NONE,
getTemporaryAppAllowlistBroadcastOptions(REASON_LOCKED_BOOT_COMPLETED)
.toBundle(), true,
false, MY_PID, SYSTEM_UID,
Binder.getCallingUid(), Binder.getCallingPid(), userId);
}
用户解锁后执行finishUserBoot(uss, resultTo);方法
发送Intent.ACTION_BOOT_COMPLETED广播
private void finishUserBoot(UserState uss, IIntentReceiver resultTo) {
final int userId = uss.mHandle.getIdentifier();
EventLog.writeEvent(EventLogTags.UC_FINISH_USER_BOOT, userId);
synchronized (mLock) {
// Bail if we ended up with a stale user
if (mStartedUsers.get(userId) != uss) {
return;
}
}
// We always walk through all the user lifecycle states to send
// consistent developer events. We step into RUNNING_LOCKED here,
// but we might immediately step into RUNNING below if the user
// storage is already unlocked.
if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) {
logUserLifecycleEvent(userId, USER_LIFECYCLE_EVENT_USER_RUNNING_LOCKED,
USER_LIFECYCLE_EVENT_STATE_NONE);
mInjector.getUserManagerInternal().setUserState(userId, uss.state);
// Do not report secondary users, runtime restarts or first boot/upgrade
if (userId == UserHandle.USER_SYSTEM
&& !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
final long elapsedTimeMs = SystemClock.elapsedRealtime();
FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__FRAMEWORK_LOCKED_BOOT_COMPLETED,
elapsedTimeMs);
final long maxElapsedTimeMs = 120_000;
if (elapsedTimeMs > maxElapsedTimeMs) {
Slogf.wtf("SystemServerTiming",
"finishUserBoot took too long. elapsedTimeMs=" + elapsedTimeMs);
}
}
if (!mInjector.getUserManager().isPreCreated(userId)) {
mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
userId, 0));
// In case of headless system user mode, do not send boot complete broadcast for
// system user as it is sent by sendBootCompleted call.
if (!(UserManager.isHeadlessSystemUserMode() && uss.mHandle.isSystem())) {
// ACTION_LOCKED_BOOT_COMPLETED
sendLockedBootCompletedBroadcast(resultTo, userId);
}
}
}
// We need to delay unlocking managed profiles until the parent user
// is also unlocked.
if (mInjector.getUserManager().isProfile(userId)) {
final UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
if (parent != null
&& isUserRunning(parent.id, ActivityManager.FLAG_AND_UNLOCKED)) {
Slogf.d(TAG, "User " + userId + " (parent " + parent.id
+ "): attempting unlock because parent is unlocked");
maybeUnlockUser(userId);
} else {
String parentId = (parent == null) ? "<null>" : String.valueOf(parent.id);
Slogf.d(TAG, "User " + userId + " (parent " + parentId
+ "): delaying unlock because parent is locked");
}
} else {
maybeUnlockUser(userId);
}
}
这里我们看maybeUnlockUser(userId);方法
/**
* Attempt to unlock user without a credential token. This typically
* succeeds when the device doesn't have credential-encrypted storage, or
* when the credential-encrypted storage isn't tied to a user-provided
* PIN or pattern.
*/
private boolean maybeUnlockUser(final @UserIdInt int userId) {
// Try unlocking storage using empty token
return unlockUserCleared(userId, null, null, null);
}
然后看unlockUserCleared(userId, null, null, null);方法
private boolean unlockUserCleared(final @UserIdInt int userId, byte[] token, byte[] secret,
IProgressListener listener) {
UserState uss;
if (!StorageManager.isUserKeyUnlocked(userId)) {
final UserInfo userInfo = getUserInfo(userId);
final IStorageManager storageManager = mInjector.getStorageManager();
try {
// We always want to unlock user storage, even user is not started yet
storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
} catch (RemoteException | RuntimeException e) {
Slogf.w(TAG, "Failed to unlock: " + e.getMessage());
}
}
synchronized (mLock) {
// Register the given listener to watch for unlock progress
uss = mStartedUsers.get(userId);
if (uss != null) {
uss.mUnlockProgress.addListener(listener);
uss.tokenProvided = (token != null);
}
}
// Bail if user isn't actually running
if (uss == null) {
notifyFinished(userId, listener);
return false;
}
if (!finishUserUnlocking(uss)) {
notifyFinished(userId, listener);
return false;
}
// We just unlocked a user, so let's now attempt to unlock any
// managed profiles under that user.
// First, get list of userIds. Requires mLock, so we cannot make external calls, e.g. to UMS
int[] userIds;
synchronized (mLock) {
userIds = new int[mStartedUsers.size()];
for (int i = 0; i < userIds.length; i++) {
userIds[i] = mStartedUsers.keyAt(i);
}
}
for (int testUserId : userIds) {
final UserInfo parent = mInjector.getUserManager().getProfileParent(testUserId);
if (parent != null && parent.id == userId && testUserId != userId) {
Slogf.d(TAG, "User " + testUserId + " (parent " + parent.id
+ "): attempting unlock because parent was just unlocked");
maybeUnlockUser(testUserId);
}
}
return true;
}
主要看里面的finishUserUnlocking方法:
/**
* Step from {@link UserState#STATE_RUNNING_LOCKED} to
* {@link UserState#STATE_RUNNING_UNLOCKING}.
*/
private boolean finishUserUnlocking(final UserState uss) {
final int userId = uss.mHandle.getIdentifier();
EventLog.writeEvent(EventLogTags.UC_FINISH_USER_UNLOCKING, userId);
logUserLifecycleEvent(userId, USER_LIFECYCLE_EVENT_UNLOCKING_USER,
USER_LIFECYCLE_EVENT_STATE_BEGIN);
// Only keep marching forward if user is actually unlocked
if (!StorageManager.isUserKeyUnlocked(userId)) return false;
synchronized (mLock) {
// Do not proceed if unexpected state or a stale user
if (mStartedUsers.get(userId) != uss || uss.state != STATE_RUNNING_LOCKED) {
return false;
}
}
uss.mUnlockProgress.start();
// Prepare app storage before we go any further
uss.mUnlockProgress.setProgress(5,
mInjector.getContext().getString(R.string.android_start_title));
// Call onBeforeUnlockUser on a worker thread that allows disk I/O
FgThread.getHandler().post(() -> {
if (!StorageManager.isUserKeyUnlocked(userId)) {
Slogf.w(TAG, "User key got locked unexpectedly, leaving user locked.");
return;
}
mInjector.getUserManager().onBeforeUnlockUser(userId);
synchronized (mLock) {
// Do not proceed if unexpected state
if (!uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
return;
}
}
mInjector.getUserManagerInternal().setUserState(userId, uss.state);
uss.mUnlockProgress.setProgress(20);
// Dispatch unlocked to system services; when fully dispatched,
// that calls through to the next "unlocked" phase
mHandler.obtainMessage(USER_UNLOCK_MSG, userId, 0, uss).sendToTarget();
});
return true;
}
可以看到mHandler.obtainMessage(USER_UNLOCK_MSG, userId, 0, uss).sendToTarget();
然后搜索USER_UNLOCK_MSG
case USER_UNLOCK_MSG:
final int userId = msg.arg1;
mInjector.getSystemServiceManager().onUserUnlocking(userId);
// Loads recents on a worker thread that allows disk I/O
FgThread.getHandler().post(() -> {
mInjector.loadUserRecents(userId);
});
logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_UNLOCKING_USER,
USER_LIFECYCLE_EVENT_STATE_FINISH);
logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_UNLOCKED_USER,
USER_LIFECYCLE_EVENT_STATE_BEGIN);
finishUserUnlocked((UserState) msg.obj);
break;
然后查看里面的 finishUserUnlocked((UserState) msg.obj); 方法
/**
* Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
* {@link UserState#STATE_RUNNING_UNLOCKED}.
*/
void finishUserUnlocked(final UserState uss) {
final int userId = uss.mHandle.getIdentifier();
EventLog.writeEvent(EventLogTags.UC_FINISH_USER_UNLOCKED, userId);
// Only keep marching forward if user is actually unlocked
if (!StorageManager.isUserKeyUnlocked(userId)) return;
synchronized (mLock) {
// Bail if we ended up with a stale user
if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
// Do not proceed if unexpected state
if (!uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
return;
}
}
mInjector.getUserManagerInternal().setUserState(userId, uss.state);
uss.mUnlockProgress.finish();
// Get unaware persistent apps running and start any unaware providers
// in already-running apps that are partially aware
if (userId == UserHandle.USER_SYSTEM) {
mInjector.startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
}
mInjector.installEncryptionUnawareProviders(userId);
if (!mInjector.getUserManager().isPreCreated(userId)) {
// Dispatch unlocked to external apps
final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
unlockedIntent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
mInjector.broadcastIntent(unlockedIntent, null, null, 0, null,
null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
Binder.getCallingUid(), Binder.getCallingPid(), userId);
}
final UserInfo userInfo = getUserInfo(userId);
if (userInfo.isProfile()) {
UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
if (parent != null) {
// Send PROFILE_ACCESSIBLE broadcast to the parent user if a profile was unlocked
broadcastProfileAccessibleStateChanged(userId, parent.id,
Intent.ACTION_PROFILE_ACCESSIBLE);
//TODO(b/175704931): send ACTION_MANAGED_PROFILE_AVAILABLE
// Also send MANAGED_PROFILE_UNLOCKED broadcast to the parent user
// if a managed profile was unlocked
if (userInfo.isManagedProfile()) {
final Intent profileUnlockedIntent = new Intent(
Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
profileUnlockedIntent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_FOREGROUND);
mInjector.broadcastIntent(profileUnlockedIntent,
null, null, 0, null, null, null, AppOpsManager.OP_NONE,
null, false, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
Binder.getCallingPid(), parent.id);
}
}
}
// Send PRE_BOOT broadcasts if user fingerprint changed; we
// purposefully block sending BOOT_COMPLETED until after all
// PRE_BOOT receivers are finished to avoid ANR'ing apps
final UserInfo info = getUserInfo(userId);
if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)
|| SystemProperties.getBoolean("persist.pm.mock-upgrade", false)) {
// Suppress double notifications for managed profiles that
// were unlocked automatically as part of their parent user
// being unlocked.
final boolean quiet;
if (info.isManagedProfile()) {
quiet = !uss.tokenProvided
|| !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
} else {
quiet = false;
}
mInjector.sendPreBootBroadcast(userId, quiet,
() -> finishUserUnlockedCompleted(uss));
} else {
finishUserUnlockedCompleted(uss);
}
}
找到了里面的关键方法finishUserUnlockedCompleted(uss);
所以最后的开机广播发送位置:
/frameworks/base/services/core/java/com/android/server/am/UserController.java#finishUserUnlockedCompleted()
private void finishUserUnlockedCompleted(UserState uss) {
......
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);
mInjector.broadcastIntent(bootIntent.......//发送开机广播
}