现在的位置: 首页 > 综合 > 正文

Android4.0 Keyguard解锁屏机制

2014年02月02日 ⁄ 综合 ⁄ 共 5936字 ⁄ 字号 评论关闭

      Keyguard解锁屏是Android系统中必不可少的模块,用户在开机后或者在点击Power按钮屏幕变亮后首先看到的画面即为解锁屏模块对应的界面。Keyguard模块功能相对简单:
      第一:直观地显示手机当前的关键信息:比如电池信息、运营商信息、日期信息以及通话短信信息等。
      第二:增强手机的安全性能:为了安全,用户可以在Setting里的Secure选项中设置password、pattern、account等不同的安全策略,防止非法用户访问手机系统。
      但从代码实现的角度该模块逻辑还是比较复杂,不但需要监听系统中的多种event,比如sim、电话、电池以及Carrier等状态,还要正确反映、显示屏幕的不同状态。为了对Keyguard模块的处理逻辑有更清晰的理解,下面首先从系统构成的角度概括介绍Keyguard解锁屏模块的框架,然后对解锁屏模块中重要的处理逻辑进行详细介绍。
一、系统介绍

      Keyguard解锁屏模块的框架类图如下:

      图中仅列出了Keyguard解锁屏模块涉及的重要类,这些类实现了Keyguard模块的主要功能,它们的作用如下:
      PhoneWindowManager是解锁屏模块对外交互的接口,窗口管理Service、电源管理Service等外部模块都是通过PhoneWindowManager访问Keyguard内部功能。
      KeyguardViewMediator类为解锁屏模块的中介者,以中介的身份处理keyguard状态变化,处理event、power管理、PhoneWindowManager通知等请求,并作为回调对象供解锁屏模块的其它类回调。
      KeyguardUpdateMonitor类为解锁屏模块的监听者,它负责监听时间、sim卡、运营商信息、电池信息、电话信息等状态的变化,并通知keyguard View模块更新显示。
      KeyguardViewManager类为解锁屏view模块的管理者,管理解锁屏界面的创建、显示、隐藏以及重置等。
      LockPatternKeyguardView类为解锁屏模块的View界面,为所有解锁屏界面的host view。根据设置的安全策略,显示不同的解锁屏界面。Google原生代码中实现了6种解锁屏界面:
     1) LockScreen:用于显示屏幕加锁状态
     2) PatternUnlockScreen:实现图案解锁模式
     3) SimPukUnlockScreen:屏幕实现SIM PUK码解锁模式
     4) SimUnlockScreen:实现Sim PIN码解锁模式
     5) AccountUnlockScreen:实现 GOOGLE 帐户解锁
     6) PasswordUnlockScreen:实现自定义密码解锁模式
二、主要逻辑
1、Keyguard模块启动、显示逻辑

     即手机开机进入系统到锁屏界面显示的过程。手机系统启动过程中会自动启动Keyguard解锁屏模块,该模块的创建始于WindowManagerService类,时序图如下:

     1)WindowManagerService在启动时会实例化PhoneWindowManager对象mPolicy,并在窗口管理Policy线程PolicyThread中初始化,代码如下:

  1. public void run() {  
  2.     Looper.prepare();  
  3.     WindowManagerPolicyThread.set(this, Looper.myLooper());  
  4.     ......  
  5.     mPolicy.init(mContext, mService, mService, mPM);  
  6.     ......  
  7.     Looper.loop();  
  8. }  

     从代码中可以看到PhoneWindowManager在独立的线程和Looper消息队列中处理Message事件,该Looper对象也为解锁屏模块使用以处理所有handler消息。
    2)mPolicy函数init中创建解锁屏模块的中介者——KeyguardViewMediator对象。
    3)在KeyguardViewMediator的构造函数中创建LockPatternKeyguardViewProperties、KeyguardUpdateMonitor、KeyguardViewManager等重要对象:

  1. public KeyguardViewMediator(Context context, PhoneWindowManager callback,  
  2.             LocalPowerManager powerManager) {  
  3.         ……  
  4.         mUpdateMonitor = new KeyguardUpdateMonitor(context);  
  5.         mUpdateMonitor.registerInfoCallback(this);  
  6.         mUpdateMonitor.registerSimStateCallback(this);  
  7.         mLockPatternUtils = new LockPatternUtils(mContext);  
  8.         mKeyguardViewProperties  
  9. new LockPatternKeyguardViewProperties(mLockPatternUtils, mUpdateMonitor);  
  10.         mKeyguardViewManager = new KeyguardViewManager(  
  11.                 context, WindowManagerImpl.getDefault(), this,  
  12.                 mKeyguardViewProperties, mUpdateMonitor);  
  13.        ……  
  14.  }  

     KeyguardViewMediator中记录了PhoneWindowManager、PowerManager等对象,同时也保存了LockPatternKeyguardViewProperties、KeyguardUpdateMonitor、KeyguardViewManager等模块内的重要对象,这样该类以中介者身份在Keyguard模块对外交互以及内部各对象间的交互中发挥了重要作用。
     4)KeyguardUpdateMonitor构造函数中创建mHandler,用以响应处理该类监听的各事件状态的改变,并在handle处理函数中通知mInfoCallbacks和mSimStateCallbacks保存的监听对象,监听事件有ACTION_TIME_TICK、ACTION_TIME_CHANGED、ACTION_BATTERY_CHANGED、ACTION_TIMEZONE_CHANGED、ACTION_SIM_STATE_CHANGED、       
