第十七篇 --ANDROID DisplayManager 服务解析一

ANDROID从版本4.2开始提供了一个显示管理服务DisplayManagerService,支持多种显示类型的多个显示器的镜像显示,包括内建的显示类型(本地)、HDMI显示类型以及支持WIFI Display 协议( MIRACAST),实现本地设备在远程显示器上的镜像显示。

整个架构类图如下:

显示管理服务通过DisplayManager提供对外接口,提供的接口包括如下几个:

1 、public Display getDisplay(int displayId)

根据displayId参数获得一个逻辑显示器的信息

2、  public Display[] getDisplays()

获得当前所有有效的逻辑显示器列表

3、public void registerDisplayListener(DisplayListener listener, Handler handler)

登记一个显示监听对象,用来监听显示器的新增、去除或改变通知事件。

4、public void unregisterDisplayListener(DisplayListener listener)

取消先前登记的一个显示监听对象

5、scanWifiDisplays()

启动WIFI显示器的扫描。

6、    public void connectWifiDisplay(String deviceAddress)

根据设备地址连接WIFI显示器

7、public void disconnectWifiDisplay()

断开WIFI显示器

8、    public void renameWifiDisplay(String deviceAddress, String alias)

为WIFI显示器命名

9、public void forgetWifiDisplay(String deviceAddress)

取消先前记忆的WIFI显示器

10、public WifiDisplayStatus getWifiDisplayStatus()

得到当前的WIFI显示器的状态

显示管理系统还与其它系统交互,实现WIFI显示器的发现、WIFI显示器在窗口系统中的登记、窗口内容在WIFI显示器的显示(源端镜像数据的获取、加密、编码,SINK端接收的镜像数据的解码和播放等)等功能。

通过WifiP2pManager接口与WifiP2pService交互,通过WIFI-DIRECT来实现WIFI显示器的自动发现。

窗口管理服务是显示管理服务的监听对象,窗口管理服务通过DisplayManager接口向DisplayManagerService进行登记,当WIFI显示器被发现和连接成功后以及WIFI显示器断开和状态改变后,都会通过回调向窗口管理服务发送事件,窗口管理服务的相应回调函数onDisplayAdded、onDisplayChanged、onDisplayRemoved被调用,用来在窗口系统中进行WIFI显示器的登记以及取消登记、状态改变等处理。

另外DisplayManagerService服务还通过WindowManagerFuncs窗口管理功能接口直接调用窗口管理服务(WindowManagerService是该接口的实现)的函数,实现窗口内容的刷新。同样DisplayManagerService服务还通过InputManagerFuncs接口直接调用输入管理服务的函数setDisplayViewports,用来设置输入系统需要的显示器的显示视图信息。

显示管理系统还通过IMediaPlayerService接口与MediaPlayerService服务交互。

如调用MediaPlayerService服务的listenForRemoteDisplay函数,用来在媒体服务中实例化一个远端显示器的本地代理对象RemoteDisplay,显示系统通过IRemoteDisplay接口调用媒体服务,目前IRemoteDisplay接口只有dispose一个接口函数,用来断开远端显示器,停止监听新的连接。

显示管理系统的WifiDisplaySource对象还调用MediaPlayerService服务的makeHDCP函数来实例化一个HDCP对象并返回给显示系统一个IHDCP接口,用来实现HDCP加密服务。

显示系统的SINK端的TunnelRenderer对象在其initPlayer中还调用MediaPlayerService服务的create函数来创建一个MediaPlayer对象,并返回一个IMediaPlayer接口给显示系统使用,用来实现SINK端接收的镜像数据的播放。

显示管理系统源端获取的镜像数据经过音视频编码(H264),然后进行HDCP加密和PES packetization及TS流化(转换为TS流)后 ,最后打包成RTP包经过UDP通道发送到SINK端,SINK端要经过相反的处理过程,从UDP通道接收RTP包,然后进行TS解析和PES去packetization化和HDCP解密,最后送给解码器进行解码。解码后的数据送给播放器的呈现器进行呈现。

源端和SINK端的音视频编解码都通过IOMX接口与底层的多媒体框架交互,实现音视频编解码功能。IOMX接口对应的对象OMX也是在MediaPlayerService服务端实例化的,在客户端对象OMXClient的connect函数中通过调用MediaPlayerService服务的getOMX函数返回OMX对应的IOMX接口。OMX对象是对多媒体框架OPENOMX的封装。

