一、 系统是如何启动锁屏的,请看下文:
1、系统开机后会启动一系列的server
在frameworks/base/services/java/com/android/server/SystemServer.java中
ServerThread::Run()
//这里是将系统启动所需要的server用ServiceManager.addService()方法添加的系统中,然后启动。
。。。。
Wm=WindowManagerService.main(context,power,factoryTest!=SystemServer.FACTORY_TEST_LOW_LEVEL,!firstBoot, onlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE,wm);
。。。。
在这个方法中添加了相当多的服务,当这些服务添加完成后就会通知许多地方系统已经准备完成,而WindowManagerService就是需要通知的地方之一。
而wm.systemReady()方法就是其具体实现。
2、具体调用流程及代码如下:
frameworks/base/services/java/com/android/server/wm/WindowManagerService.java::systemReady() >>
/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java:: systemReady(){
if (mKeyguardMediator != null) {// tell thekeyguard
mKeyguardMediator.onSystemReady();//这里就开始准备启动锁屏了
}
synchronized (mLock) {
。。。。。。。。。
}
>> frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java:: onSystemReady(){
synchronized (this) {
if (DEBUG) Log.d(TAG, "onSystemReady");
mSystemReady = true;
doKeyguardLocked();//这里就是锁屏的入口
}
}
>> showLocked()>>handleShow()>>
frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java::show(){
。。。。。
if(mScreenOn) {
mKeyguardView.show();//这里就将锁屏显示出来
}
}
mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
。。。。。。
}
到这里,系统差不多就将锁屏启动完了,但是其中有许多细节没有提及到,下面将慢慢的分析。
二、 锁屏核心类的实现分析
先来看下锁屏各类的调用关系图
1、 KeyguardViewMediator.java是重要类之一
Path::frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
功能:该类提供了一些接口,由PhoneWindowManager去访问控制Keyguard,该类是唯一实现了KeyguardViewCallback的类。该类的初始化是在PolicyWindowManager的构造函数中创建的。
上面提到的mKeyguardMediator.onSystemReady()方法是定义在KeyguardViewMediator.java类中的,这个类是整个待机解/锁屏业务的调度器,负责调度锁屏界面的相关动作及查询解锁屏状态,它在PhoneWindowManager初始化时被创建,并运行在它的线程上,锁屏的UI界面也是在这个线程上创建及显示的。这个类提供的状态查询api可以被 诸如com.android.server.wm.WindowManagerService、com.android.server.PowerManagerService等线程调用,所以KeyguardViewMediator类上的这些api方法都是线程同步的(synchronized)。开机启动时,首先执行PhoneWindowManager.systemReady(),调用KeyguardViewMediator.onSystemReady()进行待机锁屏及解锁逻辑。
给几个截图
下面看看它具体的方法
doKeyguardLocked(),这个方法是锁屏的入口,看看它的方法说明
/*Enable the keyguard if the settings are appropriate.*/
意思就是说在Setting里面设置了锁屏就启用keyguard
private void doKeyguardLocked(){}
来看看有哪些地方在调用它
A. 系统开机启动完成后会在onSystemReady()中调用它来启动锁屏
B. 若设置了锁屏,当按下power键,在onScreenTurnedOff()中(熄灭屏幕后)会调用它,所以说当再次按下后,就看到锁屏了。
C. 在TIMEROUT(屏幕长时间没动,超过了屏幕sleep时间)后会调用它
D. 当SIM卡的状态发生改变后,会调用。
E. 当接收到DELAYED_KEYGUARD_ACTION和TelephonyManager.ACTION_PHONE_STATE_CHANGED两个广播后
会在mBroadCastReceiver:: onReceive()中去调用。
再看keyguardDone方法,这是解锁完成后会调用的,跟上一个方法是是对应的。
publicvoid keyguardDone(boolean authenticated, boolean wakeup) {
synchronized (this) {
。。。。。
if (DEBUG)Log.d(TAG, "keyguardDone(" + authenticated + ")");
Message msg = mHandler.obtainMessage(KEYGUARD_DONE);
msg.arg1 =wakeup ? 1 : 0;
mHandler.sendMessage(msg);
。。。。。
}
解锁完成后会发一个handler消息出去,handler收到指令后,就会把锁屏取消了,然后到该到的地方去。
private Handler mHandler = new Handler() {
@Override
public voidhandleMessage(Message msg) {
switch(msg.what) {
.....
case KEYGUARD_DONE://收到指令
handleKeyguardDone(msg.arg1 != 0);//开始解除锁屏操作
.....
>>
private void handleKeyguardDone(booleanwakeup) {
。。。。。
handleHide();
。。。。。
}
>>
private void handleHide() {
synchronized (KeyguardViewMediator.this) {
.....
mKeyguardViewManager.hide();
mShowing = false;//将当前锁屏显示状态改为false
。。。。。
}
>> frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java::hide(){
。。。。
mKeyguardHost.removeView(lastView);//最后从顶层的view中移除,锁屏就解锁完成了
。。。。
}
然而其他应用程序或者服务也可以请求禁止锁屏(通过调用KeyguardViewMediator的setKeyguardEnabled(boolean)方法)。
例如:接听来电界面或去话界面是不能让其锁屏的;闹钟界面也是不能让其锁屏;视频的播放过程中也是不能让其锁屏。
该类的其他方法有兴趣可以去看看。
2、KeyguardViewManager.java类
Path::frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
功能:包装了WindowManager功能了,提供了添加、删除锁屏界面的功能。其中的onScreenOn和onScreenOff两个方法和KeyguardViewMediator.java里面的不同,有兴趣可以深入研究。
上面有接触到该类的show()方法,在这个方法中
。。。。。。。。
if (mKeyguardView == null) {
if (DEBUG) Log.d(TAG, "keyguard view is null, creatingit...");
mKeyguardView=mKeyguardViewProperties.createKeyguardView(mContext,mCallback,mUpdateMonitor,this);
mKeyguardView.setId(R.id.lock_screen);
final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
mKeyguardHost.addView(mKeyguardView, lp);
。。。。。。。
}
mKeyguardViewProperties.createKeyguardView(mContext,mCallback,mUpdateMonitor,this)
这个方法的实现其实是在LockPatternKeyguardViewProperties.java:: createKeyguardView()方法中做的
这个就是创建一个KeyguardViewBase的对象,也就是管理Lock、Unlock画面的类实例。但最后还是在LockPatternKeyguardView.java类中操作的。
3、 LockPatternKeyguardView.java是重要类之二
Path::frameworks/base/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java父类(KeyguardViewBase.java)
这个类