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

Android 系统服务DisplayManagerService和DisplayDevice生命周期解读

一、引言

    DisplayManagerService(以下简称DMS)是 Android 系统中用于管理显示设备的核心服务。Android 早期版本中显示管理主要由SurfaceFlinger和WindowManagerService(以下简称WMS)处理 ,DMS只负责管理基本的显示设备和加载相关配置。Android 4.2中引入了多用户支持功能,每个用户可以拥有独立的显示配置,并且支持多个显示设备(如HDMI外接显示器)。到了Android 6中为了方便开发者调试,增加了对虚拟屏和投屏的支持。Android 7和Android 8增加了对分屏与多窗口的支持,DMS负责管理这些小窗口的显示和交互。Android 10中引入了对折叠屏设备的支持,这类设备可以在展开和折叠之间切换,DMS需要处理这些显示形态的变化,将物理屏映射到正确的逻辑显示。Android 13增加了对Ultra HDR资源的显示,使得Android设备能够更好地处理和显示高动态范围内容,DMS负责一些HDR提亮逻辑和策略。

二、DMS详细剖析

1.DMS在显示系统中作用

(1)检测、添加和移除显示设备:监听并检测新显示设备的连接,例如插入新屏幕时可自动识别和适配。

(2)创建和管理逻辑显示:通过抽象出逻辑显示,DMS提供了一个灵活的中间层用来管理一个或多个物理显示设备。

(3)调整显示设备参数:调整显示设备的各种参数,比如屏幕状态、亮度、分辨率、刷新率、显示方向,显示区域等。

(4)管理多显示设备状态切换:多显示设备的连接、断开及切换需要根据当前连接的物理显示设备切换对应的逻辑显示。    

(5)事件通知:当显示设备状态变化时(连接、断开、状态变化、配置改变等),及时通知系统的其他组件如 WMS和应用程序。

2.关键组件

a7dad5cd13ac2e0de076f2618ea34d6f.png

图1 DMS中的关键组件UML类图

    在DMS模块中,对显示屏幕的描述分为物理显示屏(physical display)和逻辑显示屏(logical display),物理屏主要从SurfaceFlinger中读取参数创建,代表实实在在的物理屏,描述其物理特性,不同物理屏有不同的属性。逻辑屏则是相对于对物理屏,侧重于同一个物理屏的不同逻辑设置,受应用和WMS模块影响,如显示区域、显示位置坐标、显示方向等。每一个物理屏幕都对应一个逻辑屏幕,而一个逻辑屏幕可以对应一个或者多个物理屏幕(多屏设备当中)。因此我们可以通过修改逻辑屏幕参数,做到同一个物理屏的不同显示方式。下面我们就来看下DMS中主要类的作用:                           

●DisplayManagerService:包括显示设备管理的主要类和方法,是显示管理的核心。

●DisplayManagerInternal:为系统其他组件提供的内部API。

●DisplayManager:为app等其他上层组件提供的外部API,内部通过DisplayManagerGlobal和DisplayManagerService进行交互。

●DisplayManagerGlobal:单例,DisplayManager中方法的具体实现,最终通过binder调用到DMS。    

●DisplayDevice:表示具体的物理显示设备(physical display),它包含了与物理显示相关的具体信息。

●DisplayDeviceRepository:管理所有的DisplayDevice,监听所有物理屏的变化。

●LogicalDisplay:上层抽象出来的逻辑显示,负责管理一个或多个物理显示设备,LogicalDisplay提供了一个灵活的中间层,使得系统可以统一处理多个物理设备并动态调整显示配置,并为上层应用和系统服务提供一致的接口。这种架构设计大大简化了显示管理的复杂性,提高了系统的灵活性和可扩展性。

●LogicalDisplayMapper:负责管理所有的LogicalDisplay,并在多屏设备中负责物理显示和逻辑限制之间的映射。

●DisplayAdapter:屏幕适配器,由于不同的物理显示屏有不同的属性和处理方式,因此DMS中通过一系列的屏幕适配器来和分别对各种物理显示屏进行连接。

●DisplayPowerController:管理显示设备的状态和亮度。

3.DMS的启动流程    

1ea58b44c2bff50714b49206988c82f8.png

图2 DMS启动关键流程

    在Android系统中SystemServer进程负责DisplayManagerService的启动,SystemServiceManager 在startService中将调用DisplayManagerService的构造方法创建对象,并调用其onStart方法启动服务。

