一、     系统是如何启动锁屏的,请看下文:

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

这个类为解锁屏模块的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包括( PatternUnlockScreenAccountUnlockScreenPasswordUnlockScreen 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);

/*把创建好的lockscreen添加到LockPatternKeyguardView,而

LockPatternKeyguardView又是继承KeyguardViewBase,最终将

LockPatternKeyguardView添加到KeyguardViewManager.java::mKeyguardHost对象里,最后再设置mKeyguardHost为Visible */

       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;

        }

        ......

}

解锁完成。

好了,锁屏分析的差不多了,可能有些地方理解的不是很正确,但是可以参考参考,有兴趣可以深入研究,有疑问可以留言。



更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. Python list sort方法的具体使用
  3. python list.sort()根据多个关键字排序的方法实现
  4. android上一些方法的区别和用法的注意事项
  5. Android(安卓)Activity界面切换添加动画特效
  6. Android(安卓)拨号器的简单实现
  7. android实现字体闪烁动画的方法
  8. Android中dispatchDraw分析
  9. android用户界面之按钮(Button)教程实例汇

随机推荐

  1. android学习笔记(一)
  2. android之动画实现(一)(四种基本补间动画)
  3. 排班表实现-----Android
  4. Android第一行代码读书笔记
  5. 将Android项目导入Android Studio
  6. Android(安卓)ScrollView中嵌套ListView
  7. Android UI更新
  8. android 监听电话去电接通瞬间[非来电]
  9. 2013年4月19日--佳都新太Android笔试题+
  10. Android几种消息推送方案总结