锁屏简介

锁屏代码位置

android4.4版本之前锁屏代码位于:
frameworks\base\policy\src\com\android\internal\policy\impl\keyguard\
android4.4版本上锁屏代码位于:
frameworks\base\packages\Keyguard\src\com\android\keyguard\
并有单独的apk: /system/priv-app/Keyguard.apk
android4.4版本上缺少的文件是ClockView.java,而多出来的文件有:
KeyguardDisplayManager.java
KeyguardService.java

keyguard的主要对外接口

KeyguardManager.java(.\frameworks\base\core\java\android\app)

比如要在app中不允许锁屏的话,可以添加:

import android.app.KeyguardManager;
private KeyguardManager.KeyguardLock keyguardLock = null;
if(mApplication.getKeyguardManager().isKeyguardLocked()){
keyguardLock =
mApplication.getKeyguardManager().newKeyguardLock(LOG_TAG);
keyguardLock.disableKeyguard();
}
if (keyguardLock != null) {
keyguardLock.reenableKeyguard();
keyguardLock = null;
}

Keyguard锁屏重要类分析

PhoneWindowManagerj.ava
KeyguardServiceDelegate.java
KeyguardServiceWrapper.java
keyguardService.java
KeyguardViewMediator.java
KeyguardViewManager.java
KeyguardHostView.java
KeyguardUpdateMonitor.java

KeyguardServiceDelegate.java
和KeyguardServiceWrapper.java

  • 这两个类是android 4.4新增加的,分别对KeyguardService进行
    了代理和包装,代理类里面有一个Scrim视图在keyguard崩溃时
    显示。包装类就是对keyguardService的简单包装,最终把调度
    都会传给keyguardService。

keyguardService.java

  • 上面一再说到该类,那么它有啥出众的地方呢,其实它就是
    keyguard的入口,锁屏所有的往生都因它而起,这个类很简单,
    实例化了一个IKeyguardService.Stub供其他类bindservice时调
    用,需要特别注意的是整个keyguard的核心实力派
    KeyguardViewMediator在这里诞生了。

KeyguardViewMediator.java

字面上的意思是keyguard视图调度者,功能上是负责处理keyguard视图的事件,比如完成锁
屏和解锁这些动作的视图响应
/* 有关锁屏请求的调度者。包括锁屏状态的查询,power management事件影响锁屏是否应该
被显示或者重置,特定的回调函数来*通知windowmanager锁屏是什么时候显示,以及接受view
视图传过来的消息表明已经成功完成解锁。
*请注意锁屏是在灭屏后立即被调用显示的。这样当你点亮屏幕,锁屏才能第一时间显示出来。
*例如外部事件调度锁屏视图流程:
灭屏动作 –> 重置锁屏并显示它,为下次点亮屏幕做好准备。
键盘弹出来了–> 如果锁屏不是安全的,隐藏之。
*来自于锁屏视图的事件:
用户成功完成解锁 –> 隐藏锁屏视图,不再对输入事件进行拦截。
*注意:除了正常的电源管理事件可以影响锁屏显示与否的状态, 外部的应用或者服务(service)
通过调用setKeyguardEnabled(false),可以实现锁屏的屏蔽。
*线程和同步:
该类是由WindowManagerPolicy创建并运行在它的线程里,锁屏UI也是这个类的构造函数里面产
生。这个apis也可以被其他线程所调用,包括 com.android.server.input.InputManagerService
和android.view.WindowManager的线程.所以,这个类中的方法是同步的,任何直接指向锁屏UI
的操作都会发消息到handle来保证它是在锁屏UI线程里面执行的。
*/

