android12 SystemUI之锁屏

30 阅读4分钟

锁屏初始化入口KeyguardViewMediator

  1. 系统启动 SystemUI:当 Android 系统启动时,SystemUIApplication 会解析配置,并创建一系列系统UI组件(即 SystemUI 的子类)的实例。KeyguardViewMediator 就是其中之一。
  2. 框架回调 start() :在创建了所有 SystemUI 服务实例后,SystemUIApplication 会遍历并调用每个服务的 start()  方法。因此,KeyguardViewMediator 的 start() 方法是由其父类 SystemUI 的启动机制调用的,这是一个标准的框架回调流程。
  3. start() 内部初始化:在 KeyguardViewMediator 的 start() 方法内部,会执行一系列初始化操作,例如创建 KeyguardDisplayManager 实例,用于管理锁屏界面的显示。
//frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java

public void start() {

         synchronized (this) {
             //初始化
             setupLocked();
         }
}
  


 

锁屏页面显示流程

阶段一:系统启动 & 服务初始化

  1. SystemServer 启动:系统启动时,SystemServer 进程在 startOtherServices() 方法中启动各种核心服务,其中就包括调用 WindowManagerService.systemReady()
  2. WindowManagerService 转发WindowManagerService 的 systemReady() 方法会继续调用 PhoneWindowManager.systemReady()
  3. PhoneWindowManager 中转PhoneWindowManager(作为 WindowManagerPolicy 的实现)的 systemReady() 方法,会进一步调用 KeyguardServiceDelegate.onSystemReady()
  4. 跨进程调用KeyguardServiceDelegate 是一个代理,它会通过 KeyguardServiceWrapper,跨进程调用到 KeyguardService(运行在 SystemUI 进程)的 onSystemReady() 方法
  5. 最终回调KeyguardService 的 onSystemReady() 方法内部,最终回调到了 KeyguardViewMediator.onSystemReady()
//frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public void systemReady() {
          mSystemReady = true;
          //WindowManagerPolicy mPolicy的实现类是PhoneWindowManager 
          mPolicy.systemReady();
          mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);
          mTaskSnapshotController.systemReady();
          ...
              }
          }
 }


//frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
public void systemReady() {
          // In normal flow, systemReady is called before other system services are ready.
          // So it is better not to bind keyguard here.
          //代理类KeyguardServiceWrapper
          mKeyguardDelegate.onSystemReady();
          ...
          updateUiMode();
          mDefaultDisplayRotation.updateOrientationListener();
          synchronized (mLock) {
              mSystemReady = true;
              mHandler.post(new Runnable() {
                  @Override
                  public void run() {
                      updateSettings();
                  }
              });
              // If this happens, for whatever reason, systemReady came later than systemBooted.
              // And keyguard should be already bound from systemBooted
              if (mSystemBooted) {
                  mKeyguardDelegate.onBootCompleted();
              }
          }
  
          ...
      }



//frameworks/base/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
public void onSystemReady() {
          try {
          //IKeyguardService mService 
              mService.onSystemReady();
          } catch (RemoteException e) {
              Slog.w(TAG , "Remote Exception", e);
          }
      }


//frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
public void onSystemReady() {
              ...
              //KeyguardViewMediator mKeyguardViewMediator
              mKeyguardViewMediator.onSystemReady();
              ...
 }

阶段二:视图创建与显示

这个阶段由 KeyguardViewMediator 发起,但视图的创建和显示工作被委托给了其他组件。

  1. KeyguardViewMediator.doKeyguardLocked() :此方法会进行一系列检查,例如锁屏功能是否启用 (config_enableKeyguard)、是否被其它策略禁用等。如果所有条件满足,它会调用 showLocked() 等方法

  2. 通知 StatusBarKeyguardViewMediator 通过内部回调机制,去显示锁屏。

  3. StatusBar 调用 KeyguardViewControllerStatusBar 作为顶层的控制器,会调用 KeyguardViewController 接口的 show(...) 方法。

    • 关键点KeyguardViewController 是一个接口,其实现类是 StatusBarKeyguardViewManager。但 KeyguardViewMediator 不再直接持有它,而是由 StatusBar 来管理这个实例。
  4. KeyguardViewController 构建视图StatusBarKeyguardViewManager 的 show() 方法会负责显示完整的锁屏界面(包括 NotificationPanelViewKeyguardBouncer 等)。

//frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
 public void onSystemReady() {
          mHandler.obtainMessage(SYSTEM_READY).sendToTarget();
      }
  