5f8e87ac5ac98e7c4d0695431964a972.png

    在构造方法中DisplayManagerService会创建UI handle 和display handle,用于处理display事件。以及实例化两个重要的对象mDisplayDeviceRepo和mLogicalDisplayMapper ,mDisplayDeviceRepo管理所有的物理显示屏,而mLogicalDisplayMapper 中管理了所有的逻辑显示。另外在构造函数中还会加载一些默认配置,原生亮度曲线、色彩模式等。    

d16ea97d543f2b7715700a83d1083d8c.png

    在onStart方法中DisplayManagerService会实现binder service接口和local service接口,用于外部通信,并注册显示器监听并尝试通过SurfaceControl连接默认显示器。

5a160add20d249833a2eee3aa0be517d.png

    在DisplayManagerService 启动完成后,SystemServer会通知所有的services当前处于PHASE_WAIT_FOR_DEFAULT_DISPLAY阶段,DisplayManagerService 收到这一通知后,会尝试在LogicalDisplayMapper中获取默认display对应的逻辑显示和虚拟显示器适配器。如果都获取不到则使用同步锁的 wait 方法使当前线程等待指定的时间 delay,如果delay时间后还获取不到则会抛出运行时异常,确保了在系统启动过程中,默认显示器和虚拟显示器适配器能够正确初始化。    

2b2dabb2ac81dab52af748680f5b418d.png

    SystemServer在WMS和IMS启动完成后会通知DMS获取相关服务,并请求WMS进行窗口刷新,确保UI得到更新和正确显示。    

907950ba9c9c8ec107ac728e1903e645.png

    SystemServer在启动完所有系统服务后会调用DMS的systemReady方法,完成一些初始化的设置,如更新用户的HDR设置,注册显示模式变化的回调,注册sensor等。

05fcce8757badf6733c469053c379dc8.png

三、DisplayDevice生命周期管理

    对 DisplayDevice(显示设备) 的生命周期进行管理是DMS的核心任务,包括设备的添加、移除、配置及状态变更等。以下总结了核心的管理流程:    

1.DisplayDevice的检测

    在上一节中我们可以看到DMS在启动过程中会创建对应的显示适配器、检测显示设备以及注册显示设备监听。从SurfaceFlinger获取到默认显示设备后,显示适配器会创建对应的DisplayDevice对象,用于记录和管理显示设备的物理属性,并向DisplayDeviceRepository 发送DISPLAY_DEVICE_EVENT_ADDED消息。

8e0f15f0d854a993e188985bc9fa38b3.png

2.DisplayDevice的添加

    DisplayDeviceRepository 在收到DISPLAY_DEVICE_EVENT_ADDED消息后只是将DisplayDevice加到list当中,然后继续通知LogicalDisplayMapper处理设备添加的流程。LogicalDisplayMapper会通过createNewLogicalDisplayLocked为DisplayDevice创建对应的逻辑显示器(Logical Display),并加载默认的布局文件。    

cad7f8a4bcfc146cfb5ebc90d2e582f9.png

    在createNewLogicalDisplayLocked方法中,首先通过displayID获取到对应的layerStack。在DMS和SurfaceFlinger中layerStack是一个重要的概念,主要用于管理不同显示设备上显示内容的层级和排布,每个 layerStack 代表一个逻辑显示层的集合,这些层在一起构成了屏幕的显示内容。另外,在支持多显示设备的时,layerStack 可用于区分和管理各个显示设备的内容,不同的显示设备可以分配不同的 layerStack,从而管理各自的显示内容独立性。通过配置 layerStack,可以动态调整显示内容的布局和组合,适应各种显示需求。接下来,创建新的LogicalDisplay并与displayID、layerStack和DisplayDevice绑定。    

2e576085536c52185fadee444a6573af.png

    LogicalDisplay创建完成后,LogicalDisplayMapper会通过updateLogicalDisplaysLocked按顺序通知DMS两次,分别是LOGICAL_DISPLAY_EVENT_CONNECTED和LOGICAL_DISPLAY_EVENT_ADDED。DMS收到消息后会对LogicalDisplay进行的一些初始化工作,例如创建用于显示设备状态管理的DisplayPowerController对象更新屏幕状态和亮度、加载和配置屏幕的色彩模式、配置屏幕的分辨率和刷新率等等。    

