当前位置: 首页 > news >正文

FW SystemUI Keyguard解析(二)

文章目录

      • CTS之Keyguard Menu事件处理

CTS之Keyguard Menu事件处理

事件触发点:
NotificationShadeWindowViewController.dispatchKeyEvent
设置setInteractionEventHandler回调之后通过NotificationShadeWindowView 触发
调用到return mService.onMenuPressed();

public class NotificationShadeWindowViewController {public void setupExpandedStatusBar() {mView.setInteractionEventHandler(new NotificationShadeWindowView.InteractionEventHandler() {//省略代码@Overridepublic boolean dispatchKeyEvent(KeyEvent event) {boolean down = event.getAction() == KeyEvent.ACTION_DOWN;switch (event.getKeyCode()) {case KeyEvent.KEYCODE_BACK:if (!down) {mService.onBackPressed();}return true;case KeyEvent.KEYCODE_MENU:if (!down) {return mService.onMenuPressed();//☆☆☆☆}break;case KeyEvent.KEYCODE_SPACE:if (!down) {return mService.onSpacePressed();}break;case KeyEvent.KEYCODE_VOLUME_DOWN:case KeyEvent.KEYCODE_VOLUME_UP:if (mStatusBarStateController.isDozing()) {MediaSessionLegacyHelper.getHelper(mView.getContext()).sendVolumeKeyEvent(event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);return true;}break;}return false;}});}
}public class NotificationShadeWindowView extends FrameLayout {@Overridepublic boolean dispatchKeyEvent(KeyEvent event) {if (mInteractionEventHandler.interceptMediaKey(event)) {return true;}if (super.dispatchKeyEvent(event)) {return true;}return mInteractionEventHandler.dispatchKeyEvent(event);//☆☆☆☆}
}

以上通过接口会调用到
StatusBar类中去

public class StatusBar{public boolean onMenuPressed() {if (shouldUnlockOnMenuPressed()) {mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);//☆☆☆☆return true;}return false;}}public class ShadeControllerImpl implements ShadeController {@Overridepublic void animateCollapsePanels(int flags, boolean force) {animateCollapsePanels(flags, force, false /* delayed */, 1.0f /* speedUpFactor */);//☆☆☆☆}@Overridepublic void animateCollapsePanels(int flags, boolean force, boolean delayed,float speedUpFactor) {if (!force && mStatusBarStateController.getState() != StatusBarState.SHADE) {runPostCollapseRunnables();return;}if (SPEW) {Log.d(TAG, "animateCollapse():"+ " mExpandedVisible=" + getStatusBar().isExpandedVisible()+ " flags=" + flags);}if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {getStatusBar().postHideRecentApps();}// TODO(b/62444020): remove when this bug is fixedLog.v(TAG, "NotificationShadeWindow: " + getNotificationShadeWindowView()+ " canPanelBeCollapsed(): "+ getNotificationPanelViewController().canPanelBeCollapsed());if (getNotificationShadeWindowView() != null&& getNotificationPanelViewController().canPanelBeCollapsed()) {// release focus immediately to kick off focus change transitionmNotificationShadeWindowController.setNotificationShadeFocusable(false);getStatusBar().getNotificationShadeWindowViewController().cancelExpandHelper();getStatusBarView().collapsePanel(true /* animate */, delayed, speedUpFactor);//☆☆☆☆} else {mBubbleControllerLazy.get().collapseStack();}}}public abstract class PanelBar extends FrameLayout {public void collapsePanel(boolean animate, boolean delayed, float speedUpFactor) {boolean waiting = false;PanelViewController pv = mPanel;if (animate && !pv.isFullyCollapsed()) {pv.collapse(delayed, speedUpFactor);waiting = true;} else {pv.resetViews(false /* animate */);pv.setExpandedFraction(0); // just in casepv.cancelPeek();}if (DEBUG) LOG("collapsePanel: animate=%s waiting=%s", animate, waiting);if (!waiting && mState != STATE_CLOSED) {// it's possible that nothing animated, so we replicate the termination// conditions of panelExpansionChanged herego(STATE_CLOSED);onPanelCollapsed();//☆☆☆☆}}
}public class PhoneStatusBarView extends PanelBar {private Runnable mHideExpandedRunnable = new Runnable() {@Overridepublic void run() {if (mPanelFraction == 0.0f) {mBar.makeExpandedInvisible();//☆☆☆☆}}};@Overridepublic void onPanelCollapsed() {super.onPanelCollapsed();// Close the status bar in the next frame so we can show the end of the animation.post(mHideExpandedRunnable);//☆☆☆☆mIsFullyOpenedPanel = false;}
}public class StatusBar extends SystemUI {void makeExpandedInvisible() {if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible+ " mExpandedVisible=" + mExpandedVisible);if (!mExpandedVisible || mNotificationShadeWindowView == null) {return;}// Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)mStatusBarView.collapsePanel(/*animate=*/ false, false /* delayed*/,1.0f /* speedUpFactor */);mNotificationPanelViewController.closeQs();mExpandedVisible = false;visibilityChanged(false);// Update the visibility of notification shade and status bar window.mNotificationShadeWindowController.setPanelVisible(false);mStatusBarWindowController.setForceStatusBarVisible(false);// Close any guts that might be visiblemGutsManager.closeAndSaveGuts(true /* removeLeavebehind */, true /* force */,true /* removeControls */, -1 /* x */, -1 /* y */, true /* resetMenu */);mShadeController.runPostCollapseRunnables();setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);if (!mNotificationActivityStarter.isCollapsingToShowActivityOverLockscreen()) {showBouncerIfKeyguard();//☆☆☆☆} else if (DEBUG) {Log.d(TAG, "Not showing bouncer due to activity showing over lockscreen");}mCommandQueue.recomputeDisableFlags(mDisplayId,mNotificationPanelViewController.hideStatusBarIconsWhenExpanded() /* animate */);// Trimming will happen later if Keyguard is showing - doing it here might cause a jank in// the bouncer appear animation.if (!mStatusBarKeyguardViewManager.isShowing()) {WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);}}private void showBouncerIfKeyguard() {if ((mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)&& !mKeyguardViewMediator.isHiding()) {mStatusBarKeyguardViewManager.showBouncer(true /* scrimmed */); //☆☆☆☆}}}public class StatusBarKeyguardViewManager {public void showBouncer(boolean scrimmed) {if (mShowing && !mBouncer.isShowing()) {mBouncer.show(false /* resetSecuritySelection */, scrimmed);//☆☆☆☆}updateStates();}
}public class KeyguardBouncer {private final Runnable mShowRunnable = new Runnable() {@Overridepublic void run() {mRoot.setVisibility(View.VISIBLE);showPromptReason(mBouncerPromptReason);final CharSequence customMessage = mCallback.consumeCustomMessage();if (customMessage != null) {mKeyguardView.showErrorMessage(customMessage);}// We might still be collapsed and the view didn't have time to layout yet or still// be small, let's wait on the predraw to do the animation in that case.if (mKeyguardView.getHeight() != 0 && mKeyguardView.getHeight() != mStatusBarHeight) {mKeyguardView.startAppearAnimation();} else {mKeyguardView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {@Overridepublic boolean onPreDraw() {mKeyguardView.getViewTreeObserver().removeOnPreDrawListener(this);mKeyguardView.startAppearAnimation();//☆☆☆☆return true;}});mKeyguardView.requestLayout();}mShowingSoon = false;if (mExpansion == EXPANSION_VISIBLE) {mKeyguardView.onResume();mKeyguardView.resetSecurityContainer();showPromptReason(mBouncerPromptReason);}SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED,SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN);}};public void show(boolean resetSecuritySelection, boolean isScrimmed) {final int keyguardUserId = KeyguardUpdateMonitor.getCurrentUser();if (keyguardUserId == UserHandle.USER_SYSTEM && UserManager.isSplitSystemUser()) {// In split system user mode, we never unlock system user.return;}ensureView();mIsScrimmed = isScrimmed;// On the keyguard, we want to show the bouncer when the user drags up, but it's// not correct to end the falsing session. We still need to verify if those touches// are valid.// Later, at the end of the animation, when the bouncer is at the top of the screen,// onFullyShown() will be called and FalsingManager will stop recording touches.if (isScrimmed) {setExpansion(EXPANSION_VISIBLE);}if (resetSecuritySelection) {// showPrimarySecurityScreen() updates the current security method. This is needed in// case we are already showing and the current security method changed.showPrimarySecurityScreen();}if (mRoot.getVisibility() == View.VISIBLE || mShowingSoon) {return;}final int activeUserId = KeyguardUpdateMonitor.getCurrentUser();final boolean isSystemUser =UserManager.isSplitSystemUser() && activeUserId == UserHandle.USER_SYSTEM;final boolean allowDismissKeyguard = !isSystemUser && activeUserId == keyguardUserId;// If allowed, try to dismiss the Keyguard. If no security auth (password/pin/pattern) is// set, this will dismiss the whole Keyguard. Otherwise, show the bouncer.if (allowDismissKeyguard && mKeyguardView.dismiss(activeUserId)) {return;}// This condition may indicate an error on Android, so log it.if (!allowDismissKeyguard) {Log.w(TAG, "User can't dismiss keyguard: " + activeUserId + " != " + keyguardUserId);}mShowingSoon = true;// Split up the work over multiple frames.DejankUtils.removeCallbacks(mResetRunnable);if (mKeyguardStateController.isFaceAuthEnabled() && !needsFullscreenBouncer()&& !mKeyguardUpdateMonitor.userNeedsStrongAuth()&& !mKeyguardBypassController.getBypassEnabled()) {mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY);//☆☆☆☆} else {DejankUtils.postAfterTraversal(mShowRunnable);//☆☆☆☆}mCallback.onBouncerVisiblityChanged(true /* shown */);mExpansionCallback.onStartingToShow();}
}public class KeyguardHostView extends FrameLayout implements SecurityCallback {public void startAppearAnimation() {mSecurityContainer.startAppearAnimation();//☆☆☆☆}
}public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSecurityView {public void startAppearAnimation() {if (mCurrentSecuritySelection != SecurityMode.None) {getSecurityView(mCurrentSecuritySelection).startAppearAnimation();//☆☆☆☆}}
}public class KeyguardPINView extends KeyguardPinBasedInputView {@Overridepublic void startAppearAnimation() {enableClipping(false);setAlpha(1f);//☆☆☆☆setTranslationY(mAppearAnimationUtils.getStartTranslation());AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 500 /* duration */,0, mAppearAnimationUtils.getInterpolator());mAppearAnimationUtils.startAnimation2d(mViews,new Runnable() {@Overridepublic void run() {enableClipping(true);}});}}

相关文章:

FW SystemUI Keyguard解析(二)

文章目录 CTS之Keyguard Menu事件处理 CTS之Keyguard Menu事件处理 事件触发点: NotificationShadeWindowViewController.dispatchKeyEvent 设置setInteractionEventHandler回调之后通过NotificationShadeWindowView 触发 调用到return mService.onMenuPressed(); public cla…...

MySQL之备份与恢复(二)

备份与恢复 定义恢复需求 如果一切正常,那么永远也不需要考虑恢复。但是,一旦需要恢复,只有世界上最好的备份系统是没用的,还需要一个强大的恢复系统。 不幸的是,让备份系统平滑工作比构造良好的恢复过程和工具更容易…...

MySQL:保护数据库

保护数据库 1. 用户1.1 创建用户1.2 查看用户1.3 删除用户1.4 修改密码 2. 权限2.1 授予权限2.2 查看权限2.3 撤销权限 之前都是介绍本地数据库而你自己就是数据库的唯一用户,所以不必考虑安全问题。但实际业务中数据库大多放在服务器里,你必须妥善处理好…...

不是大厂云用不起,而是五洛云更有性价比

明月代维的一个客户的大厂云境外云服务器再有几天就到期了,续费提醒那是提前一周准时到来,但是看到客户发来的续费价格截图,我是真的没忍住。这不就是在杀熟吗?就这配置续费竟然如此昂贵?说实话这个客户的服务器代维是…...

C++初学者指南-3.自定义类型(第一部分)-异常

C初学者指南-3.自定义类型(第一部分)-异常 文章目录 C初学者指南-3.自定义类型(第一部分)-异常简介什么是异常?第一个示例用途:报告违反规则的行为异常的替代方案标准库异常处理 问题和保证资源泄露使用 RAII 避免内存泄漏!析构函数:不要让异…...

学会python——用python编写一个电子时钟(python实例十七)

目录 1.认识Python 2.环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3.电子时钟程序 3.1 代码构思 3.2代码实例 3.3运行结果 4.总结 1.认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性…...

elementui中@click短时间内多次触发,@click重复点击,做不允许重复点击处理

click快速点击&#xff0c;发生多次触发 2.代码示例&#xff1a; //html<el-button :loading"submitLoading" type"primary" click"submitForm">确 定</el-button>data() {return {submitLoading:false,}}//方法/** 提交按钮 */sub…...

助力游戏实现应用内运营闭环,融云游戏社交方案升级!

通信能力在所有应用场景都是必备组件&#xff0c;这源于社交属性带给应用的增长神话。 在游戏场景&#xff0c;玩家从少数核心向大众用户泛化扩展的过程&#xff0c;就是游戏深度融合社交能力的过程。 从单机到联机&#xff0c;游戏乐趣的升级 1996 年&#xff0c;游戏界顶流…...

守护创新之魂:源代码防泄漏的终极策略

在信息化快速发展的今天&#xff0c;企业的核心机密数据&#xff0c;尤其是源代码&#xff0c;成为了企业竞争力的关键所在。然而&#xff0c;源代码的泄露风险也随之增加&#xff0c;给企业的安全和发展带来了巨大威胁。在这样的背景下&#xff0c;SDC沙盒作为一种创新的源代码…...

Halcon 基于分水岭的目标分割

一 分水岭 1 分水岭介绍 传统的分水岭分割方法&#xff0c;是一种基于拓扑理论的数学形态学的分割方法&#xff0c;其基本思想是把图像看作是地质学上的拓扑地貌&#xff0c;图像中每一像素的灰度值表示该点的海拔高度&#xff0c;每一个局部极小值及其周边区域称为集水盆地&…...

PHP 面向对象编程(OOP)入门指南

面向对象编程&#xff08;Object-Oriented Programming&#xff0c;简称OOP&#xff09;是一种编程范式&#xff0c;通过使用对象来设计和组织代码。PHP作为一种广泛使用的服务器端脚本语言&#xff0c;支持面向对象编程。本文将介绍PHP面向对象编程的基本概念和用法&#xff0…...

Django学习第三天

python manage.py runserver 使用以上的命令启动项目 实现新建用户数据功能 views.py文件代码 from django.shortcuts import render, redirect from app01 import models# Create your views here. def depart_list(request):""" 部门列表 ""&qu…...

Vue3实现点击按钮实现文字变色

1.动态样式实现 1.1核心代码解释&#xff1a; class"power-station-perspective-item-text"&#xff1a; 为这个 span 元素添加了一个 CSS 类&#xff0c;以便对其样式进行定义。 click"clickItem(item.id)"&#xff1a; 这是一个 Vue 事件绑定。当用户点…...

深入理解Vue生命周期钩子函数

深入理解Vue生命周期钩子函数 Vue.js 是一款流行的前端框架&#xff0c;通过其强大的响应式数据绑定和组件化的开发方式&#xff0c;使得前端开发变得更加简单和高效。在Vue应用中&#xff0c;每个组件都有其生命周期&#xff0c;这些生命周期钩子函数允许开发者在不同阶段执行…...

Linux-gdb

目录 1.-g 生成含有debug信息的可执行文件 2.gdb开始以及gdb中的常用执行指令 3.断点的本质用法 4.快速跳出函数体 5.其他 1.-g 生成含有debug信息的可执行文件 2.gdb开始以及gdb中的常用执行指令 3.断点的本质用法 断点的本质是帮助我们缩小出问题的范围 比如&#xff0c;…...

Oracle分析表和索引(analyze)

分析表 analyze table tablename compute statistics; 分析索引 analyze index indexname compute statistics; 该语句生成的统计信息会更新user_tables这个视图的统计信息,分析的结果被Oracle用于基于成本的优化生成更好的查询计划 对于使用CBO(Cost-Base Optimization)很有好…...

MyBatis踩坑记录-多表关联字段相同,字段数据覆盖问题

MyBatis踩坑记录-多表关联字段相同&#xff0c;字段数据覆盖问题 1. 背景描述2. 实体记录3. 错误映射3.1 造成的影响 4. 解决办法4.1 修改映射文件 5. 修复后的效果5.1 返回的数据5.2 正确展示 7. end ~ 1. 背景描述 现有一下业务&#xff0c;单个任务下可能会有多个子任务&am…...

昇思25天学习打卡营第6天|数据变换 Transforms

学习目标&#xff1a;熟练掌握数据变换操作 熟悉mindspore.dataset.transforms接口 实践掌握常用变换 昇思大模型平台学习心得记录&#xff1a; 一、关于mindspore.dataset.transforms 1.1 变换 mindspore.dataset.transforms.Compose将多个数据增强操作组合使用。 mindspo…...

在线JSON可视化工具--改进

先前发布了JSON格式化可视化在线工具&#xff0c;提供图形化界面显示结构关系功能&#xff0c;并提供JSON快速格式化、JSON压缩、快捷复制、下载导出、对存在语法错误的地方能明确显示&#xff0c;而且还支持全屏&#xff0c;极大扩大视野区域。 在线JSON格式化可视化工具 但…...

探讨命令模式及其应用

目录 命令模式命令模式结构命令模式适用场景命令模式优缺点练手题目题目描述输入描述输出描述题解 命令模式 命令模式是一种行为设计模式&#xff0c; 它可将请求转换为一个包含与请求相关的所有信息的独立对象。 该转换让你能根据不同的请求将方法参数化、 延迟请求执行或将其…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...