安卓12开机动画Bootanimation源码分析-结束流程

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.......//发送开机广播
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值