第七篇 窗口系统机制之KEYGUARD机制

转载

  ANDROID的KEYGUARD相关类提供了屏幕锁屏等相关功能,虽然功能简单,但是相关的逻辑还是挺复杂的,要处理屏幕处于不同状态的情况,要监控各种事件(时间,电池,Sim状态,电话状态),因此GOOGLE还是对屏幕功能进行了细致的设计,架构上采用了中介模式、MVC模式等设计模式。系统类图如下

       

      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视图上显示。

      KeyguardUpdateMonitor、KeyguardViewHost、LockPatternKeyguardView、KeyguardScreen接口的对象都通过回调与KeyguardViewMediator反向调用。

      KeyguardUpdateMonitor 类实现时间,电池,Sim状态,电话状态的监视,KeyguardViewMediator类是KeyguardUpdateMonitor类内部回调接口InfoCallback、SimStateCallbac的实现类,因此KeyguardViewMediator对象可以作为KeyguardUpdateMonitor对象的回调对象,通过KeyguardUpdateMonitor的registerInfoCallback和registerSimStateCallback函数把KeyguardViewMediator对象添加到KeyguardUpdateMonitor对象的回调对象列表中,当KeyguardViewMediator对象检测到时间,电池,Sim状态,电话状态变化时通过回调调用KeyguardViewMediator对象的相关接口。

      KeyguardViewMediator类也是KeyguardViewCallback接口的实现,因此在KeyguardViewManager实例化时KeyguardViewMediator对象也作为KeyguardViewCallback类型的参数传进KeyguardViewManager作为KeyguardViewManager的内部成员mCallback。然后mCallback又作为参数在KeyguardViewHost对象实例化时传进去作为KeyguardViewHost对象的成员,并通过LockPatternKeyguardView的函数setCallback设置LockPatternKeyguardView对象的回调对象,因此KeyguardViewHost、LockPatternKeyguardView都可以通过KeyguardViewCallback类型的回调对象与KeyguardViewMediator对象通讯。

      LockPatternKeyguardView对象创建了六个实现了KeyguardScreen接口的各个锁屏、解锁屏幕对象,LockScreen用于显示屏幕加锁状态,另外根据不同的unlockMode模式创建了不同的解锁屏幕:PatternUnlockScreen实现图案解锁模式,SimPukUnlockScreen屏幕实现SIM PUK码解锁模式,SimUnlockScreen实现 Sim PIN码解锁模式,AccountUnlockScreen实现 GOOGLE帐户解锁,PasswordUnlockScreen实现口令解锁模式。

      每个锁屏、解锁屏幕对象在创建时都传进去一个实现了KeyguardScreenCallback接口的回调对象mKeyguardScreenCallback(LockPatternKeyguardView的一个成员),KeyguardScreenCallback接口派生自KeyguardViewCallback接口。在mKeyguardScreenCallback回调对象中实现了KeyguardViewCallback类型的回调对象mCallback的包装(装饰模式的采用),因此各个锁屏、解锁屏幕对象可以通过KeyguardScreenCallback接口与KeyguardViewMediator对象通讯。

      另外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.    }  

      在KeyguardViewManagershow中实例化KeyguardViewHostLockPatternKeyguardView对象。

     

[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.    }  

   在LockPatternKeyguardViewcreateLockScreencreateUnlockScreenFor函数中创建加锁和解锁屏幕。

       

[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.     }  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值