ee8f95421acd05a0063b3c34f86c08b3.png

    在完成默认显示器的初始化后DMS还需要需要唤醒所有被sycnroot大锁阻塞的线程,并通知所有listener,显示设备已添加。

83886069f691b9b3b90f540231ee62fd.png

3.DisplayDevice的更新    

    DisplayDevice的更新主要有以下几个原因:屏幕状态变化、hdr亮度与sdr亮度的比值发生变化、刷新率和分辨率发生变化、色彩模式发生变化等。 

1625b4291fe0339b1cec72ff07d60de3.png

    这些display 属性发生变化时LocalDisplayAdapter会清空当前的DisplayDeviceInfo,并向上通知LogicalDisplayMapper 更新LogicalDisplay。

7dfb3325e59e0a99d4b7e183159a8a24.png

    LogicalDisplayMapper收到一次更新通知后会对当前所有的LogicalDisplay进行遍历,并更新DisplayDeviceInfo,同时根据diff和前后info的差异识别特定的事件(如hdr亮度与sdr亮度的比值发生变化、刷新率和分辨率发生变化、折叠屏导致的物理显示和逻辑显示的swap等),最后按特定的顺序发送到DMS,再由DMS通知到所有的listener。    

1fc9d642a9725a9f1acc19cd9a15a2c5.png

    DMS在收到LOGICAL_DISPLAY_EVENT_CHANGED事件后会先通过异步消息通知IMS更新viewport,以及通知所有listener中非cache的进程(cache进程需要等到变成非cache才会通知)display已经发生了改变。最后请求WMS重新刷新窗口,确保UI的正常显示。至此,整个DisplayDevice的更新流程就算完成了。    

39bf62ca01aab1e0441f4b52a2ab35eb.png

4.DisplayDevice的移除

在DMS的启动过程中我们已经注册了显示设备的监听,在收到移除事件后,LocalDisplayAdapter会通过tryDisconnectDisplayLocked移除相应的DisplayDevice,然后通过LogicalDisplayMapper向DMS发送LOGICAL_DISPLAY_EVENT_REMOVED和LOGICAL_DISPLAY_EVENT_DISCONNECTED消息销毁对象。这里的流程与设备添加的流程基本一致,只是动作正好相反,就不展开赘述了。

698f419f4434c9ba77ca632fb28a677a.png

四、总结

    DMS 在 Android 显示系统中扮演着至关重要的角色, 与 SurfaceFlinger、WMS、IMS、AMS、PMS等系统组件紧密协作,确保显示系统整体功能完备,在各种场景下能够提供稳定、高质量、流畅的显示体验。    

7d23f9c3b552407b82979b8b932f5139.jpeg

WebRTC音视频同步原理与实现详解(上)

WebRTC音视频同步原理与实现详解(下)

走进音频:器件与效果篇

2fac85a1231dfcf1fb05a7aa860efbb2.gif


http://www.kler.cn/a/468548.html

相关文章:

  • Eureka原理
  • 【LC】2469. 温度转换
  • 【Java数据结构】二叉树
  • 通过爬虫方式实现视频号助手发布视频
  • Linux运维相关基础知识(二)
  • Qt 5.14.2 学习记录 —— 일 新项目
  • Redis数据库笔记——ZSet的底层实现(跳表)
  • 密码学原理技术-第十四章-Key Management
  • 力扣-20-有效的括号-栈
  • Qt笔记:网络编程Tcp
  • 自闭症儿童康复个案研究:深度解析治疗效果
  • C/C++中new/delete与malloc/free的区别及对象管理
  • Hello 2025
  • 《机器学习》从入门到实战——决策树
  • 记录一次电脑被入侵用来挖矿的过程(Trojan、Miner、Hack、turminoob)
  • 算法13、基础二分查找的应用(木根切割等)
  • kubernetes-循序渐进了解coredns
  • 打造三甲医院人工智能矩阵新引擎(二):医学影像大模型篇--“火眼金睛”TransUNet
  • Spring Boot教程之四十九:Spring Boot – MongoRepository 示例
  • 【数据结构与算法:二、线性表】
  • Zookeeper模式安装Kafka(含常规、容器两种安装方式)
  • SpringBoot的6种API请求参数读取方式
  • 【C++】P1428 小鱼比可爱
  • Unity开发2d游戏全套教程[入门案例]
  • 0-基于蚁群优化和带注意力机制的循环神经网络的新型混合算法用于解决旅行商问题(HAL science)(完)
  • 【数据结构与算法:五、树和二叉树】