源端的音视频编码、TS流化、HDCP加密、RTP打包发送的流程都有PlaybackSession线程类管理和调度,PlaybackSession类初始化时实例化一个SurfaceMediaSource对象,SurfaceMediaSource对象内部实例化一个BufferQueue对象(BufferQueue从ISurfaceTexure中派生)。在与SINK端建立连接后,通过IRemoteDisplayClient接口的回调函数onDisplayConnected把BufferQueue对象传给JAVA层,JAVA层的WifiDisplayAdapter对象收到onDisplayConnected事件后调用Surface类的createDisplay函数在SurfaceFlinger服务中登记一个虚拟显示器,并调用Surface类的setDisplaySurface函数把BufferQueue传给SurfaceFlinger服务虚拟显示器对应的DisplayDeviceState变量中.。因此PlaybackSession可以使用BufferQueue对象从SurfaceFlinger服务读取要镜像的数据。

SINK端WifiDisplaySink对象接收的数据经RTP解码(由RTPSink对象负责)后,送给TunnelRenderer对象进进行呈现, TunnelRenderer对象在initPlayer函数中实例化一个PlayerClient播放客户端,并通过IMediaPlayerService接口调用MediaPlayerService服务的create函数创建一个MediaPlayer对象并返回TunnelRenderer对象IMediaPlayer接口, TunnelRenderer对象使用IMediaPlayer接口对接收到的镜像数据进行播放和呈现, TunnelRenderer对象还在initPlayer函数中通过SurfaceComposerClient对象实例化和获得一个Surface对象,并调用其getSurfaceTexture函数获得Surface对象对应的ISurfaceTexture,并调用IMediaPlayer接口的setVideoSurfaceTexture函数把ISurfaceTexture赋值给播放器,从而实现播放器解码后的显示数据送给SurfaceFlinger显示服务进行显示.

SINK端的WifiDisplaySink对象和源端WifiDisplaySource的对象负责WIFI Display 交互协议的处理,两个对象都包含一个ANetworkSession对象负责两者之间的网络交互会话过程。

如下是WIFI Display 协议的框架图。

ANDROID4.2的开源代码提供了WIFI Display 协议的具体实现,但对SINK端只是作为一个本地测试命令来执行,并且没有提供图中的用户输入功能,而对于WFD Source端则提供了完整的实现代码,这主要是ANDROID系统主要是作为手机平板操作系统使用的缘故。

ANDROID4.2的WIFIDisplay的实现包括JAVA部分和C++部分。JAVA部分的功能主要对应DisplayManagerService服务,DisplayManagerService服务对于WIFIDisplay实例化和登记一个WifiDisplayAdapter对象(派生自DisplayAdapter),用来与对应的显示设备建立连接,每个DisplayAdapter与一个显示设备DisplayDevice类一一对应 。每个显示设备在DisplayManagerService服务中 对应一个LogicalDisplay对象。

DisplayManager发起的对WIFI Display的请求都由DisplayManagerService服务转发给WifiDisplayAdapter对象处理,为了实现异步交互和避免死锁,WifiDisplayAdapter对象对于每个请求都启动一个线程来实际完成请求处理,并实例化一个WifiDisplayController对象来封装这些请求的调用。WifiDisplayAdapter对象内部也实例化一个WifiDisplayController.Listener对象用来监听请求的状态。 WifiDisplayController对象内部实例化一个WifiP2pManager对象用来通过其接口向WifiP2pService服务发起WI-FI DIRECT请求。在与WIFI Display连接时通过实例化一个RemoteDisplay 对象来启动监听底层WIFI Display的连接事件。

C++ 部分位于媒体框架层,处于libstagefright目录的wifi-display目录下,wifi-display目录包含两个sink和source两个子目录(分别对应wifi display的sink和source 对应的程序),wifi-display目录还包含source和SINK公用的程序。

主要包含如下文件:

Sink目录主要包含WifiDisplaySink.cpp、RTPSink.cpp、TunnelRenderer.cpp等C++类文件和相应的头文件,分别负责SINK端的协议协议,RTP接收和镜像数据的呈现过程。而TS解析和PES去packetization化及解码过程都有播放器NuPlayer完成,由于Sink端只是一个测试例程,因此暂没有提供HDCP解码流程。

