安卓VirtualDisplay虚拟屏幕如何实现没有内容显示mirror屏幕内容

发布于:2024-06-11 ⋅ 阅读:(67) ⋅ 点赞:(0)

背景:

在录屏或者投屏创建VirtualDisplay时候经常会用到一个flag属性:

在这里插入图片描述简单说这个VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR功能就是在自己屏幕没有内容时候,会把另一个屏幕的内容进行镜像显示。即看到的如下状态:

在这里插入图片描述

上图既可以很好展示出这个虚拟屏幕的镜像功能,就是把主屏幕内容都复制一遍进行显示,即虚拟屏幕看到内容都和主屏幕内容一模一样,这个也就是录屏投屏必须会设置的VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR。

但VirtualDisplay也是可以进行自己内容的独立显示,比如可以把Activity单独搞到这Display上显示:
在这里插入图片描述

那么问题来了,请问系统是怎么做到的在有内容时候就不显示mirror主屏幕内容,没有内容就就只显示mirror内容呢?

原理调研方法步骤:

这里有了以前sf课程的知识基础,肯定知道一般各个layer要是显示在Display上,说明就是这个layer可以被Display包含,主要就是如下参数:
dumpsys SurfaceFlinger命令输出如下:

看看display的层级数据
在这里插入图片描述
同时在看看对应的每个layer也有对应的图层索引数据:
在这里插入图片描述
二者可以匹配那么就代表layer可以在这Display进行显示

看看镜像模式和自己内容显示时候,对于这个Display的layerStack有啥差异

显示自己内容时候如下:
在这里插入图片描述
显示镜像时候如下:
在这里插入图片描述
明显可以看到这里时候得layerStack居然变成0。

所以这里就可以有一个非常重要线索,那就是在VirtualDisplay没有显示内容和有显示内容时候会涉及一个layerStack的变化,这layerStack变化是不是可以通过打印啥的来抓取一下是哪里触发的这个layerStack的变化呢?所以下面就需要在相关变化layerStack的地方加入堆栈打印来追踪

堆栈追踪

这里上层一旦有Task移入VirtualDisplay,就会导致相关的layerStack进行变化,这里一般的最后触发到SurfaceFlinger体现了,说明会通过SurfaceControl相关方法。
在这里插入图片描述
加入相关堆栈后,操作把Task移入虚拟屏幕和移出虚拟屏幕看看打印情况如下:

移入Activity到Display:
在这里插入图片描述
移出:
在这里插入图片描述
看一看到确实有对这个layerStack进行修改在Task进行移入和移出时候

核心源码分析

核心源码经过追踪最后发现如下部分是核心:

在这里插入图片描述
首先通过判断是否有FLAG_OWN_CONTENT_ONLY,我们是VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR所以自然这地方的ownContent是false

    
 final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0;

所以核心会进入如下这个判断
在这里插入图片描述
这里的display.hasContentLocked标志就是返回当前Display是否有内容,如果没内容,那么就会吧dispkay变化成 device.getDisplayIdToMirrorLocked即这个displaydevice虚拟mirror的Display
在这里插入图片描述

而上面的hasContentLocked其实本质也是在通过遍历DisplayContent下面有没有可以显示Window决定的。
在这里插入图片描述

总结

VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR设置

1、会在DisplayContent的mApplySurfaceChangesTransaction中对Display是否有内容进行确定

2、一旦涉及了Display的上有内容到无内容的变化会调用setDisplayLayerStack来重新设置layerStack

3、在sf中layer会对layerStack进行匹配然后决定显示哪个Display

本文章更多详细代码和资料需要购买课程获取
hal+perfetto+surfaceflinger
https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
在这里插入图片描述

私聊作者+v(androidframework007)

其他课程七件套专题:在这里插入图片描述
点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

视频试看:
https://www.bilibili.com/video/BV1wc41117L4/