private void handleSystemReady() {
          synchronized (this) {
              if (DEBUG) Log.d(TAG, "onSystemReady");
              mSystemReady = true;
              //主要调用方法
              doKeyguardLocked(null);
              ...
          }
          ...
 }


 private void doKeyguardLocked(Bundle options) {
         
         ...
  
          //如果已经显示直接返回
          if (mShowing && mKeyguardViewControllerLazy.get().isShowing()) {
              if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
              resetStateLocked();
              return;
          }
  
          ...
          //显示锁屏
          showLocked(options);
   }
   
   
  
private void showLocked(Bundle options) {
         
         //发消息到消息队列
          Message msg = mHandler.obtainMessage(SHOW, options);
          mHandler.sendMessage(msg);
         
      }




 private void handleShow(Bundle options) {
          ...
          synchronized (KeyguardViewMediator.this) {
              if (!mSystemReady) {
              //如果系统还没准备好直接返回
                  if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready.");
                  return;
              } else {
                  if (DEBUG) Log.d(TAG, "handleShow");
              }
  
              mHiding = false;
              mKeyguardExitAnimationRunner = null;
              mWakeAndUnlocking = false;
              mPendingLock = false;
              setShowingLocked(true);
              //调用KeyguardViewController的实现类StatusBarKeyguardViewManager
              mKeyguardViewControllerLazy.get().show(options);
              resetKeyguardDonePendingLocked();
              mHideAnimationRun = false;
              adjustStatusBarLocked();
              userActivity();
              mUpdateMonitor.setKeyguardGoingAway(false);
              mKeyguardViewControllerLazy.get().setKeyguardGoingAwayState(false);
              mShowKeyguardWakeLock.release();
          }
          mKeyguardDisplayManager.show();
  
          ...
 }


//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
 /**
       * Show the keyguard.  Will handle creating and attaching to the view manager
       * lazily.
       */
      @Override
      public void show(Bundle options) {
          mShowing = true;
         
          //通知栏锁屏状态更新
          mNotificationShadeWindowController.setKeyguardShowing(true);
          mKeyguardStateController.notifyKeyguardState(mShowing,
                  mKeyguardStateController.isOccluded());
          reset(true /* hideBouncerWhenShowing */);
          ...
      }
      
      
public void reset(boolean hideBouncerWhenShowing) {
          if (mShowing) {
              // Hide quick settings.
              mNotificationPanelViewController.resetViews(/* animate= */ true);
              // Hide bouncer and quick-quick settings.
              if (mOccluded && !mDozing) {
                  mStatusBar.hideKeyguard();
                  if (hideBouncerWhenShowing || mBouncer.needsFullscreenBouncer()) {
                      hideBouncer(false /* destroyView */);
                  }
              } else {
                  //
                  showBouncerOrKeyguard(hideBouncerWhenShowing);
              }
              ...
          }
  }

阶段三:普通锁屏页面与安全锁屏页面交互

  1. KeyguardBouncer 处理验证:如果用户设置了安全锁(PIN、图案、密码等),具体的验证逻辑由 KeyguardBouncer 组件处理。它负责显示相应的输入界面并校验用户输入。
  2. 通知 KeyguardViewMediator:验证成功后,KeyguardBouncer 会通过回调通知 KeyguardViewMediator 解锁成功(例如调用 keyguardDone() 等方法)。
  3. KeyguardViewMediator 处理善后KeyguardViewMediator 执行解锁后的系统级操作,如播放声音、通知 PowerManagerService 等。
  4. 隐藏锁屏视图:最后,KeyguardViewMediator 会通知 StatusBar,再由 StatusBar 通过 KeyguardViewController 去执行隐藏锁屏界面的操作。
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java

protected void showBouncerOrKeyguard(boolean hideBouncerWhenShowing) {
          if (mBouncer.needsFullscreenBouncer() && !mDozing) {
     
             //通知状态栏隐藏普通锁屏界面
             mStatusBar.hideKeyguard();
             //显示锁屏安全页面
              mBouncer.show(true /* resetSecuritySelection */);
          } else {
            //通知状态栏显示普通锁屏界面
              mStatusBar.showKeyguard();
              if (hideBouncerWhenShowing) {
              ////隐藏锁屏安全页面
                  hideBouncer(shouldDestroyViewOnReset() /* destroyView */);
                  mBouncer.prepare();
              }
          }
          updateStates();
 }