Android焦点之FocusWindow切换流程

关键调用是setInputWindows

InputDispatcher::dispatchFocusLocked:在这里打印日志"Focus entering" 或 "Focus leaving"

SurfaceFlinger::updateInputFlingernotifyWindowInfos();mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, mInputWindowCommands.syncInputWindows);
@frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpplistener->onWindowInfosChanged(windowInfos, shouldSync ? mWindowInfosReportedListener : nullptr);setInputWindows(handlesPerDisplay);InputDispatcher::setInputWindowsLocked// 对每一个windowInfo进行判断和处理//更新mWindowHandlesByDisplay这个map,然后通过getWindowHandlesLocked()找newFocusedWindowHandleupdateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);std::vector<sp<WindowInfoHandle>> newHandles;newHandles.push_back(handle);mWindowHandlesByDisplay[displayId] = newHandles;const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);auto it = mWindowHandlesByDisplay.find(displayId);return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
@frameworks/native/services/inputflinger/dispatcher/FocusResolver.cpp        // 对FocusChanges进行处理,同步给FocusResolver来更新窗口状态std::optional<FocusResolver::FocusChanges> changes = mFocusResolver.setInputWindows(displayId, windowHandles);//当窗口属性更改时,将调用“setInputWindows”。这里我们将检查当前聚焦的窗口是否可以保持聚焦//如果当前聚焦的窗口仍然有资格获得焦点(“isTokenFocusable”返回 OK),那么我们将继续授予它焦点const sp<IBinder> currentFocus = getFocusedWindowToken(displayId); // 获取当前的焦点窗口const std::optional<FocusRequest> request = getFocusRequest(displayId); //请求焦点,WMS把focusRequest发给surfaceFlinger,surfaceFlinger传递到这里。// 根据最新的 FocusRequest 查找下一个焦点令牌。如果请求的焦点窗口无法获得焦点,则焦点将被移除。if (request) {const Focusability result = isTokenFocusable(requestedFocus, windows);// 遍历InputDispatcher中保存的所有窗口信息for (const sp<WindowInfoHandle>& window : windows) {if (window->getToken() != token) { continue; } // 一直走这个分支的话,就是找不到目标窗口windowFound = true;if (window->getInfo()->visible) { visibleWindowFound = true;  } // 窗口可见的if (!window->getInfo()->focusable) { allWindowsAreFocusable = false; } //窗口就是不能获取焦点// 根据前面的遍历查找结果设置焦点窗口状态if (!windowFound) { return Focusability::NO_WINDOW;  }if (!allWindowsAreFocusable) { return Focusability::NOT_FOCUSABLE; }if (!visibleWindowFound) { return Focusability::NOT_VISIBLE; }return Focusability::OK;  // 仅当窗口可以聚焦时才okif (result == Focusability::OK) { //只有获取的状态为ok// 如果可以获取焦点,则更新焦点窗口return updateFocusedWindow(displayId, "Window became focusable. Previous reason: " + NamedEnum::string(previousResult), requestedFocus, request->windowName);// 无法获取焦点,则焦点为空return updateFocusedWindow(displayId, removeFocusReason, nullptr);if (changes) {  onFocusChangedLocked(*changes); }        //Focus entering 5e40cef org.mozilla.firefox/org.mozilla.fenix.HomeActivity (server), reason=Window became focusable. Previous reason: NOT_VISIBLE enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
@frameworks/native/services/inputflinger/InputManager.cpp                            for (const auto& focusRequest : mInputWindowCommands.focusRequests) { mInputFlinger->setFocusedWindow(focusRequest); }/* 将焦点设置到由标记标识的窗口。必须在更新任何输入窗口句柄后调用此函数。Params:*  request.token - 输入通道令牌用于标识应该获得焦点的窗口*  request.focusedToken - 调用者期望当前关注的令牌。如果指定的令牌与当前聚焦的窗口不匹配,则该请求将被丢弃。*                      如果指定的焦点标记与当前焦点窗口匹配,则调用将成功。如果无论当前聚焦的令牌是什么,此调用都应该成功,则将其设置为“null”*  request.timestamp - 请求焦点更改时客户端 (wm) 设置的 SYSTEM_TIME_MONOTONIC 时间戳(以纳秒为单位)。如果存在来自另一个源(例如指针向下)的焦点更改请求,这将确定哪个请求优先。*/mDispatcher->setFocusedWindow(request);
@frameworks/native/services/inputflinger/dispatcher/FocusResolver.cpp//当窗口属性更改时,将调用“setInputWindows”。这里我们将检查当前聚焦的窗口是否可以保持聚焦//如果当前聚焦的窗口仍然有资格获得焦点(“isTokenFocusable”返回 OK),那么我们将继续授予它焦点,否则我们将检查先前的焦点请求是否有资格获得焦点。std::optional<FocusResolver::FocusChanges> changes = mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));const sp<IBinder> currentFocus = getFocusedWindowToken(displayId);  // 获取当前的焦点窗口mFocusRequestByDisplay[displayId] = request;  //赋值mFocusRequestByDisplayif (changes) { onFocusChangedLocked(*changes); }  //Focus leaving 9fd3baa org.mozilla.firefox/org.mozilla.fenix.HomeActivity (server), reason=Waiting for window because NO_WINDOWif (changes.newFocus) { enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason); }//该事件应该位于队列的前面,但位于所有其他焦点事件之后,找到最后一个焦点事件,并在其后面插入mInboundQueue队列std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =  std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(), [](const std::shared_ptr<EventEntry>& event) { return event->type == EventEntry::Type::FOCUS; });// 维护焦点事件的顺序。在所有其他焦点事件之后插入条目mInboundQueue.insert(it.base(), std::move(focusEntry));InputDispatcher::dispatchOncedispatchOnceInnerLocked(&nextWakeupTime);mPendingEvent = mInboundQueue.front();case EventEntry::Type::FOCUS: {//关键log"Focus entering" 或 "Focus leaving" 打印地方dispatchFocusLocked(currentTime, typedEntry);std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") + channel->getName();std::string reason = std::string("reason=").append(entry->reason);android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;dispatchEventLocked(currentTime, entry, {target});

 

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

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

