Android窗口系統機制之KEYGUARD機制

Android的KEYGUARD相關類提供了屏幕鎖屏等相關功能,雖然功能簡單,可是相關的邏輯仍是挺複雜的,要處理屏幕處於不一樣狀態的狀況,要監控各類事件(時間,電池,Sim狀態,電話狀態),所以GOOGLE仍是對屏幕功能進行了細緻的設計,架構上採用了中介模式、MVC模式等設計模式。系統類圖以下:java

       

      PhoneWindowManager、PowerManager、KeyguardViewMediator、KeyguardUpdateMonitor、KeyguardViewManager、KeyguardViewHost、LockPatternKeyguardView、KeyguardScreen相關類之間構成中介模式,KeyguardViewMediator對象處於模式的核心,起到中介者的角色,其它對象都經過KeyguardViewMediator對象相互交互。設計模式

      KeyguardViewMediator對象是PhoneWindowManager成員,所以PhoneWindowManage能夠直接訪問KeyguardViewMediator對象。KeyguardViewMediator也經過PowerManager服務建立了三個不計數WakeLock鎖實現與PowerManager服務的通信,達到鎖屏操做時電源狀態管理的目的(mWakeLock鎖用於保證在 keyguard顯示時可以顯示一段時間後屏幕才能睡眠;mShowKeyguardWakeLock用於在 keyguard顯示要打開時可以保持設備喚醒;mWakeAndHandOff由PhoneWindowManager截獲事件進行觸發,用於在用戶按鍵或鼠標移動時喚醒設備便於對keyguard進行操做)。KeyguardUpdateMonitor、KeyguardViewManager對象做爲KeyguardViewMediator對象的成員又都是由KeyguardViewMediator實例化的,KeyguardViewMediator能夠直接操做KeyguardUpdateMonitor、KeyguardViewManager對象。架構

      而KeyguardViewHost、LockPatternKeyguardView做爲視圖對象經過調用KeyguardViewManager對象的show函數建立並做爲視圖添加到窗口上, KeyguardViewHost做爲窗口得主視圖, LockPatternKeyguardView是KeyguardViewHost的子視圖。KeyguardScreen類是各種鎖屏、解鎖屏幕的接口,各種鎖屏、解鎖屏幕都是KeyguardScreen類的視圖實現類,在調用LockPatternKeyguardView的updateScreen函數時根據不一樣的模式做爲LockPatternKeyguardView的子視圖添加到LockPatternKeyguardView視圖上顯示。app

      KeyguardUpdateMonitor、KeyguardViewHost、LockPatternKeyguardView、KeyguardScreen接口的對象都經過回調與KeyguardViewMediator反向調用。函數

      KeyguardUpdateMonitor 類實現時間,電池,Sim狀態,電話狀態的監視,KeyguardViewMediator類是KeyguardUpdateMonitor類內部回調接口InfoCallback、SimStateCallbac的實現類,所以KeyguardViewMediator對象能夠做爲KeyguardUpdateMonitor對象的回調對象,經過KeyguardUpdateMonitor的registerInfoCallback和registerSimStateCallback函數把KeyguardViewMediator對象添加到KeyguardUpdateMonitor對象的回調對象列表中,當KeyguardViewMediator對象檢測到時間,電池,Sim狀態,電話狀態變化時經過回調調用KeyguardViewMediator對象的相關接口。oop

      KeyguardViewMediator類也是KeyguardViewCallback接口的實現,所以在KeyguardViewManager實例化時KeyguardViewMediator對象也做爲KeyguardViewCallback類型的參數傳進KeyguardViewManager做爲KeyguardViewManager的內部成員mCallback。而後mCallback又做爲參數在KeyguardViewHost對象實例化時傳進去做爲KeyguardViewHost對象的成員,並經過LockPatternKeyguardView的函數setCallback設置LockPatternKeyguardView對象的回調對象,所以KeyguardViewHost、LockPatternKeyguardView均可以經過KeyguardViewCallback類型的回調對象與KeyguardViewMediator對象通信。this

      LockPatternKeyguardView對象建立了六個實現了KeyguardScreen接口的各個鎖屏、解鎖屏幕對象,LockScreen用於顯示屏幕加鎖狀態,另外根據不一樣的unlockMode模式建立了不一樣的解鎖屏幕:PatternUnlockScreen實現圖案解鎖模式,SimPukUnlockScreen屏幕實現SIM PUK碼解鎖模式,SimUnlockScreen實現 Sim PIN碼解鎖模式,AccountUnlockScreen實現 GOOGLE賬戶解鎖,PasswordUnlockScreen實現口令解鎖模式。spa

      每一個鎖屏、解鎖屏幕對象在建立時都傳進去一個實現了KeyguardScreenCallback接口的回調對象mKeyguardScreenCallback(LockPatternKeyguardView的一個成員),KeyguardScreenCallback接口派生自KeyguardViewCallback接口。在mKeyguardScreenCallback回調對象中實現了KeyguardViewCallback類型的回調對象mCallback的包裝(裝飾模式的採用),所以各個鎖屏、解鎖屏幕對象能夠經過KeyguardScreenCallback接口與KeyguardViewMediator對象通信。.net

      另外KeyguardUpdateMonitor、KeyguardViewManager、LockPatternKeyguardView、KeyguardScreen類還構成了MVC模式。KeyguardUpdateMonitor實現了MVC模式中的模式角色,用來提供模式狀態數據。KeyguardViewManager擔當MVC模式中的控制器角色,經過KeyguardViewManager生成視圖,生成和控制視圖的表現。LockPatternKeyguardView、KeyguardScreen接口類對象擔當視圖角色,模式能夠直接向視圖傳送狀態(經過把LockPatternKeyguardView和鎖屏、解鎖屏幕的內部對象做爲回調對象登記到KeyguardUpdateMonitor對象的回調對象列表中),視圖也能夠直接讀取KeyguardUpdateMonitor模式的狀態數據,所以LockPatternKeyguardView、KeyguardScree類對象視圖中都有一個KeyguardUpdateMonitor對象的引用。線程

      LockPatternKeyguardView對象由LockPatternKeyguardViewProperties對象採用了工廠方法進行實例化。

      各個對象的實例化代碼片段:

         PhoneWindowManager對象WindowManagerService.java中實例化,並在WindowManagerService的PolicyThread線程運行時初始化。

 

