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();
 }
相关推荐
圆山猫2 小时前
[Virtualization](三):RISC-V H-extension 与 Guest 执行模式
android·java·risc-v
爱笑鱼2 小时前
Binder(七):getCallingUid() 读到的是谁?clearCallingIdentity() 又清掉了什么?
android
2501_915909068 小时前
iOS 应用反调试技详解术 检测调试器的原理与防护实践
android·ios·小程序·https·uni-app·iphone·webview
Lvan的前端笔记8 小时前
AndroidX 完全入门指南
android·androidx
帅次9 小时前
Android 应用高级面试:Window 近1年高频追问 18 题
android·面试·职场和发展
总捣什么乱19 小时前
MySQL MySQL是怎么保证主备一致的?
android·mysql·adb
zzm6289 小时前
精读 HinDroid:基于异构信息网络的安卓恶意软件检测
android
weixin_4407841110 小时前
Android基础知识汇总
android·java·android studio
sbjdhjd10 小时前
安全初级 | Upload 文件上传漏洞实操
android·经验分享·安全·网络安全·开源·php·apache