Android SurfaceFlinger layer层级

壁纸作为显示的最底层窗口它是怎么显示的

1. SurfaceFlinger layer层级

 锁屏状态dump SurfaceFlinger ,adb shell dumpsys SurfaceFlinger

Display 0 (active) HWC layers:
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 Layer name
           Z |  Window Type |  Layer Type |  Comp Type |  Transform |   Disp Frame (LTRB) |          Source Crop (LTRB) |     Frame Rate (Explicit) (Seamlessness) [Focused]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 Wallpaper BBQ wrapper#58
  rel      0 |            0 |            0 |     CLIENT |          0 |    0    0 1080 2408 |    0.0    0.0 1080.0 2408.0 |                                              [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 StatusBar#105
  rel      0 |         2000 |           21 |     CLIENT |          0 |    0    0 1080   76 |    0.0    0.0 1080.0   76.0 |                                              [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 NotificationShade#656
  rel      0 |         2040 |           17 |     CLIENT |          0 |    0    0 1080 2408 |    0.0    0.0 1080.0 2408.0 |                                              [*]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 NavigationBar0#101
  rel      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.cpp

int LayerVector::do_compare(const void* lhs, const void* rhs) const
{
    // sort layers per layer-stack, then by z-order and finally by sequence
    const 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.java

void 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.java
    
default int getMaxWindowLayer() {
        return 36;
}


frameworks/base/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java

private 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.java

void 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.cpp


SurfaceComposerClient::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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SAP Ariba Approval _Email Approval

Email Approval Example 当用户成为文档审批者时,SAP Ariba会向该用户发送电子邮件通知消息。 在以下情况下,批准人可以收到电子邮件通知: 有人提交或重新提交文件以获得批准 某人撤回文件 系统升级文档 系统即将向主管升级请求 如果多个用户共享一个群组职责,他们则会收到…

vue 封装全局方法及使用

1.找到项目中的utils定义js&#xff0c;这个js存放全局可使用的方法 2.去项目中main.js中引入注册 import publicFun from ./utils/test Vue.prototype.$publicFun publicFun;3.项目使用 ddd(){this.$publicFun.testwen()},

MQTT消息服务器mosquitto介绍及说明

Mosquitto是一个开源的消息代理软件&#xff0c;支持MQTT协议&#xff08;消息队列遥测传输协议&#xff09;。MQTT是一种轻量级的发布/订阅消息传输协议&#xff0c;专为低带宽、不可靠网络环境下的物联网设备通信而设计。以下是关于Mosquitto服务器的一些介绍和说明&#xff…

(长期更新)《零基础入门 ArcGIS(ArcMap) 》实验一(下)----空间数据的编辑与处理(超超超详细!!!)

续上篇博客&#xff08;长期更新&#xff09;《零基础入门 ArcGIS(ArcMap) 》实验一&#xff08;上&#xff09;----空间数据的编辑与处理&#xff08;超超超详细&#xff01;&#xff01;&#xff01;&#xff09;-CSDN博客 继续更新 目录 什么是拓扑&#xff1f; 1.3.5道路拓…

深信服ATRUST与锐捷交换机端口链路聚合的配置

深信服ATRUST业务口原来只配置使用一个电口&#xff0c;近期出现流量达到800-900M接近端口的极限带宽。由于设备没有万光口&#xff0c;于是只好用2个光口来配置链接聚合。 下需附上深信服ATRST端口配置的截图&#xff0c;由于深信服ATRUST与锐捷交换机端口只共同支持源mac目的…

简易图书管理系统

javawebjspservlet 实体类 package com.ghx.entity;/*** author &#xff1a;guo* date &#xff1a;Created in 2024/12/6 10:13* description&#xff1a;* modified By&#xff1a;* version:*/ public class Book {private int id;private String name;private double pri…

【1】数据分析基础(一些概念)

数据分析的五步&#xff1a; &#xff08;1&#xff09;提出问题&#xff1b;&#xff08;2&#xff09;收集数据&#xff1b;&#xff08;3&#xff09;数据处理和清洗&#xff1b;&#xff08;4&#xff09;数据分析&#xff1b;&#xff08;5&#xff09;可视化&#xff0c…

Spring Boot 3.0 + MySQL 8.0 + kkFileView 实现完整文件服务

Spring Boot 3.0 MySQL 8.0 kkFileView 实现完整文件服务 背景&#xff1a;比较常见的需求&#xff0c;做成公共的服务&#xff0c;后期维护比较简单&#xff0c;可扩展多个存储介质&#xff0c;上传逻辑简单&#xff0c;上传后提供一个文件id&#xff0c;后期可直接通过此i…

文生图模型开源之光!ComfyUI - AuraFlow本地部署教程

一、模型介绍 AuraFlow 是唯一一个真正开源的文生图模型&#xff0c;由Fal团队开源&#xff0c;其代码和权重都放在了 FOSS 许可证下。基于 6.8B 参数优化模型架构&#xff0c;采用最大更新参数化技术&#xff0c;还重新标注数据集提升指令遵循质量。在物体空间和色彩上有优势…

OpenAI12天 –第3天的实时更新,包括 ChatGPT、Sora、o1 等

OpenAI提前开启了假期&#xff0c;推出了为期 12 天的活动&#xff0c;名为“OpenAI 12 天”。在接下来的一周左右的每一天&#xff0c;OpenAI 都将发布现有产品的新更新以及新软件&#xff0c;包括备受期待的 Sora AI 视频生成器。 OpenAI 首席执行官 Sam Altman 表示&#x…

06_掌握Python列表、元组、字典、集合

学习完本篇内容,你将掌握以下技能: 列表、元组、字典、集合的创建与删除列表、元组、字典、集合的访问及遍历列表、元组、字典、集合的操作方法列表、元组、字典、集合的生成式列表的基本操作 # 列表的基本操作 # 创建列表 list1 = [1, 2,

Ubuntu Server 22.04.5 LTS重启后IP被重置问题

Ubuntu Server 22.04.5 LTS重启后IP被重置问题 最近在使用Ubuntu Server 22.04做项目开发测试时发现每次重启和关机后&#xff0c;所设置的静态IP地址都会回复到安装系统时所设置的ip Ubuntu Server 22.04 官网下载地址&#xff1a;Ubuntu官方下载地址 对虚拟机下安装Ubuntu感…

QtCreator UI界面 菜单栏无法输入中文

如下图红色所示的区域&#xff0c;直接输入是无法输入中文的&#xff1a; 解决方法&#xff1a;在右边的属性值里输入即可 也可以参考这位同学的解决方法&#xff1a;友情链接

SCI论文丨机器学习与深度学习论文

目录 第一章、ChatGPT-4o使用方法与技巧 第二章、ChatGPT-4o辅助文献检索、总结与分析 第三章、ChatGPT-4o辅助学术论文选题、创新点挖掘与实验方案设计 第四章、ChatGPT-4o辅助学术论文开题与大纲生成 第五章、ChatGPT-4o辅助学术论文写作马拉松活动介绍 第六章、ChatGPT…

ES语句——DSL(kibana语句)

一、查询操作 查看当前索引的数据结构 _mapping Get ai-open-log*/_mapping 查询当前索引下的文档数以及分片信息 _count Get ai-open-log*/_count { "count": 12345, //当前索引下的文档总数 "_shards": { //分片信息 "total&…

【sgUploadImage】自定义组件:基于elementUI的el-upload封装的上传图片、相片组件,适用于上传缩略图、文章封面

sgUploadImage源码 <template><div :class"$options.name"><ul class"uploadImages"><liclass"uploadImage"v-loading"loadings[i]"v-for"(a, i) in imgFiles && imgFiles.length ? imgFiles : 1…

NAT traversal 原理 | TCP / UDP/ P2P

注&#xff1a;本文为 “NAT traversal ”相关的几篇文章合辑。 未整理去重。 NAT 穿越技术原理 Li_yy123 于 2020-12-08 18:54:26 发布 一、NAT 由来 为了解决全球公有 IPv4 的稀缺&#xff0c;提出了 NAT 技术。NAT 是 Network Address Translation 网络地址转换的缩写。 …

算法日记(2024.12.09)

1.二叉树的最小深度 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a;叶子节点是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;2 …

js:事件监听

事件监听 事件监听&#xff1a;让程序检测是否有事件产生&#xff0c;一旦有事件触发&#xff0c;就调用一个函数做出响应&#xff0c;也称为绑定事件或注册事件 事件&#xff1a;编程系统内发生的动作或发生的事情 比如用户单击一个按钮下拉菜单 添加事件监听 事件监听三要…

Linux驱动开发(12):中断子系统–按键中断实验

本章我们以按键为例讲解在驱动程序中如何使用中断&#xff0c; 在学习本章之前建议先回顾一下关于中断相关的裸机部分相关章节&#xff0c; 这里主要介绍在驱动中如何使用中断&#xff0c;对于中断的概念及GIC中断控制器相关内容不再进行讲解。 本章配套源码和设备树插件位于“…