[java] view plain copy

  1. final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();  
  2.   
  3.      public PolicyThread(WindowManagerPolicy policy,  
  4.   
  5.              WindowManagerService service, Context context,  
  6.   
  7.              PowerManagerService pm) {  
  8.   
  9.          super("WindowManagerPolicy");  
  10.   
  11.          mPolicy = policy;  
  12.   
  13.          mService = service;  
  14.   
  15.          mContext = context;  
  16.   
  17.          mPM = pm;  
  18.   
  19.      }  
  20.   
  21.      public void run() {  
  22.   
  23.          Looper.prepare();  
  24.   
  25.          mPolicy.init(mContext, mService, mService, mPM);  
  26.   
  27.   
  28.   
  29.          synchronized (this) {  
  30.   
  31.    
  32.   
  33.          }  
  34.   
  35.          Looper.loop();  
  36.   
  37.      }  
  38.   
  39.  }  

 

 

 

        final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager(); public PolicyThread(WindowManagerPolicy policy, WindowManagerService service, Context context, PowerManagerService pm) { super("WindowManagerPolicy"); mPolicy = policy; mService = service; mContext = context; mPM = pm; } public void run() { Looper.prepare(); mPolicy.init(mContext, mService, mService, mPM); synchronized (this) { } Looper.loop(); } }

         在PhoneWindowManager對象init函數調用時實例化KeyguardMediator對象

  

[java]  view plain  copy
  1. public void init(Context context, IWindowManager windowManager,  
  2.   
  3.             WindowManagerFuncs windowManagerFuncs,  
  4.   
  5.             LocalPowerManager powerManager) {      
  6.   
  7.  …  
  8.   
  9.    mKeyguardMediator = new KeyguardViewMediator(context, this, powerManager);  
  10.   
  11. }  
 

 

 

       KeyguardViewMediator構造函數中實例化PowerManager的三個鎖及KeyguardUpdateMonitor、LockPatternKeyguardViewProperties、KeyguardViewManager對象。

    

[java]  view plain  copy
  1. public KeyguardViewMediator(Context context, PhoneWindowManager callback,  
  2.   
  3.            LocalPowerManager powerManager) {  
  4.   
  5.        mPM = (PowerManager) context.getSystemService(Context.POWER_SERVICE);  
  6.   
  7.        mWakeLock = mPM.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "keyguard");  
  8.   
  9.        mWakeLock.setReferenceCounted(false);  
  10.   
  11.        mShowKeyguardWakeLock=mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");  
  12.   
  13.        mShowKeyguardWakeLock.setReferenceCounted(false);  
  14.   
  15.   
  16.   
  17.        mWakeAndHandOff = mPM.newWakeLock(  
  18.   
  19.                PowerManager.PARTIAL_WAKE_LOCK,  
  20.   
  21.                "keyguardWakeAndHandOff");  
  22.   
  23.        mWakeAndHandOff.setReferenceCounted(false);  
  24.   
  25.   
  26.   
  27.        mUpdateMonitor = new KeyguardUpdateMonitor(context);  
  28.   
  29.        mUpdateMonitor.registerInfoCallback(this);  
  30.   
  31.        mUpdateMonitor.registerSimStateCallback(this);、  
  32.   
  33.   
  34.   
  35.        mKeyguardViewProperties=new LockPatternKeyguardViewProperties(mLockPatternUtils, mUpdateMonitor);  
  36.   
  37.   
  38.   
  39.        mKeyguardViewManager = new KeyguardViewManager(  
  40.   
  41.                context, WindowManagerImpl.getDefault(), this,  
  42.   
  43.                mKeyguardViewProperties, mUpdateMonitor);  
  44.   
  45.   
  46.   
  47.    }  
 

 

 

      在KeyguardViewManager的show中實例化KeyguardViewHost、LockPatternKeyguardView對象。

     

