Android SurfaceFlinger layer层级
壁纸作为显示的最底层窗口它是怎么显示的
1. SurfaceFlinger layer层级
锁屏状态dump SurfaceFlinger ,adb shell dumpsys SurfaceFlinger
Display 0 (active) HWC layers:
---------------------------------------------------------------------------------------------------------------------------------------------------------------Layer nameZ | Window Type | Layer Type | Comp Type | Transform | Disp Frame (LTRB) | Source Crop (LTRB) | Frame Rate (Explicit) (Seamlessness) [Focused]
---------------------------------------------------------------------------------------------------------------------------------------------------------------Wallpaper BBQ wrapper#58rel 0 | 0 | 0 | CLIENT | 0 | 0 0 1080 2408 | 0.0 0.0 1080.0 2408.0 | [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------StatusBar#105rel 0 | 2000 | 21 | CLIENT | 0 | 0 0 1080 76 | 0.0 0.0 1080.0 76.0 | [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------NotificationShade#656rel 0 | 2040 | 17 | CLIENT | 0 | 0 0 1080 2408 | 0.0 0.0 1080.0 2408.0 | [*]
---------------------------------------------------------------------------------------------------------------------------------------------------------------NavigationBar0#101rel 0 | 2019 | 21 | CLIENT | 0 | 0 2364 1080 2408 | 0.0 0.0 1080.0 44.0 | [ ]
可以看到壁纸layer显示在最底层,其上依次是状态栏layer,锁屏layer,导航栏窗口layer。
void SurfaceFlinger::dumpHwcLayersMinidumpLockedLegacy(std::string& result) const {for (const auto& [token, display] : mDisplays) {const auto displayId = HalDisplayId::tryCast(display->getId());if (!displayId) {continue;}StringAppendF(&result, "Display %s (%s) HWC layers:\n", to_string(*displayId).c_str(),displayId == mActiveDisplayId ? "active" : "inactive");Layer::miniDumpHeader(result);const DisplayDevice& ref = *display;mDrawingState.traverseInZOrder([&](Layer* layer) { layer->miniDumpLegacy(result, ref); });result.append("\n");}
}
mDrawingState是按照Layer.z属性排序的
frameworks/native/services/surfaceflinger/LayerVector.cppint LayerVector::do_compare(const void* lhs, const void* rhs) const
{// sort layers per layer-stack, then by z-order and finally by sequenceconst auto& l = *reinterpret_cast<const sp<Layer>*>(lhs);const auto& r = *reinterpret_cast<const sp<Layer>*>(rhs);const auto& lState = l->getDrawingState();const auto& rState = r->getDrawingState();const auto ls = lState.layerStack;const auto rs = rState.layerStack;if (ls != rs)return (ls > rs) ? 1 : -1;int32_t lz = lState.z;int32_t rz = rState.z;if (lz != rz)return (lz > rz) ? 1 : -1;
}
2. system_server窗口层级
通常我们看到的窗口层级如下
frameworks/base/services/core/java/com/android/server/policy/WindowManagerPolicy.java default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow,boolean roundedCornerOverlay) {// Always put the rounded corner layer to the top most.if (roundedCornerOverlay && canAddInternalSystemWindow) {return getMaxWindowLayer();}if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {return APPLICATION_LAYER;}switch (type) {case TYPE_WALLPAPER:// wallpaper is at the bottom, though the window manager may move it.return 1;
}
/frameworks/base/services/core/java/com/android/server/wm/WindowState.java mBaseLayer = mPolicy.getWindowLayerLw(this)* TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
大概层级
DisplayArea添加到DisplayContent
frameworks/base/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.javavoid instantiateChildren(DisplayArea<DisplayArea> parent, DisplayArea.Tokens[] areaForLayer,int level, Map<Feature, List<DisplayArea<WindowContainer>>> areas) {mChildren.sort(Comparator.comparingInt(pendingArea -> pendingArea.mMinLayer));for (int i = 0; i < mChildren.size(); i++) {final PendingArea child = mChildren.get(i);final DisplayArea area = child.createArea(parent, areaForLayer);if (area == null) {// TaskDisplayArea and ImeContainer can be set at different hierarchy, so it can// be null.continue;}parent.addChild(area, WindowContainer.POSITION_TOP);if (child.mFeature != null) {areas.get(child.mFeature).add(area);}child.instantiateChildren(area, areaForLayer, level + 1, areas);}
}
创建37个layer并添加进displayContent中
frameworks/base/services/core/java/com/android/server/policy/WindowManagerPolicy.javadefault int getMaxWindowLayer() {return 36;
}frameworks/base/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.javaprivate void build(@Nullable List<HierarchyBuilder> displayAreaGroupHierarchyBuilders) {final WindowManagerPolicy policy = mRoot.mWmService.mPolicy;final int maxWindowLayerCount = policy.getMaxWindowLayer() + 1;final DisplayArea.Tokens[] displayAreaForLayer =new DisplayArea.Tokens[maxWindowLayerCount];...root.instantiateChildren(mRoot, displayAreaForLayer, 0, featureAreas);// Notify the root that we have finished attaching all the DisplayAreas. Cache all the// feature related collections there for fast access.mRoot.onHierarchyBuilt(mFeatures, displayAreaForLayer, featureAreas);}
通过assignLayer来设置surfacecontrol的layer属性及(LayerState的z属性)
frameworks/base/services/core/java/com/android/server/wm/WindowContainer.javavoid assignChildLayers(Transaction t) {int layer = 0;// We use two passes as a way to promote children which// need Z-boosting to the end of the list.for (int j = 0; j < mChildren.size(); ++j) {final WindowContainer wc = mChildren.get(j);wc.assignChildLayers(t);if (!wc.needsZBoost()) {wc.assignLayer(t, layer++);}}for (int j = 0; j < mChildren.size(); ++j) {final WindowContainer wc = mChildren.get(j);if (wc.needsZBoost()) {wc.assignLayer(t, layer++);}}if (mOverlayHost != null) {mOverlayHost.setLayer(t, layer++);}}
3. 通过SurfaceComposerClient 传递到SurfaceFlinger ( sf->setTransactionState)
frameworks/native/libs/gui/SurfaceComposerClient.cppSurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer(const sp<SurfaceControl>& sc, int32_t z) {layer_state_t* s = getLayerState(sc);if (!s) {mStatus = BAD_INDEX;return *this;}s->what |= layer_state_t::eLayerChanged;s->what &= ~layer_state_t::eRelativeLayerChanged;s->z = z;registerSurfaceControlForCallback(sc);return *this;
}
相关文章:

Android SurfaceFlinger layer层级
壁纸作为显示的最底层窗口它是怎么显示的 1. SurfaceFlinger layer层级 锁屏状态dump SurfaceFlinger ,adb shell dumpsys SurfaceFlinger Display 0 (active) HWC layers: -----------------------------------------------------------------------------------…...

spark-sql配置教程
1.前期准备 (1)首先要把hadoop集群,hive和spark等配置好 hadoop集群,hive的配置可以看看这个博主写的博客 大数据_蓝净云的博客-CSDN博客 或者看看黑马程序员的视频 黑马程序员大数据入门到实战教程,大数据开发必…...
生成表格pdf格式
1. 添加依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>kernel</artifactId><version>7.2.5</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>layout…...
C++ 游戏开发的前沿趋势:从光线追踪到人工智能的全新挑战
随着游戏行业的快速发展,技术的不断进步为游戏开发带来了前所未有的机遇和挑战。从逼真的光影效果到复杂的物理模拟,再到智能化的非玩家角色(NPC)行为和玩家交互,现代游戏的技术需求已经超越了传统的图形渲染与场景搭建…...

微信小程序3-显标记信息和弹框
感谢阅读,初学小白,有错指正。 一、实现功能: 在地图上添加标记点后,标记点是可以携带以下基础信息的,如标题、id、经纬度等。但是对于开发来说,这些信息还不足够,而且还要做到点击标记点时&a…...

EasyNVR中HTTP-FLV协议无法播放怎么解决?
在科技日新月异的今天,摄像头作为公共安全领域的重要一环,其技术的不断提升正显著地改变着社会的安全格局。从最初的简单监控到如今的高清智能分析,我们可以对特定区域进行实时监控和记录,为社会的安全稳定提供了强有力的保障。 问…...
spring cloud之ribbon复习回顾
其实在项目中直接使用ribbon时不多,大多是使用feign的,其实feign底层也是通过ribbon构建的,主要记忆一下计算规则,ribbon的源码还是很不错的,还是值得学习的。 1、添加pom <dependency><groupId>org.spr…...

RFT 强化微调
OpenAI在今天发布的新技术,RFT结合了SFT和RL的优化算法,与传统的监督微调不同,强化微调旨在通过任务训练让模型掌握复杂推理能力,而不仅仅是“记住答案”。 什么是强化微调 强化微调是通过高质量任务数据和参考答案优化大语言模型…...

SpringBoot教程(三十二) SpringBoot集成Skywalking链路跟踪
SpringBoot教程(三十二) | SpringBoot集成Skywalking链路跟踪 一、Skywalking是什么?二、Skywalking与JDK版本的对应关系三、Skywalking下载四、Skywalking 数据存储五、Skywalking 的启动六、部署探针 前提: Agents 8.9.0 放入 …...
分布式搜索引擎Elasticsearch
Elasticsearch是一个基于Lucene库的开源分布式搜索引擎,它被设计用于云计算中,能够实现快速、near-real-time的搜索,并且可以进行大规模的分布式索引。 以下是一个简单的Python代码示例,展示如何使用Elasticsearch的Python客户端…...
在Vue.js中生成二维码(将指定的url+参数 生成二维码)
在Vue.js中生成二维码,你可以使用JavaScript库如qrcode或qr.js。以下是一个简单的例子,展示如何在Vue组件中使用qrcode库将指定的URL加上参数生成二维码。 首先,你需要安装qrcode库。如果你使用的是npm或yarn,可以通过命令行安装…...

统信桌面专业版部署postgresql-14.2+postgis-3.2方法介绍
文章来源:统信桌面专业版部署postgresql-14.2postgis-3.2方法介绍 | 统信软件-知识分享平台 应用场景 CPU架构:X86(海光C86-3G 3350) OS版本信息:1070桌面专业版 软件信息:postgresql-14.2postgis-3.2 …...

数字图像处理(16):RGB与HSV互转
(1)HSV颜色模型:HSV颜色模型,又称为六角锥体模型,以色调(H)、饱和度(S)、亮度(V)为基础,能够更加自然地表现和处理颜色,因…...

web组态可视化编辑器
随着工业智能制造的发展,工业企业对设备可视化、远程运维的需求日趋强烈,传统的单机版组态软件已经不能满足越来越复杂的控制需求,那么实现web组态可视化界面成为了主要的技术路径。 行业痛点 对于软件服务商来说,将单机版软件转…...

数组 - 八皇后 - 困难
************* C topic: 面试题 08.12. 八皇后 - 力扣(LeetCode) ************* Good morning, gays, Fridary angin and try the hard to celebrate. Inspect the topic: This topic I can understand it in a second. And I do rethink a movie, …...
【分布式】Redis分布式缓存
一、什么是Redis分布式缓存 Redis分布式缓存是指使用Redis作为缓存系统来存储和管理数据的分布式方案。在分布式系统中,多台服务器共同对外提供服务,为了提高系统的性能和可扩展性,通常会引入缓存来减轻数据库的压力。Redis作为一种高性能的…...
Ubuntu——extrepo添加部分外部软件源
extrepo 是一个用于 Ubuntu 和其他基于 Debian 的系统的工具,它的主要作用是简化和管理外部软件源(repositories)的添加和更新。通过使用 extrepo,用户可以方便地添加、删除和管理第三方软件源,而不需要手动编辑源列表…...

评估大语言模型(LLM)在分子预测任务能够理解分子几何形状性能
摘要 论文地址:https://arxiv.org/pdf/2403.05075 近年来,机器学习模型在各个领域越来越受欢迎。学术界和工业界都投入了大量精力来提高机器学习的效率,以期实现人工通用智能(AGI)。其中,大规模语言模型&a…...
如何查看电脑刷新率
Windows 系统 通过显示设置查看: 右键点击桌面空白处,选择 “显示设置”。在打开的窗口中,找到 “高级显示设置”。点击 “显示适配器属性”。在弹出的窗口中,选择 “监视器” 选项卡,即可看到当前的屏幕刷新率。使用 …...
mysql集群MHA方式部署
1. 基本信息 部署机器角色部署路径192.168.242.71MySQL-Mater MHA-NodeMySQL: /alidata1/mysql-8.0.28192.168.242.72MySQL-Slave MHA-NodeMHA-Node: /alidata1/admin/tools/mha4mysql-node-0.58192.168.242.73MySQL-Slave MHA-Node192.168.242.74MHA-ManagerMHA-Manager: …...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...