一、 系统是如何启动锁屏的,请看下文:
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(),这个方法是锁屏的入口,看看它的方法说明
意思就是说在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)
这个类为解锁屏模块的View界面,为所有解锁屏界面的host view。它是所有锁屏和解锁UI界面的宿主。它有2个模式Mode. LockScreen和Mode. UnlockScreen。它负责根据当前上下文环境切换当前应该显示的待机屏。它提供一个回调给当前显示的待机屏并处理其回调,如果回调动作是自己处理不了的,则继续报告给KeyguardViewMediator进行处理。它会根据在Settings中设置的安全策略,显示不同的解锁屏界面。Google原生代码中实现了多种解锁屏界面:
例如:
1) LockScreen:用于显示屏幕加锁状态
2) PatternUnlockScreen:实现图案解锁模式
3) SimPukUnlockScreen:屏幕实现SIM PUK码解锁模式
4) SimUnlockScreen:实现Sim PIN码解锁模式
5) AccountUnlockScreen:实现 GOOGLE帐户解锁
6) PasswordUnlockScreen:实现自定义密码解锁模式
咱们来仔细的分析下这个类
在Setting里面设置各种锁屏之后,再按power键重新开启时会产生Lock或者Unlock画面,需要输入密码或绘出Pattern等操作后才能进入Home界面。这个锁定和解锁是由这个类实现的。来分析下它的构造函数
public LockPatternKeyguardView(
Contextcontext, KeyguardViewCallback callback, KeyguardUpdateMonitor updateMonitor,
LockPatternUtils lockPatternUtils, KeyguardWindowController controller,
BackupQuestionUtils backupQuestionUtils) {
super(context,callback);
…。。。。。。。。。
mConfiguration =context.getResources().getConfiguration();
。。。。。。。。
mUpdateMonitor.registerInfoCallback(mInfoCallback);
keyguardScreenCallback();
。。。。。。。。
}
重要实现:mConfigurtion=context.getResources().getConfiguration();
这个函数是用来获取系统的一些配置,在此用来决定是横屏显示还是竖屏显示。还有一个非常重要的回调函数mKeyguardScreenCallback,里面实现方法对应了具体功能(如:解锁,锁屏等)。
该类中有个getInitialMode()方法,这个方法是用来获取系统锁屏的Mode,这个Mode是个枚举类型的
enum Mode{
LockScreen,
UnlockScreen
}
主要是用来判断两大锁屏类型,
LockScreen一般是指滑动锁屏,没有密码限制、
UnlockScreen包括( PatternUnlockScreen、AccountUnlockScreen、PasswordUnlockScreen、 SimUnlockScreen)这些锁屏类型,在上面有提到。
然而获取这个状态非常重要,它决定了初始化时究竟是显示unlock界面还是lock界面。看下它的实现
private ModegetInitialMode() {
//判断当前sim卡的状态(如:缺卡、sim PUK锁定、simready等)
final IccCard.StatesimState = mUpdateMonitor.getSimState();
if(stuckOnLockScreenBecauseSimMissing() ||
(simState == IccCard.State.PUK_REQUIRED &&
!mLockPatternUtils.isPukUnlockScreenEnable())) {
returnMode.LockScreen;
} else {
if(!isSecure() || mShowLockBeforeUnlock) {
return Mode.LockScreen;
} else {
returnMode.UnlockScreen;
}
}
}
判断手机sim卡是否被puk锁定或者手机没有sim卡,则返回了Mode.LockScreen;否则判断手机是否设置了其他的解锁方式,其中有个方法isSecure()判断当前是否用了其他的解锁方式(如:图形、密码等),返回true,则返回Mode.UnlockScreen。
咱们看看isSecure()方法
protected boolean isSecure() {
//得到当具体是什么UnlockScreen方式,下面会一一进行判断
UnlockMode unlockMode =getUnlockMode();
boolean secure= false;
switch(unlockMode) {
caseQuestion:
caseAccount:
caseBackupSelection:
casePattern:
secure= mLockPatternUtils.isLockPatternEnabled();
break;
caseSimPin:
secure= mUpdateMonitor.getSimState() == IccCard.State.PIN_REQUIRED;
break;
caseSimPuk:
secure= mUpdateMonitor.getSimState() == IccCard.State.PUK_REQUIRED;
break;
casePassword:
secure= mLockPatternUtils.isLockPasswordEnabled();
break;
caseUnknown:
// Thismeans no security is set up
break;
default:
thrownew IllegalStateException("unknown unlock mode " + unlockMode);
}
return secure;
}
最后返回一个UnlockScreen类型
getInitialMode()方法在会做为一个参数传入updateScreen(getInitialMode(),false);这个方法中,这个方法是干什么的呢?请往下看
该类中的第三个方法updateScreen();
protected void updateScreen(Mode mode, boolean force){
。。。。。。
// Re-createthe lock screen if necessary
if (mode ==Mode.LockScreen || mShowLockBeforeUnlock) {
if (force|| mLockScreen == null || mMode == Mode.UnlockScreen) {
。。。。。。。
//上面根据Mode来判断是否是lockSeceen,若是就创建lockscreen锁屏
recreateLockScreen();
}
// No darkfilter since that is managed in the external lockscreen
setBackgroundDrawable(null);
}
。。。。。。。
if (mode ==Mode.UnlockScreen && unlockMode != UnlockMode.Unknown) {
if (force|| mUnlockScreen == null || unlockMode != mUnlockScreenMode ||
(getUnlockMode() == UnlockMode.SimPin) ||
(getUnlockMode() == UnlockMode.SimPuk)) {
//上面根据Mode来判断是否是UnlockSeceen,若是就创建Unlockscreen锁屏
recreateUnlockScreen(unlockMode);
}
resetBackground(); // Enable dark filter
}
//visibleScreen should never be null
//下面是根据mode的值来判断到底谁该显示,谁该隐藏
final View goneScreen =(mode == Mode.LockScreen) ? mUnlockScreen : mLockScreen;
final ViewvisibleScreen = (mode == Mode.LockScreen) ? mLockScreen : mUnlockScreen;
。。。。。。。。
//这里就是控制两种锁屏类型的显示和隐藏,所以这里相信应该明白锁屏的根本机制就是控制Screen的显示和隐藏
if (goneScreen != null) {
goneScreen.setVisibility(View.GONE);
}
visibleScreen.setVisibility(View.VISIBLE);
mWindowController.setFullscreen(isFullscreen((KeyguardScreen)visibleScreen));
requestLayout();
。。。。。。。
}
}
上面的方法里调用了其他两个方法
recreateLockScreen()和recreateUnlockScreen(unlockMode);这两个方法就是创建LockScreen和UnLockscreen所用的。下面具体来看看
方法一::recreateLockScreen()
protected void recreateLockScreen() {
if (mLockScreen != null) {
((KeyguardScreen) mLockScreen).onPause();
((KeyguardScreen)mLockScreen).cleanUp();
removeView(mLockScreen);
}
//将创建好的LockScreen赋值给mLockScreen对象
mLockScreen= createLockScreen();
//设置lockScreen不显示
mLockScreen.setVisibility(View.INVISIBLE);
addView(mLockScreen);
}
方法二::recreateUnlockScreen(unlockMode);
protected void recreateUnlockScreen(UnlockMode unlockMode) {
if(mUnlockScreen != null) {
((KeyguardScreen) mUnlockScreen).onPause();
((KeyguardScreen) mUnlockScreen).cleanUp();
removeView(mUnlockScreen);
}
mUnlockScreen =createUnlockScreenFor(unlockMode);
mUnlockScreen.setVisibility(View.INVISIBLE);
addView(mUnlockScreen);
}
这个方法其实跟上个方法大同小异,只是在createUnlockScreenFor(unlockMode);这里传入了一个unlockMode参数,根据这个参数去判断到底是创建那个解锁方式(如:密码、图形、Pin码锁等)。来看看这个方法
ViewcreateUnlockScreenFor(UnlockMode unlockMode) {
View unlockView = null;
.....
if(unlockMode == UnlockMode.Pattern) {
PatternUnlockScreen view = newPatternUnlockScreen(
......
unlockView = view;
} else if (unlockMode == UnlockMode.SimPuk){
unlockView = newSimPukUnlockScreen(
......
} else if (unlockMode == UnlockMode.SimPin) {
unlockView = new SimUnlockScreen(
.......
} else if (unlockMode == UnlockMode.Account) {
try {
unlockView = newAccountUnlockScreen(
......
} catch (IllegalStateException e) {
......
returncreateUnlockScreenFor(UnlockMode.Pattern);
}
} else if (unlockMode == UnlockMode.Password){
unlockView = newPasswordUnlockScreen(
......
} else if (unlockMode ==UnlockMode.BackupSelection) {
unlockView = newBackupSelectionUnlockScreen(mContext, mUpdateMonitor,
mKeyguardScreenCallback,mLockPatternUtils);
} else if (unlockMode == UnlockMode.Question) {
unlockView = newBackupQuestionUnlockScreen(mContext, mUpdateMonitor,mKeyguardScreenCallback,mLockPatternUtils, mBackupUtils);
} else {
throw newIllegalArgumentException("unknown unlock mode " + unlockMode);
}
initializeTransportControlView(unlockView);
initializeBiometricUnlockView(unlockView);
mUnlockScreenMode = unlockMode;
return unlockView;
}
上面这两个方法就是创建锁屏界面的过程,有不清楚可以自己跟下代码。
上面提到的几个类都是锁屏中最重要的类,有兴趣可以好好研究下
下面简单介绍下锁屏中的其他类
4、 KeyguardScreen.java类
Path::frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardScreen.java
功能:该接口的主要功能是为每个需要显示的界面:LockScreen或者UnlockScreen定义了四个方法,使其在不同的状态能够得到相应的处理。
public interface KeyguardScreen {
boolean needsInput();
void onPause();
void onResume();
void cleanUp();
}
5、 KeyguardScreenCallback.java类
Path::frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardScreenCallback.java
功能: 每个需要显示的界面:LockScreen或者UnLockScreen都保存了该对象的唯一实例,用来向控制界面汇报情况。
6、 KeyguardViewCallback.java类
Path::frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardViewCallback.java
功能: 提供了一些接口用来接受用户操作Screen。其唯一实现类KeyguardViewMediator。
7、 KeyguardWindowController.java类(interface)
Path::frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardWindowController.java
功能:提供通用 接口,判断该界面是否需要显示输入法窗口。其唯一实现类是KeyguardViewManager类
8、 KeyguardUpdateMonitor.java类
Path::frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
功能:监听系统状态值的改变如时间、SIM卡状态、电池电量等,状态值的改变会回调监听了该状态信息的对象实例。如果只是关注功能的话只需要看hadle里面的每个消息调用的方法即可。
3、 KeyguardViewBase.java类
Path::frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
功能:为LockPatternKeyguardView提供了一组通用的方法。需要值得注意的方法就是他对某些KeyEvent的监听,当他监听到这些KeyEvent,我们的App就监听不到这些KeyEvent了 。
9. KeyguardViewProperties类(interface)
功能:提供了创建界面的通用方法。(创建LockPatternKeyguardView,其唯一实现类是是LockPatternKeyguardViewProperties类)
另外几种锁屏方式相关的类
LockScreen.java用于显示屏幕加锁状态
PatternUnlockScree.java实现图案解锁类
SimPukUnlockScreen.java实现SIM PUK码解锁模式类
SimUnlockScreen.java实现Sim PIN码解锁类
AccountUnlockScreen.java实现 GOOGLE 帐户解锁类
PasswordUnlockScreen.java实现自定义密码解锁模式类
下面简单介绍下当按下power健时的处理逻辑
下面先给出一个 连续两次按下Power按钮屏幕亮->暗->亮过程中解锁屏模块处理逻辑的时序图
在函数
PowerManagerService:setPowerState(frameworks/base/services/java/com/android/server/PowerManagerService.java)方法中响应Power按钮的按下,代码如下:
private voidsetPowerState(int newState, boolean noChangeLights, int reason)
{
synchronized (mLocks) {
……
if (oldScreenOn != newScreenOn) {
if (newScreenOn) {
// When the user pressesthe power button, we need to always send out the
// notification that it'sgoing to sleep so the keyguard goes on. But
// we can't do that untilthe screen fades out, so we don't show the keyguard
// too early.
if(mStillNeedSleepNotification) {
sendNotificationLocked(false, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
}
……
if (err == 0) {
sendNotificationLocked(true,-1);
// Update the lights*after* taking care of turning the
// screen on, so we dothis after our notifications are
// enqueued and thuswill delay turning on the screen light
// until the windowsare correctly displayed.
if (stateChanged) {
updateLightsLocked(newState, 0);
}
mPowerState |= SCREEN_ON_BIT;
}
} else {
……
if(!mScreenBrightness.animating) {
err = screenOffFinishedAnimatingLocked(reason);
}
……
}
}
……
}
}
根据上面的代码逻辑,屏幕即将变暗时调用函数screenOffFinishedAnimatingLocked,屏幕即将变亮时调用函数sendNotificationLocked。
2)函数sendNotificationLocked发送Notification Task线程到handler,并异步执行通知解锁屏模块进行状态更新:
private RunnablemNotificationTask = new Runnable()
{
public void run()
{
while (true) {
......
if (value == 1) {
policy.screenTurningOn(mScreenOnListener);
......
}
else if (value == 0) {
policy.screenTurnedOff(why);
......
}
else {
// If we're in this case,then this handler is running for a previous
// paired transaction. mBroadcastWakeLock will already have beenreleased.
break;
}
}
}
};
上面的线程函数run中分别处理了屏幕变暗和变亮的情形。按下Power按钮屏幕变暗时调用了函数screenTurnedOff,why为变暗的原因,此处值为OFF_BECAUSE_OF_USER。
3)KeyguardViewMediator中根据屏幕变暗的原因分别处理屏幕变暗事件:
public void onScreenTurnedOff(int why) {
synchronized (this) {
……
else if (mShowing) { //若是(mShowing)则重置显示界面,否则重新显示锁屏界面
notifyScreenOffLocked();
resetStateLocked();
}else if (why ==WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) {
……
if (timeout <=0) {
// Lock now
mSuppressNextLockSound = true;
doKeyguardLocked();
} else {
// Lock in thefuture
long when =SystemClock.elapsedRealtime() + timeout;
Intent intent= new Intent(DELAYED_KEYGUARD_ACTION);
intent.putExtra("seq", mDelayedShowingSequence);
PendingIntentsender = PendingIntent.getBroadcast(mContext,
0, intent,PendingIntent.FLAG_CANCEL_CURRENT);
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
sender);
}
} else if (why ==WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
// Do not enablethe keyguard if the prox sensor forced the screen off.
} else { //显示锁屏屏幕
doKeyguardLocked();
}
}
}
4)调用doKeyguardLocked重新显示锁屏界面,随后的锁屏界面显示逻辑与Keyguard模块启动显示中的8~10步相同,不再赘述。
5)按下Power按钮屏幕即将由暗->亮时代码处理逻辑重新执行1~2步,第二步中屏幕变亮时调用的函数是PhoneWindowManager:screenTurningOn。
6)函数screenTurningOn中调用中介者KeyguardViewMediator的函数onScreenTurnedOn,该函数直接调用屏幕变亮异步通知函数KeyguardViewMediator:notifyScreenOnLocked,告知解锁屏模块屏幕即将变亮。
7)函数handleNotifyScreenOn响应屏幕变亮的通知
8)程序执行到LockPatternKeyguardView:onScreenTurnedOn函数,并调用show函数进行解锁屏界面的显示,代码如下:
@Override
public void show() {
// Emulate activity life-cycle for bothlock and unlock screen.
if (mLockScreen != null) {
((KeyguardScreen) mLockScreen).onResume();
}
if (mUnlockScreen != null) {
((KeyguardScreen) mUnlockScreen).onResume();
}
if (mBiometricUnlock != null &&mSuppressBiometricUnlock) {
mBiometricUnlock.hide();
}
}
再来看看将锁屏设置为密码锁屏方式时的解锁逻辑
先来看看它的解锁时序图,如下:
这里提到的类
Path::frameworks/base/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
1) 解锁屏界面输入密码点击确定按钮后,在函数onEditorAction中进行响应:
public boolean onEditorAction(TextView v, int actionId, KeyEvent event){
// Check if this was theresult of hitting the enter key
if (actionId ==EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE
|| actionId ==EditorInfo.IME_ACTION_NEXT) {
verifyPasswordAndUnlock();//验证密码是否正确
return true;
}
return false;
}
2)在函数verifyPasswordAndUnlock中对输入的密码进行判断,如果输入正确,测调用keyguardDone响应解锁完成的操作。mCallback.keyguardDone(true)调用是所有解锁屏mode情形在解锁成功后必须调用的函数,随后的处理逻辑对于不同的解锁屏界面也是相同的。
3)回调KeyguardScreenCallback和KeyguardViewMediator的函数keyguardDone,在后者的keyguardDone函数中,异步发送keyDone事件:
Patch::frameworks/base/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
public void keyguardDone(booleanauthenticated, boolean wakeup) {
synchronized (this) {
……
Message msg =mHandler.obtainMessage(KEYGUARD_DONE);
msg.arg1 = wakeup ? 1 : 0;
mHandler.sendMessage(msg);
……
}
}
4)函数KeyguardViewMediator:handleKeyguardDone异步处理keyguardDone事件,调用handleHide隐藏锁屏界面。
5)KeyguardViewManager.hide函数中调用锁屏界面的销毁函LockPatternKeyguardView:cleanUp数隐藏销毁界面,如下:
Path:: frameworks/base/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
public void cleanUp() {
if (mLockScreen != null) {
((KeyguardScreen)mLockScreen).onPause();
((KeyguardScreen)mLockScreen).cleanUp();
this.removeView(mLockScreen);
mLockScreen = null;
}
if (mUnlockScreen != null) {
((KeyguardScreen)mUnlockScreen).onPause();
((KeyguardScreen)mUnlockScreen).cleanUp();
this.removeView(mUnlockScreen);
mUnlockScreen = null;
}
......
}
解锁完成。
好了,锁屏分析的差不多了,可能有些地方理解的不是很正确,但是可以参考参考,有兴趣可以深入研究,有疑问可以留言。