[java]  view plain  copy
  1. public synchronized void show() {  
  2.   
  3.           if (mKeyguardHost == null) {  
  4.   
  5.                mKeyguardHost = new KeyguardViewHost(mContext, mCallback);  
  6.   
  7.                WindowManager.LayoutParams lp = new WindowManager.LayoutParams(  
  8.   
  9.                    stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD,  
  10.   
  11.                    flags, PixelFormat.TRANSLUCENT);  
  12.   
  13.    
  14.   
  15.                mViewManager.addView(mKeyguardHost, lp);  
  16.   
  17.        }  
  18.   
  19.   
  20.   
  21.        if (mKeyguardView == null) {  
  22.   
  23.            mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);  
  24.   
  25.            mKeyguardView.setCallback(mCallback);  
  26.   
  27.   
  28.   
  29.            final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams(  
  30.   
  31.                    ViewGroup.LayoutParams.MATCH_PARENT,  
  32.   
  33.                    ViewGroup.LayoutParams.MATCH_PARENT);  
  34.   
  35.   
  36.   
  37.            mKeyguardHost.addView(mKeyguardView, lp);  
  38.   
  39.    }  
 

 

 

   在LockPatternKeyguardView的createLockScreen和createUnlockScreenFor函數中建立加鎖和解鎖屏幕。

       

[java] view plain copy

  1. View createLockScreen() {  
  2.   
  3.         View lockView = new LockScreen(  
  4.   
  5.                 mContext,  
  6.   
  7.                 mConfiguration,  
  8.   
  9.                 mLockPatternUtils,  
  10.   
  11.                 mUpdateMonitor,  
  12.   
  13.                 mKeyguardScreenCallback);  
  14.   
  15.         return lockView;  
  16.   
  17.     }  
  18.   
  19.    
  20.   
  21.     View createUnlockScreenFor(UnlockMode unlockMode) {  
  22.   
  23.         if (unlockMode == UnlockMode.Pattern) {  
  24.   
  25.             PatternUnlockScreen view = new PatternUnlockScreen(  
  26.   
  27.                     mContext,  
  28.   
  29.                     mConfiguration,  
  30.   
  31.                     mLockPatternUtils,  
  32.   
  33.                     mUpdateMonitor,  
  34.   
  35.                     mKeyguardScreenCallback,  
  36.   
  37.                     mUpdateMonitor.getFailedAttempts());  
  38.   
  39.         } else if (unlockMode == UnlockMode.SimPuk) {  
  40.   
  41.             unlockView = new SimPukUnlockScreen(  
  42.   
  43.                     mContext,  
  44.   
  45.                     mConfiguration,  
  46.   
  47.                     mUpdateMonitor,  
  48.   
  49.                     mKeyguardScreenCallback,  
  50.   
  51.                     mLockPatternUtils);  
  52.   
  53.         } else if (unlockMode == UnlockMode.SimPin) {  
  54.   
  55.             unlockView = new SimUnlockScreen(  
  56.   
  57.                     mContext,  
  58.   
  59.                     mConfiguration,  
  60.   
  61.                     mUpdateMonitor,  
  62.   
  63.                     mKeyguardScreenCallback,  
  64.   
  65.                     mLockPatternUtils);  
  66.   
  67.         } else if (unlockMode == UnlockMode.Account) {  
  68.   
  69.      
  70.   
  71.                 unlockView = new AccountUnlockScreen(  
  72.   
  73.                         mContext,  
  74.   
  75.                         mConfiguration,  
  76.   
  77.                         mUpdateMonitor,  
  78.   
  79.                         mKeyguardScreenCallback,  
  80.   
  81.                         mLockPatternUtils);  
  82.   
  83.              
  84.   
  85.         } else if (unlockMode == UnlockMode.Password) {  
  86.   
  87.             unlockView = new PasswordUnlockScreen(  
  88.   
  89.                     mContext,  
  90.   
  91.                     mConfiguration,  
  92.   
  93.                     mLockPatternUtils,  
  94.   
  95.                     mUpdateMonitor,  
  96.   
  97.                     mKeyguardScreenCallback);  
  98.   
  99.         }  
  100.   
  101.         return unlockView;  
  102.   
  103.     }  
相關文章
相關標籤/搜索