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
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
- public void init(Context context, IWindowManager windowManager,
- WindowManagerFuncs windowManagerFuncs,
- LocalPowerManager powerManager) {
- …
- mKeyguardMediator = new KeyguardViewMediator(context, this, powerManager);
- }
KeyguardViewMediator構造函數中實例化PowerManager的三個鎖及KeyguardUpdateMonitor、LockPatternKeyguardViewProperties、KeyguardViewManager對象。
[java] view plain copy
- public KeyguardViewMediator(Context context, PhoneWindowManager callback,
- LocalPowerManager powerManager) {
- mPM = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- mWakeLock = mPM.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "keyguard");
- mWakeLock.setReferenceCounted(false);
- mShowKeyguardWakeLock=mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
- mShowKeyguardWakeLock.setReferenceCounted(false);
- mWakeAndHandOff = mPM.newWakeLock(
- PowerManager.PARTIAL_WAKE_LOCK,
- "keyguardWakeAndHandOff");
- mWakeAndHandOff.setReferenceCounted(false);
- mUpdateMonitor = new KeyguardUpdateMonitor(context);
- mUpdateMonitor.registerInfoCallback(this);
- mUpdateMonitor.registerSimStateCallback(this);、
- mKeyguardViewProperties=new LockPatternKeyguardViewProperties(mLockPatternUtils, mUpdateMonitor);
- mKeyguardViewManager = new KeyguardViewManager(
- context, WindowManagerImpl.getDefault(), this,
- mKeyguardViewProperties, mUpdateMonitor);
- }
在KeyguardViewManager的show中實例化KeyguardViewHost、LockPatternKeyguardView對象。
[java] view plain copy
- public synchronized void show() {
- if (mKeyguardHost == null) {
- mKeyguardHost = new KeyguardViewHost(mContext, mCallback);
- WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD,
- flags, PixelFormat.TRANSLUCENT);
- mViewManager.addView(mKeyguardHost, lp);
- }
- if (mKeyguardView == null) {
- mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);
- mKeyguardView.setCallback(mCallback);
- final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT);
- mKeyguardHost.addView(mKeyguardView, lp);
- }
在LockPatternKeyguardView的createLockScreen和createUnlockScreenFor函數中建立加鎖和解鎖屏幕。
[java] view plain copy