一般情况下,SystemUI启动完成之后,进入的第一个界面为锁屏界面;
锁屏keyguard属于SystemUI,keyguard大致分为两个部分:
- keyguard模块的启动;
- WMS处理锁屏显示流程;
keyguard
keyguard模块中,存在几个核心的类:
- KeyguardViewMediator:继承SystemUI,是keyguard的核心类,是交互的中转类,其他对象都是通过KeyguardViewMediator对象相互交互;
- KeyguardUpdateMonitor:状态回调的管理类;
- KeyguardBouncer:锁屏view的通信交互类;
- KeyguardService:用于跨进程交互;
KeyguardViewMediator
SystemUI 启动
在SystemUI启动的过程中,SystemUIApplication中对config配置文件中解析出来的SystemUI组件进行反射创建实例,其中就包含了KeyguardViewMediator组件;
创建好KeyguardViewMediator实例后,调用该组件的start方法进行初始化操作,在该过程中,创建了KeyguardDisplayManager实例,用于后续锁屏界面显示逻辑的处理;
WakeLock:唤醒锁,用于点亮屏幕;
开机首次锁屏显示
SystemUI启动完成之后,会直接调用WMS的onSystemUiStarted方法,通知WMS SystemUI已经初始化完成,WMS可以开始bind锁屏服务,开始准备后续需要使用到的锁屏服务;
当WMS bind成功KeyguardService之后,在后续的逻辑中会执行WMS的一些逻辑,当WMS模块的初始化和关联逻辑执行完成之后,会调用WMS的systemReady方法代表WMS已经准备就绪;
在这个过程中,会调用KeyguardService的onSystemReady,而在KeyguardViewMediator中,所有的任务都是通过Handler的信息执行的,通过sendMessage发送对应的消息 ,该过程对应的Message = SYSTEM_READY;
息屏 & 亮屏 锁屏
参考:息屏与亮屏;
锁屏逻辑
无论是开机首次显示锁屏,还是后续的息屏亮屏显示锁屏,其对应的锁屏逻辑都是一样的;
在doKeyguardLocked方法中,大致执行了两个逻辑:
-
判断当前的系统环境是否支持锁屏服务或者是锁屏功能;
- 判断是否有其他app阻止锁屏界面显示,例如通话功能;
- 判断是否已经处于锁屏界面;
- 判断设置配置或者SIM卡配置是否支持锁屏界面;
-
执行锁屏逻辑;
上述判断的阻止锁屏界面显示的条件都不满足的话,就会执行到showLocked方法,在这个方法中,就是真正执行锁屏逻辑的过程;
禁止锁屏方法
所有的禁止锁屏的方案,其本质上都是通过在doKeyguardLocked方法中中断后续显示锁屏界面的逻辑实现的。实现方案可以分为:
- 自定义中断条件;
- 使用Android原生的中断条件;
关闭锁屏服务 + 禁止doKeyguardLocked
SystemUIApplication#onCreate()
scss
if (!getResources().getBoolean(R.bool.config_enableKeyguard)) {
Log.v(TAG, "SystemUI disable Keyguard.");
new android.os.Handler().post(new Runnable() {
@Override
public void run() {
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock keyguardLock = km.newKeyguardLock(TAG);
keyguardLock.disableKeyguard();
}
});
}
config_car.xml
xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="config_enableKeyguard">false</bool>
</resources>
KeyguardViewMediator#dokeyguardLocked
arduino
private void doKeyguardLocked(Bundle options) {
if (!mContext.getResources().getBoolean(R.bool.config_enableKeyguard)) {
Log.d(TAG, "doKeyguard: disable Keyguard.");
return;
}
......
}
移除Keyguard组件 + 禁用KeyguardService + 禁止doKeyguardLocked
config_car.xml
xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="config_enableKeyguard">false</bool>
<!-- The list of components to exclude from config_systemUIServiceComponents. -->
<string-array name="config_systemUIServiceComponentsExclude" translatable="false">
<item>com.android.systemui.keyguard.KeyguardViewMediator</item>
</string-array>
</resources>
KeyguardService
arduino
private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
/**
* 所有的方法都空实现
*
*/
}
KeyguardViewMediator#dokeyguardLocked
arduino
private void doKeyguardLocked(Bundle options) {
if (!mContext.getResources().getBoolean(R.bool.config_enableKeyguard)) {
Log.d(TAG, "doKeyguard: disable Keyguard.");
return;
}
......
}
LockPatternUtils禁用锁屏 + 禁用KeyguardService
这个方案是在模拟器上面使用的方案,这个值会被设置到SQLite数据库中进行保存;
KeyguardViewMediator#setupLocked
scss
private void setupLocked() {
setLockScreenDisabled(mContext.getResources().getBoolean(R.bool.config_disableKeyguard));
..................
}
private void setLockScreenDisabled(boolean disable) {
if (disable) {
if (DEBUG) Log.d(TAG, "setLockScreenDisabled: not showing because lockscreen is off");
mLockPatternUtils.setLockScreenDisabled(disable, 0);
}
}
config_car.xml
xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="config_disableKeyguard">true</bool>
</resources>
config.xml
xml
<!-- Whether to enable KeyguardService or not -->
<bool name="config_enableKeyguardService">false</bool>