相关文章

深度学习落地实战:识别火车票信息

前言 大家好,我是机长 本专栏将持续收集整理市场上深度学习的相关项目,旨在为准备从事深度学习工作或相关科研活动的伙伴,储备、提升更多的实际开发经验,每个项目实例都可作为实际开发项目写入简历,且都附带完整的代码与数据集。可通过百度云盘进行获取,实现开箱即用 …

高阶面试-hw算法整理

坚持最近一个星期把每道题搞熟悉 文章目录 1154一年中的第几天[125. 验证回文串](https://leetcode.cn/problems/valid-palindrome/)[344. 反转字符串](https://leetcode.cn/problems/reverse-string/)[20. 有效的括号](https://leetcode.cn/problems/valid-parentheses/)[392.…

【Java】详解抽象类和接口的区别

一、抽象类和接口的主要区别表格 特性抽象类接口声明关键字abstractinterface声明访问修饰符public、protected、default&#xff08;不能用private&#xff09;public、default继承关键字extendsimplements变量跟普通类一样&#xff0c;可以包含实例变量、静态变量等 只能包含…

excel表怎么增乱序单词表 和正序单词表四六级要来了?!Excel帮你构建自己的单词库

excel表怎么增乱序单词表 和正序单词表四六级要来了&#xff1f;&#xff01;Excel帮你构建自己的单词库 1.背单词的第一步&#xff0c;当然是先上网找电子版的单词集。 盘搜搜 2. 建立 xls 格式的表格 3. 把下载的单词数据 复制到 表格 粘贴 4.新建一列 辅助列 生成随机数来…

murmurhash3算法的go语言实现

MurmurHash的定义 MurmurHash 是一种非加密型哈希函数&#xff0c;适用于一般的哈希检索操作。由Austin Appleby在2008年发明&#xff0c;并出现了多个变种&#xff0c;都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比&#xff0c;对于规律性较强的key&…

网络编程-TCP/IP

网络概述 网络采用分而治之的方法设计&#xff0c;将网络的功能划分为不同的模块&#xff0c;以分层的形式有机组合在一起。 每层实现不同的功能&#xff0c;其内部实现方法对外部其他层次来说是透明的。每层向上层提供服务&#xff0c;同时使用下层提供的服务 网络体系结构…

SpringMVC注解全解析:构建高效Web应用的终极指南 (上)

SpringMVC 是一个强大的 Web 框架&#xff0c;广泛应用于 Java Web 开发中。它通过注解简化了配置&#xff0c;增强了代码的可读性。本文将全面解析 SpringMVC 中常用的注解及其用法&#xff0c;帮助你构建高效的 Web 应用。 一. MVC介绍 MVC 是 Model View Controller 的缩写…

数字通云平台 智慧政务OA PayslipUser SQL注入漏洞复现

0x01 产品简介 数字通云平台智慧政务OA产品是基于云计算、大数据、人工智能等先进技术,为政府部门量身定制的智能化办公系统。该系统旨在提高政府部门的办公效率、协同能力和信息资源共享水平,推动电子政务向更高层次发展。 0x02 漏洞概述 数字通云平台 智慧政务OA Paysli…

在vue2中引入一个js文件, 在模版中不能使用js中的变量解决

在 Vue 2 中&#xff0c;如果你引入一个 JavaScript 文件&#xff0c;并希望在模板中使用该文件中的变量&#xff0c;通常有几个常见的问题和解决方法&#xff1a; 1. 作用域问题 在 Vue 模板中&#xff0c;只能访问到 Vue 实例中的数据和方法&#xff0c;而无法直接访问外部…

使用百度语音技术实现文字转语音

使用百度语音技术实现文字转语音 SpringBootVue前后端分离项目 调用api接口需要使用AK和SK生成AccessToken,生成getAccessToken的接口有跨域限制,所以统一的由后端处理了 部分参数在控制台->语音技术->在线调试里面能找到 Controller RestController RequestMapping(&q…

差分进化(Differential Evolution)算法

一、差分进化&#xff08;Differential Evolution&#xff09;算法的起源 差分进化算法&#xff08;DE&#xff09;是一种基于群体的进化算法&#xff0c;由Rainer Storn和Kenneth Price在1995年提出。它是一种全局优化算法&#xff0c;适用于处理多种优化问题&#xff0c;包括…

PostgreSQL的引号、数据类型转换和数据类型

一、单引号和双引号&#xff08;重要&#xff09;&#xff1a; 1、在mysql没啥区别 2、在pgsql中&#xff0c;实际字符串用单引号&#xff0c;双引号相当于mysql的,用来包含关键字&#xff1b; -- 单引号&#xff0c;表示user_name的字符串实际值 insert into t_user(user_nam…

浏览器跨tab页面通信方式总结

需求&#xff1a; 浏览器不同 tab 标签页之间是独立的&#xff0c; 如果要通信必须通过特殊手段来实现跨标签页通信。 1.StorageEvent 事件 当一个标签页 localStorage 变化时&#xff08;sessionStorage 无效&#xff09;&#xff0c;同源下另一个或其他所有标签页使用 DO…

python多级表头汇总

需求&#xff1a;将图一的数据展示为图二样式 图一&#xff1a; 图二&#xff1a; 图一具体的Excel截图 图二具体样式 python解决办法&#xff1a; # 导入 pandas 库&#xff0c;用于数据处理 import pandas as pd# 加载 Excel 文件 file_path 多级表头读取实例.xl…

科研绘图系列:R语言circos图(circos plot)

介绍 Circos图是一种数据可视化工具,它以圆形布局展示数据,通常用于显示数据之间的关系和模式。这种图表特别适合于展示分层数据或网络关系。Circos图的一些关键特点包括: 圆形布局:数据被组织在一个或多个同心圆中,每个圆可以代表不同的数据维度或层次。扇区:每个圆被划…

【BUG】已解决:SyntaxError invalid syntax

SyntaxError invalid syntax 目录 SyntaxError invalid syntax 【常见模块错误】 错误原因&#xff1a; 解决办法&#xff1a; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于…

C?C++?

c和C的区别主要是&#xff1a; 1、语言使用难度不同C难度大于C#大于C语言。 2、面向的对象不同C 语言是面向过程的&#xff0c;而 C 是面向对象的&#xff0c;C# 是一种完全面向对象的语言。 3、函数形式不同C 语言有标准的函数库&#xff0c;它们松散的&#xff0c;只是把功能…

图书馆定位导航:RFID、VR与AR技术在图书馆中的应用

图书馆作为知识的宝库&#xff0c;承载着无数求知者的梦想与期待&#xff0c;随着馆藏书籍数量的激增与图书馆布局的日益复杂&#xff0c;读者在寻找目标书籍往往有许多困难。传统的索引号查询方式虽能提供书籍的基本信息&#xff0c;但在寻找过程中&#xff0c;因不熟悉图书馆…

【Android】使用视图绑定ViewBinding来代替findViewById

文章目录 介绍作用用法开启ViewBinding功能自动生成绑定类在Activity中使用访问视图控件 区别 介绍 ViewBinding 是 Android 开发中的一个功能&#xff0c;它简化了访问视图的过程&#xff0c;避免了使用 findViewById 的繁琐步骤。它通过生成与布局文件相对应的绑定类&#xf…

CentOS 7 安装Jenkins2.346.1(war方式安装)

既然想要安装Jenkins&#xff0c;肯定是先要从官网解读所需环境配置信息&#xff0c;如需了解更多自行查阅 https://www.jenkins.io/doc/book/installing/linux/ JDK17&#xff0c;Maven3.9 安装 先从官网分别下载JDK17与Maven3.9 下载好之后上传至服务器、并解压&#xff1a…