android12 systemUI 之锁屏

锁屏初始化入口KeyguardViewMediator

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

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

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

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();
 }
相关推荐
2501_915918413 分钟前
iOS 上架注意事项有哪些?Appuploader 的四个阶段自查清单
android·ios·小程序·https·uni-app·iphone·webview
张小姐的猫44 分钟前
【MySQL】表的约束
android·linux·服务器·数据库·c++·mysql·adb
Kapaseker1 小时前
为什么程序员始终无法彻底解决内存泄漏?
android·kotlin
汤姆宝库1 小时前
推理工程深拆:调度、量化与投机解码
android·开发语言·kotlin
AirDroid_cn1 小时前
隔离风险:用备用机测试不明APP,电脑远程操控安卓保主力机安全
android·安全
恋猫de小郭2 小时前
Flutter 官方表示:AI 时代代码越来越容易写,为什么还要一套代码库?
android·前端·flutter
二宝哥2 小时前
把安卓平板变成电脑第二屏幕(扩展屏):局域网与外网方案全解析
android·电脑·平板·扩展屏
xiaoshiquan120616 小时前
Gradle 复合构建:宿主项目直接依赖 SDK 源码模块的配置实践
android
小师兄吃牛肉19 小时前
Android Studio 2025 专业介绍:新特性、性能与开发体验全面解析
android·ide·android studio
美摄科技19 小时前
安卓离线类美颜特效SDK
android