Android 锁屏界面启动流程

本文基于Android 7.1
在开机过程中,Systemserver 会启动 WindowManagerService,并调用其systemReady 方法。进而调用PhoneWindowManager的systemReady方法

@Overridepublic void systemReady() {mKeyguardDelegate = new KeyguardServiceDelegate(mContext,this::onKeyguardShowingStateChanged);mKeyguardDelegate.onSystemReady();boolean bindKeyguardNow;synchronized (mLock) {mSystemReady = true;bindKeyguardNow = mDeferBindKeyguard;Slog.d(TAG,"bindKeyguardNow:"+bindKeyguardNow);}if (bindKeyguardNow) {mKeyguardDelegate.bindService(mContext);mKeyguardDelegate.onBootCompleted();}}

首先初始化 KeyguardServiceDelegate 对象,并调用其 onSystemReady 方法。

public void onSystemReady() {Slog.d(TAG"mKeyguardService:"+mKeyguardService);if (mKeyguardService != null) {mKeyguardService.onSystemReady();} else {mKeyguardState.systemIsReady = true;}}

值得注意的是:

  • PhoneWindowManager的 systemReady 方法中 ,bindKeyguardNow为false,所以并不会在这里 bindService
  • KeyguardServiceDelegate 的 onSystemReady 方法中,mKeyguardService还是为null ,所以在改方法中只是将 mKeyguardState.systemIsReady 变量置为true
WindowManager: bindKeyguardNow:false
KeyguardServiceDelegate:mKeyguardService:null

真正bindService 的地方在 PhoneWindowManager 中的 systemBooted 方法。

@Overridepublic void systemBooted() {Log.d(TAG,"systemBooted:",new Exception());boolean bindKeyguardNow = false;synchronized (mLock) {if (mKeyguardDelegate != null) {bindKeyguardNow = true;} else {mDeferBindKeyguard = true;}}if (bindKeyguardNow) {//绑定服务mKeyguardDelegate.bindService(mContext);mKeyguardDelegate.onBootCompleted();}synchronized (mLock) {mSystemBooted = true;}......}

在前面已经初始化了mKeyguardDelegate对象,所以这里不为null,bindKeyguardNow为true,调用 KeyguardServiceDelegate 的 bindService 方法去绑定服务

public void bindService(Context context) {Intent intent = new Intent();final Resources resources = context.getApplicationContext().getResources();final ComponentName keyguardComponent = ComponentName.unflattenFromString(resources.getString(com.android.internal.R.string.config_keyguardComponent));intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);intent.setComponent(keyguardComponent);if (!context.bindServiceAsUser(intent, mKeyguardConnection,Context.BIND_AUTO_CREATE, mScrimHandler, UserHandle.SYSTEM)) {......} ......}

这里 keyguardComponent 为 com.android.systemui/com.android.systemui.keyguard.KeyguardService

<!-- Keyguard component --><string name="config_keyguardComponent" translatable="false">com.android.systemui/com.android.systemui.keyguard.KeyguardService</string>

该服务在 SystemUI中

<serviceandroid:name=".keyguard.KeyguardService"android:exported="true"android:enabled="@bool/config_enableKeyguardService" />

注意这里可以配置enable,不启动KeyguardService,即配置 config_enableKeyguardService 决定是否永远禁止锁屏界面.
绑定成功的话,会调用 mKeyguardConnection 的onServiceConnected 方法

private final ServiceConnection mKeyguardConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)");mKeyguardService = new KeyguardServiceWrapper(mContext,IKeyguardService.Stub.asInterface(service), mShowingStateChangedCallback);if (mKeyguardState.systemIsReady) {// If the system is ready, it means keyguard crashed and restarted.mKeyguardService.onSystemReady();......}};

前面已经将 mKeyguardState.systemIsReady 置为true 了,所以这里会调用 KeyguardServiceWrapper 的 onSystemReady方法, 最终 调用KeyguardViewMediator 的 onSystemReady 方法

public void onSystemReady() {synchronized (this) {if (DEBUG) Log.d(TAG, "onSystemReady");mSystemReady = true;doKeyguardLocked(null);mUpdateMonitor.registerCallback(mUpdateCallback);}......}

在 doKeyguardLocked 方法中,经过一系列的判断,决定是否需要显示锁屏界面,如果需要显示,则调用showLocked 方法去显示锁屏界面。值得注意的是,这里 读取了 数据库中 lockscreen.disabled 字符串的值,来决定是否显示锁屏界面。而该值可以通过 def_lockscreen_disabled 来配置。即可以通过 配置 def_lockscreen_disabled 的值,来决定是否出厂默认禁止锁屏界面(该方法是LockPatternUtils的 isLockScreenDisabled,感兴趣的话自行分析)。