Source目录主要包括WifiDisplaySource.cpp、PlaybackSession.cpp、MediaPuller.cpp、Converter.cpp、TSPacketizer.cpp、Sender.cpp等C++类文件和相应的头文件,分别负责Source端的协议交互,会话过程管理、镜像媒体读取、编码、TS打包及RTP打包发送等过程。Converter 对象中包括一个MediaCodec对象具体负责编码过程,MediaCodec对象实际通过ACodec对象调用IOMX接口使用OPENOMX媒体框架完成镜像数据的编码。

sink和source使用的公共类文件主要是ANetworkSession.cpp和对应头文件以及一个 启动WifiDisplaySink的主程序wfd.cpp,用来 生成命令wfd。

整个协议主要的流程包括WIFI Display显示设备的连接过程和镜像数据的打包发送和接收流程,具体流程在下一篇博文中阐述。

时间: 2024-10-08 12:04:07

第十七篇 --ANDROID DisplayManager 服务解析一的相关文章

ANDROID DisplayManager 服务解析一

from://http://blog.csdn.net/goohong/article/details/8536102 http://www.tuicool.com/articles/FJVFnu ANDROID从版本4.2开始提供了一个显示管理服务DisplayManagerService,支持多种显示类型的多个显示器的镜像显示,包括内建的显示类型(本地).HDMI显示类型以及支持WIFI Display 协议( MIRACAST),实现本地设备在远程显示器上的镜像显示. 整个架构类图如下:

Android Service完全解析,关于服务你所需知道的一切(下) (转载)

转自:http://blog.csdn.net/guolin_blog/article/details/9797169 转载请注册出处:http://blog.csdn.net/guolin_blog/article/details/9797169 在 上一篇文章中,我们学习了Android Service相关的许多重要内容,包括Service的基本用法.Service和Activity进行通信.Service的销毁方式. Service与Thread的关系.以及如何创建前台Service.以上

Android Service完全解析,关于服务你所需知道的一切(上)

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了.Service作为Android四大组件之一,在每一个应用程序中都扮演着非常重要的角色.它主要用于在后台处理一些耗时的逻辑,或者去执行某些需要长期运行的任务.必要的时候我们甚至可以在程序退出的情况下,让Service在后台继续保持

Android Service完全解析,关于服务你所需知道的一切(下)

转载请注册出处:http://blog.csdn.net/guolin_blog/article/details/9797169 在上一篇文章中,我们学习了Android Service相关的许多重要内容,包括Service的基本用法.Service和Activity进行通信.Service的销毁方式.Service与Thread的关系.以及如何创建前台Service.以上所提到的这些知识点,基本上涵盖了大部分日常开发工作当中可能使用到的Service技术.不过关于Service其实还有一个更加

Android Service完全解析,关于服务你所需知道的一切(上) (转载)

转自:http://blog.csdn.net/guolin_blog/article/details/11952435 转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相 信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了. Service作为Android四大组件之一,在每一个应用程序中都扮演着非常重要的角色.它主要用于在后台

【转】Android Service完全解析,关于服务你所需知道的一切(下) ---- 不错

原文网址:http://blog.csdn.net/guolin_blog/article/details/9797169 转载请注册出处:http://blog.csdn.net/guolin_blog/article/details/9797169 在上一篇文章中,我们学习了Android Service相关的许多重要内容,包括Service的基本用法.Service和Activity进行通信.Service的销毁方式.Service与Thread的关系.以及如何创建前台Service.以上

【转载】Android Service完全解析,关于服务你所需知道的一切(上)

文章转载至:http://blog.csdn.net/guolin_blog/article/details/11952435 这是郭霖写的.......就是写 "第一行代码"的那个厉害人物,大师就是大师,和大师写的文章相比自己还差的挺多 文章写的太好了......感觉自己也写不出如此好的介绍Service的文章,希望多转载,让更多的人看到 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了.Serv

Android从服务端获取json解析显示在客户端上面

Android从服务端获取json解析显示在客户端上面 百度经验:jingyan.baidu.com 首先说一下Json数据的最基本的特点,Json数据是一系列的键值对的集合,和XML数据来比,Json数据的体积更加小,传输效率高,易解析,不过可读性不高; 因为这次要从服务器端得到Json数据,并且通过解析之后把解析后的数据显示在Android客户端中,首先部署服务器端代码(直接使用Jsp/Servlet): 构造的Json数据如下: [{"name":"张三",&

Android笔记(四十七) Android中的数据存储——XML(三)SAX解析

SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备. SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件.所谓事件,其实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口.下面是一些ContentHandler接口常用的方法: startDocument():当遇到文档的开头的时候,调用这