ACTION_PHONE_STATE_CHANGED、RINGER_MODE_CHANGED_ACTION

    至此Keyguard解锁屏模块中重要的类对象已经实例化,但是还未涉及解锁屏View界面的创建和显示。
    5)系统启动后解锁屏界面的首次显示始于WindowManagerService的systemReady函数,通知PhoneWindowManager系统就绪,代码如下:

  1. public void systemReady() {  
  2.     mPolicy.systemReady();  
  3. }  

    6)PhoneWindowManager的systemReady函数中通知解锁屏模块的中介者KeyguardViewMediator对象系统就绪
    7)中介者KeyguardViewMediator类中处理系统就绪情形:调用doKeyguardLocked函数显示解锁屏界面:

  1. public void onSystemReady() {  
  2.     synchronized (this) {  
  3.          mSystemReady = true;  
  4.          doKeyguardLocked();  
  5.     }  
  6. }  
  7. private void doKeyguardLocked() {  
  8.         ......  
  9.         // if the keyguard is already showing, don't bother  
  10.         if (mKeyguardViewManager.isShowing()) {  
  11.             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");  
  12.             return;  
  13.         }  
  14.   
  15.         .....  
  16.         if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");  
  17.         showLocked();  
  18. }  

    showLocked函数中发送SHOW消息异步处理解锁屏界面显示的请求。
    8)handleShow中处理界面显示的消息请求,函数中调用KeyguardViewManager的函数show实现解锁屏界面的真正显示:

  1. public synchronized void show() {  
  2.         ......  
  3.         if (mKeyguardHost == null) {  
  4.             if (DEBUG) Log.d(TAG, "keyguard host is null, creating it...");  
  5.   
  6.             mKeyguardHost = new KeyguardViewHost(mContext, mCallback);  
  7.             ......  
  8.             mViewManager.addView(mKeyguardHost, lp);  
  9.         }  
  10.         ......  
  11.         mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);  
  12.   
  13.         if (mKeyguardView == null) {  
  14.             mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);  
  15.             ......  
  16.             mKeyguardHost.addView(mKeyguardView, lp);  
  17.             ......  
  18.         }  
  19.         ......  
  20. }  

    该函数中主要创建了Keyguard显示View中的两个重要的对象:mKeyguardHost和mKeyguardView,它们都是继承于FrameLayout,为解锁屏视图的根view。
     9)在创建对象mKeyguardView时根据解锁屏mode创建解锁屏界面:

  1. protected void updateScreen(Mode mode, boolean force) {  
  2.          ......  
  3.         // Re-create the lock screen if necessary  
  4.         if (mode == Mode.LockScreen || mShowLockBeforeUnlock) {  
  5.             if (force || mLockScreen == null) {  
  6.                 recreateLockScreen();  
  7.             }  
  8.         }  
  9.   
  10.         // Re-create the unlock screen if necessary. This is primarily required to properly handle  
  11.         // SIM state changes. This typically happens when this method is called by reset()  
  12.         if (mode == Mode.UnlockScreen) {  
  13.             final UnlockMode unlockMode = getUnlockMode();  
  14.             if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {  
  15.                 recreateUnlockScreen(unlockMode);  
  16.             }  
  17.         }  
  18.         ......  
  19.     }  

    10)在函数createLockScreen或者createUnlockScreenFor中创建具体的Lock或者Unlock View界面,并调用show函数进行显示
    至此,Keyguard解锁屏模块从系统开机启动到界面显示的处理逻辑已介绍完成。

2、两次按下Power按钮屏幕亮->暗->亮过程中锁屏模

抱歉!评论已关闭.