private void showLocked(Bundle options) {Trace.beginSection("KeyguardViewMediator#showLocked aqcuiring mShowKeyguardWakeLock");if (DEBUG) Log.d(TAG, "showLocked");// ensure we stay awake until we are finished displaying the keyguardmShowKeyguardWakeLock.acquire();Message msg = mHandler.obtainMessage(SHOW, options);mHandler.sendMessage(msg);Trace.endSection();}private Handler mHandler = new Handler(Looper.myLooper(), null, true /*async*/) {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case SHOW:handleShow((Bundle) msg.obj);break;

在 handleShow 中 调用StatusBarKeyguardViewManager 的show 方法

public void show(Bundle options) {mShowing = true;mStatusBarWindowManager.setKeyguardShowing(true);mScrimController.abortKeyguardFadingOut();reset();}public void reset() {if (mShowing) {if (mOccluded) {......} else {showBouncerOrKeyguard();}......}}protected void showBouncerOrKeyguard() {if (mBouncer.needsFullscreenBouncer()) {......} else {......mBouncer.prepare();}}

调用 KeyguardBouncer 的 prepare 方法

public void prepare() {boolean wasInitialized = mRoot != null;ensureView();if (wasInitialized) {mKeyguardView.showPrimarySecurityScreen();}mBouncerPromptReason = mCallback.getBouncerPromptReason();}

最终调用打 KeyguardSecurityContainer 的 showPrimarySecurityScreen 方法 ,先得到 锁屏的模式,然后去显示锁屏界面

void showPrimarySecurityScreen(boolean turningOff) {SecurityMode securityMode = mSecurityModel.getSecurityMode();if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");showSecurityScreen(securityMode);//显示锁屏界面}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/767569.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win10开启了hyper-v,docker 启动还是报错 docker desktop windows hypervisor is not present

问题 在安装了docker windows版本后启动 docker报错docker desktop windows hypervisor is not present 解决措施 首先确认windows功能是否打开Hyper-v 勾选后重启&#xff0c;再次启动 启动后仍报这个错误&#xff0c;是Hyper-v没有设置成功 使用cmd禁用再启用 一.禁用h…

Activiti7学习大纲及环境-Activiti7从入门到专家(2)

学习大纲 入门系列 开发环境及源码编译流程设计器核心API简单流程示例启动与结束事件边界事件中间事件用户任务手动任务接受任务服务任务脚本任务业务规则任务排他网关并行网关包容网关事件网关子流程调用活动泳池泳道执行监听器任务监听器全局监听器真实业务流程 进阶系列 …

基于react native的自定义轮播图

基于react native的自定义轮播图 效果示例图示例代码 效果示例图 示例代码 import React, {useEffect, useRef, useState} from react; import {Animated,PanResponder,StyleSheet,Text,View,Dimensions, } from react-native; import {pxToPd} from ../../common/js/device;c…

蓝桥集训之子矩阵

蓝桥集训之子矩阵 核心思想&#xff1a;二维单调队列 先求每一行中列长为B的区间的最值再在最值数组中求行长为A的区间的最值 –> 区间最值最后遍历所有最大最小值相乘的结果 #include <iostream>#include <cstring>#include <algorithm>using namespa…

序列化与反序列化介绍

文章目录 一、序列化与反序列化二、PHP反序列化漏洞成因三、JAVA反序列化 一、序列化与反序列化 在PHP语言开发层面上基本都是围绕着serialize()&#xff0c;unserialize()这两个函数。serialize()函数序列化对象后&#xff0c;可以很方便的将它传递给其他需要它的地方&#x…

java 设计模式 深入理解

在学习设计模式的时候&#xff0c;以前学习了下总以为理解了&#xff0c;但是在实际工作中基本上用不起来。在学习拆书后&#xff0c;想到用讲的方式去学习和思考的时候&#xff0c;要想讲清楚&#xff0c;就要深入理解其中的原理。在重新整理和写下来的过程中&#xff0c;感觉…

蓝桥杯刷题--python-28-并查集

528. 奶酪 - AcWing题库 T=int(input()) def union(p,i,j): p1=parent(p,i) p2=parent(p,j) p[p1]=p2 def parent(p,i): root=i while p[root]!=root: root=p[root] while p[i]!=i: x=i;i=p[i];p[x]=root return root class Node:…

存储器的层次结构和局部性原理

前言 大家好我是jiantaoyab&#xff0c;这是我所总结作为学习的笔记第19篇&#xff0c;在这里分享给大家&#xff0c;这篇文章讲存储器的一部分内容。 存储器的层次结构 SRAM 静态随机存取存储器的芯片&#xff0c;SRAM 之所以被称为“静态”存储器&#xff0c;是因为只要处…

设计模式 之 策略模式

策略模式是一种定义一系列算法的方法&#xff0c;以相同的方式调用不同的算法&#xff0c;减少了各种算法类与使用算法类之间的耦合。 它的重心不是如何实现算法&#xff0c;而是如何组织&#xff0c;调用这些算法。从而让程序结构更灵活&#xff0c;具有更好的维护性和扩展性…

用Springboot(java程序)访问Salesforce RestAPI

本文讲一下&#xff0c;如何从0构建一个Springboot的应用程序&#xff0c;并且和Salesforce系统集成&#xff0c;取得Salesforce里面的数据。 一、先在Salesforce上构建一个ConnectApp。 有了这个&#xff0c;SF才允许你和它集成。手顺如下&#xff1a; 保存后&#xff0c;…

云计算系统管理(ADMIN)

01. 公司需要将/opt/bjcat3目录下的所有文档打包备份&#xff0c;如何实现&#xff1f; 答案&#xff1a; # tar -czf /tmp/bjcat3.tar.gz /opt/bjcat302. 简述创建crontab计划任务的流程 答案&#xff1a; 利用crontab –e -u 用户名 进入计划任务编辑模式 分 时 日 月 周 …

揭秘.dataru勒索病毒,远离数据被锁的威胁

导言&#xff1a; 在网络安全领域&#xff0c;勒索病毒已成为一个日益严重的威胁。其中&#xff0c;.dataru勒索病毒以其独特的加密技术和狡猾的传播方式&#xff0c;让许多企业和个人遭受了巨大的损失。本文将深入剖析.dataru勒索病毒的特点、传播方式&#xff0c;并提出有效…

Android kotlin全局悬浮窗全屏功能和锁屏页面全屏悬浮窗功能二

1.前言 在进行app应用开发中,在实现某些功能中要求实现悬浮窗功能,分为应用内悬浮窗 ,全局悬浮窗和 锁屏页面悬浮窗功能 等,接下来就来实现这些悬浮窗全屏功能,首选看下第二部分功能实现 2.kotlin实现锁屏页面悬浮窗全屏功能二分析 悬浮窗是属于Android系统的一种浮动窗…

dddssss

import cv2 from cvzone.PoseModule import PoseDetectorif __name__ __main__:# cap cv2.VideoCapture(2.mp4)cap cv2.VideoCapture(0)detector PoseDetector()posList []while True:success, img cap.read()img detector.findPose(img)# 获取33个点的每一帧放到lmList…

web渗透测试漏洞流程:目标域名CDN绕过

1.2.1 判断域名是否存在CDN 首先,要验证一个域名是否正在使用CDN服务,我们可以借助在线工具如ChinaZ的Ping服务(http://ping.chinaz.com/)来进行测试。当通过该工具查询到的IP地址不止一个时,这通常意味着显示的IP列表并非直接指向实际服务器的唯一真实IP。比如,若结果显…

jenkins配置源码管理的git地址时,怎么使用不了 credential凭证信息

前提 Jenkins使用docker部署 问题 &#xff08;在jenlins中设置凭证的方式&#xff09;在Jenkins的任务重配置Git地址&#xff0c;并且设置了git凭证,但是验证不通过&#xff0c;报错; 无法连接仓库&#xff1a;Command "git ls-remote -h -- http://192.1XX.0.98:X02/…

Compose UI 之 Checkbox 复选框 RadioButton 单选框

Checkbox 复选框 & RadioButton 单选框 Checkbox 复选框提供了在多个选项中选择一个或多个选项的作用。 RadioButton 单选框提供了在多个选项中只能选择一个选项的作用。 下面就分别来介绍下 Android Compose UI 库中的 Checkbox 复选框 和 RadioButton 单选框。 Radio…

C语言中的运算符优先级详解与使用示例

以下是C语言中运算符优先级的&#xff0c;以及对每个运算符的详细解释&#xff1a; 优先级运算符类别运算符描述1后缀() 函数调用 ( 数组下标 )函数调用、数组元素访问. 结构体成员访问 -> 结构体指针成员访问访问结构体的成员 后缀自增 -- 后缀自减自增或自减操作&#xf…

模拟实现字符串库函数(一)

在C语言的标准库中提供了很多针对字符串的库函数&#xff0c;这篇文章我们会学习并模拟实现几个简单的库函数 求字符串长度函数strlen strlen函数我们在之前已经用过很多次了&#xff0c;同时也模拟实现过&#xff0c;但是都不是模仿标准库中的strlen来实现&#xff0c;首先我…

IOS苹果开发者账号封号的规避心得,利用好防关联工具避免APP下架问题

大家好我是咕噜美乐蒂&#xff0c;很高兴又和大家见面了&#xff01; 当涉及到避免 iOS 苹果开发者账号封号以及利用防关联工具来规避应用下架问题时&#xff0c;有一些具体的操作和注意事项可以帮助你更好地管理你的开发者账号和应用。 避免账号封号的规避心得&#xff1a; …