public class KeyguardViewMediator {
 /**
 * This handler will be associated with the policy thread, which will also
 * be the UI thread of the keyguard. Since the apis of the policy, and therefore
 * this class, can be called by other threads, any action that directly
 * interacts with the keyguard ui should be posted to this handler, rather
 * than called directly.
 */
 private Handler mHandler = new Handler(Looper.myLooper(), null, true /*async*/) {
 @Override
 public void handleMessage(Message msg) {
 switch (msg.what) {
 case SHOW:
 handleShow((Bundle) msg.obj);
 break;
 case HIDE:
 handleHide();
 break;

KeyguardViewManager.java

如果说mediator相当于总裁,那这个就是经理,而且是视图
部门老大,它有一个类型为FrameLayout名叫ViewManager的
内部类,用来作为keyguard的viewroot。在viewroot里添加了
KeyguardHostView,我们叫它mKeyguardView。Keyguard里任
何的view细节和问题都能通过它找到蛛丝马迹。

/** * Manages creating, showing, hiding and resetting
the keyguard. Calls back via {@link
KeyguardViewMediator.ViewMediatorCallback} to poke
the wake lock and report that the keyguard is done,
which is in turn, reported to this class by the current
{@link KeyguardViewBase}.
*/
public class KeyguardViewManager {

KeyguardHostView.java

这里完成keyguardView布局,实例化。分析一个自定义的viewgroup,重点需要分析的是它
的构造方法和onFinishInflate()方法:

KeyguardUpdateMonitor.java

监听系统状态值的改变如时间、SIM卡状态、电池电量等,状态值的改变会回调监听了该状
态信息的对象实例。如果只是关注功能的话只需要看handle里面的每个消息调用的方法即可.

/** * Watches for updates that may be interesting to the keyguard, and provides
the up to date information as well as a registration for callbacks that care
to be updated.
 * Note: under time crunch, this has been extended to include some stuff that
 * doesn't really belong here. see {@link #handleBatteryUpdate} where it
shutdowns the device, and {@link #getFailedUnlockAttempts()}, {@link
#reportFailedAttempt()} and {@link #clearFailedUnlockAttempts()}. Maybe we
should rename this 'KeyguardContext'...
 */
public class KeyguardUpdateMonitor {

KeyguardSecurityView.java

此接口定义了各锁屏view最基本的方法

public interface KeyguardSecurityView {

这个接口一共有9+2个实例(其中一个是所有view的容器KeyguardSecurityViewFlipper,另
一个是其中几个view的抽象父类KeyguardAbsKeyInputView),还有其它9个锁屏的基本view.

下面这六个是KeyguardAbsKeyInputView的子类,这些view的特点是都只需要一个可以输入密
码的TextView或EditText:
KeyguardPasswordView–密码解锁
KeyguardPINView–PIN解锁
KeyguardSimPinView
KeyguardSimPukView
KeyguardAccountView–账户解锁
KeyguardFaceUnlockView–人脸解锁
KeyguardPatternView–图案解锁
KeyguardSelectorView–滑动解锁
KeyguardVoiceUnlockView–语音解锁

KeyguardUpdateMonitorCallback.java

由mCallbacks来保存所有的具体观察者角色,可以通过registerCallback
和removeCallback方法来实现具体观察者角色添加和删除。
具体观察者:很多,分布在各个文件中:
CameraWidgetFrame.java
CarrierText.java
EmergencyButton.java
FaceUnlock.java
KeyguardFaceUnlockView.java
KeyguardHostView.java
KeyguardMessageArea.java
KeyguardSelectorView.java
KeyguardStatusView.java
KeyguardTransportControlView.java
KeyguardUpdateMonitor.java
KeyguardViewManager.java
KeyguardViewMediator.java
KeyguardWidgetFrame.java

  • 下面来看通过mHandler处理的其它观察对象吧。
    在这部分中,他们的特点是:当某事件发生时(或某些方法被
    调用时),发送一个消息到mHandler中,mHandler根据what信息
    去调用handleXXX方法。

  • 这些触发向mHandler中发送消息的事件是什么呢?有两类:一
    是KeyguardUpdateMonitor监听到的各种广播事件,二是其它的
    非广播事件。

第一类,广播事件(共11个)

Intent.ACTION_TIME_TICK
Intent.ACTION_TIME_CHANGED
Intent.ACTION_TIMEZONE_CHANGED
MSG_TIME_UPDATE
handleTimeUpdate

TelephonyIntents.SPN_STRINGS_UPDATED_ACTION
MSG_CARRIER_INFO_UPDATE
handleCarrierInfoUpdate
Intent.ACTION_BATTERY_CHANGED
MSG_BATTERY_UPDATE
handleBatteryUpdate
TelephonyIntents.ACTION_SIM_STATE_CHANGED CellConnMgr.ACTION_UNLOCK_SIM_LOCK
MSG_SIM_STATE_CHANGE
handleSimStateChange
AudioManager.RINGER_MODE_CHANGED_ACTION
MSG_RINGER_MODE_CHANGED
handleRingerModeChange
TelephonyManager.ACTION_PHONE_STATE_CHANGED
MSG_PHONE_STATE_CHANGED
handlePhoneStateChanged
DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
MSG_DPM_STATE_CHANGED
handleDevicePolicyManagerStateChanged
Intent.ACTION_USER_REMOVED
MSG_USER_REMOVED
handleUserRemoved
Intent.ACTION_BOOT_COMPLETED
MSG_BOOT_COMPLETED
handleBootCompleted
ACTION_SMARTBOOK_PLUG
MSG_DOCK_STATUS_UPDATE
handleDockStatusUpdate
Intent.ACTION_USER_INFO_CHANGED
MSG_USER_INFO_CHANGED
handleUserInfoChanged

这里写图片描述

解锁的流程

各种锁屏界面都不一样,但是基本都是调用

mCallback.dismiss(true);

在 KeyguardPatternView.java 中,

private class UnlockPatternListener implements
LockPatternView.OnPatternListener {
public void
onPatternDetected(List<LockPatternView.Cell> pattern) {
if (mLockPatternUtils.checkPattern(pattern)) {
mCallback.reportSuccessfulUnlockAttempt();
mLockPatternView.setDisplayMode(LockPatternView.Displa
yMode.Correct);
mCallback.dismiss(true);

在KeyguardSimPukView.java中,

if (result == PhoneConstants.PIN_RESULT_SUCCESS) {
KeyguardUpdateMonitor.getInstance(getContext()).report
SimUnlocked();
mCallback.dismiss(true);
}

如果要永不锁屏,比如车载设备上

将./frameworks/base/packages/SettingsProvider/res/values/defaults.xml中的
def_screen_off_timeout设置为-1;
将KeyguardViewMediator.java中
mExternallyEnabled的初始值设为false;
去掉设置项中的显示超时休眠菜单.

参考
http://blog.csdn.net/wdaming1986/article/details/8991456
http://blog.csdn.net/wdaming1986/article/details/8837023

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值