android12 systemUI 之锁屏

锁屏初始化入口KeyguardViewMediator

  1. 系统启动 SystemUI :当 Android 系统启动时,SystemUIApplication 会解析配置,并创建一系列系统UI组件(即 SystemUI 的子类)的实例。KeyguardViewMediator 就是其中之一。
  2. 框架回调 start() :在创建了所有 SystemUI 服务实例后,SystemUIApplication 会遍历并调用每个服务的 start() 方法。因此,KeyguardViewMediatorstart() 方法是由其父类 SystemUI 的启动机制调用的,这是一个标准的框架回调流程。
  3. start() 内部初始化 :在 KeyguardViewMediatorstart() 方法内部,会执行一系列初始化操作,例如创建 KeyguardDisplayManager 实例,用于管理锁屏界面的显示。
csharp 复制代码
//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 转发WindowManagerServicesystemReady() 方法会继续调用 PhoneWindowManager.systemReady()
  3. PhoneWindowManager 中转PhoneWindowManager(作为 WindowManagerPolicy 的实现)的 systemReady() 方法,会进一步调用 KeyguardServiceDelegate.onSystemReady()
  4. 跨进程调用KeyguardServiceDelegate 是一个代理,它会通过 KeyguardServiceWrapper ,跨进程调用到 KeyguardService (运行在 SystemUI 进程)的 onSystemReady() 方法
  5. 最终回调KeyguardServiceonSystemReady() 方法内部,最终回调到了 KeyguardViewMediator.onSystemReady()
scss 复制代码
//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 构建视图StatusBarKeyguardViewManagershow() 方法会负责显示完整的锁屏界面(包括 NotificationPanelViewKeyguardBouncer 等)。

scss 复制代码
//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 去执行隐藏锁屏界面的操作。
scss 复制代码
//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();
 }
相关推荐
tianshi48517 小时前
Android 应用启动窗口(Splash Screen)的创建与销毁流程
android
脚踏实地,坚持不懈!7 小时前
ICU Calendar 实际工作问题排查手册
android
ii_best8 小时前
安卓脚本/ios开发软件按键精灵实战:自动定位弹窗广告关闭按钮坐标的通用方案
android·ios·自动化
天空之城--8 小时前
Android Jetpack Compose 状态管理浅析
android·android jetpack
企业数字化笔记12 小时前
固定资产财务账与实物账怎么对账?折旧快照、差异检测与SQL核对
android·数据库·sql
千里马-horse14 小时前
第 66 章:在 Android 上运行 Windows 游戏
android·aosp
云边有个稻草人18 小时前
飞牛 NAS 远程访问实战:星空组网连接 Mac 与安卓,从 Compose 部署到 5G 验证
android·5g·macos
聚美智数18 小时前
手机号归属地-手机号归属地查询-手机归属地-运营商归属地
android·智能手机
恋猫de小郭18 小时前
Shopify 从 React Native 回到 Swift/Kotlin,但是你以为有手就行??
android·前端·ios
菠萝加点糖18 小时前
Android ChipGroup 使用说明
android