Android的Surface系统定义了一个DisplayType的枚举,其中有代表手机屏幕的DISPLAY_PRIMARY和代表HDMI等外接设备的DISPLAY_EXTERNAL,还有用于Wi-Fi Display的虚拟显示设备DISPLAY_VIRTUAL。本文就讲解HDMI的输出制式的设置流程。

Android设备通过HDMI线把内容显示到电视机上,当我们开关电视、拔插HDMI线,设置输出制式时,Android系统都做了什么来实现我们的操作?如果由你来设计这个流程,你要怎么实现?看过笔者前面写过的关于Android的网络系统的同仁,熟悉Android系统的代码的人估计很快就会想出Google的工程师应该会怎么实现。首先代码里要有一个HDMI service,这个service用来设置和管理HDMI输出制式,这个service可以是Java的,也可以是C++的,如果是C++说明这个service需要硬件配合实现。当HDMI cable插入后,底层HDMI的驱动检测到(HPD)后,需要通过本地Socket或者其他通信手段把uevent传给HDMI daemon,daemon再把event发送给HDMI service,HDMI daemon和HDMI service的通信不用多说,自然应该是通过Binder机制来实现。HDMI service收到event后做相应的处理来实现用户的操作。

/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

Android系统启动的时候有调用PhoneWindowManager对象的init方法,而该方法里有调用initializeHdmiState(),我们就来分析一下这个

initializeHdmiState()

{

//这里会创建出一个UEventThread线程来,接收Native层传上来的uevent

//就是说接收和/devices/virtual/switch/hdmi相关的uevent

mHDMIObserver.startObserving("DEVPATH=/devices/virtual/switch/hdmi");

}

显然这个UEventThread线程就是我们要找的HDMI daemon。

在UEventThread线程的主函数里

/frameworks/base/core/java/android/os/UEventObserver.java

public void run() {

nativeSetup();

while (true) {

//不停的接受从Native层传上来的uevent

Stringmessage = nativeWaitForNextEvent();

if (message!= null) {

//把Message发送给相对应的UEventObserver对象

sendEvent(message);

}

}

}

nativeWaitForNextEvent()函数是jni接口函数

/frameworks/base/core/jni/android_os_UEventObserver.cpp

static jstring nativeWaitForNextEvent(JNIEnv *env, jclassclazz) {

for (;;) {

int length =uevent_next_event(buffer, sizeof(buffer) - 1);

}

}

/hardware/libhardware_legacy/uevent/uevent.c

int uevent_init()

{

//在明显不过通过Socket和底层驱动进行通信

s =socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);

setsockopt(s,SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz));

if(bind(s, (structsockaddr *) &addr, sizeof(addr)) < 0) {

}

}

int uevent_next_event(char* buffer, int buffer_length)

{

while (1) {

//recv接收来自底层驱动的UEvent。

int count =recv(fd, buffer, buffer_length, 0);

}

}

从上面两个函数来看的话,HDMI daemon其实就是通过Socket和底层驱动进行通信的。

而HDMI的UEventObserver对象就是mHDMIObserver

/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

private UEventObserver mHDMIObserver = new UEventObserver() {

//处理来自于HDMI daemon的消息

public voidonUEvent(UEventObserver.UEvent event) {

setHdmiHwPlugged("1".equals(event.get("SWITCH_STATE")));

}

};

void setHdmiHwPlugged(boolean plugged) {

if(SystemProperties.getBoolean("ro.platform.has.mbxuimode", false)) {

if (plugged)

mMboxOutputModeManager.setHdmiPlugged();

else

mMboxOutputModeManager.setHdmiUnPlugged();

}

}

/frameworks/base/core/java/android/app/MboxOutputModeManager.java

public void setHdmiPlugged(){

mService.setHdmiPlugged();

}

其中mService就是MboxOutputModeService对象

MboxOutputModeService是SystemServer里的服务,显然MboxOutputModeService就是我们苦苦寻找的HDMI service。

该服务专门设置盒子的输出制式

/frameworks/base/services/java/com/android/server/MboxOutputModeService.java

public void setHdmiPlugged() {

setOutputMode()

}

public void setOutputModeNowLocked(final String mode){

//把新制式保存到文件/sys/class/display/mode里

//发送广播

}

common/drivers/xxxxx/hdmi/hdmi_tx/hdmi_tx.c

static int amhdmitx_probe(struct platform_device *pdev)

{

//显然有个线程在不停的处理HDMI相关的事情

hdmitx_device.task= kthread_run(hdmi_task_handle, &hdmitx_device, "kthread_hdmi");

}

show_disp_cap()

{

//获取edid

const char*native_disp_mode = hdmitx_edid_get_native_VIC(&hdmitx_device);

if(hdmitx_device.tv_no_edid){

//获取不到edid的话,添加"nulledid"

pos +=snprintf(buf+pos, PAGE_SIZE, "null edid\n");

} else {

//正常流程

}

}

Android HDMI输出设置流程相关推荐

  1. android 恢复出厂设置流程分析,基于Android系统快速恢复出厂设置方法实现.doc

    基于Android系统快速恢复出厂设置方法实现 基于Android系统快速恢复出厂设置方法实现 摘 要:针对使用Android系统的智能电视进行恢复出厂设置时重置速度慢的情况进行了研究和分析,从其重置 ...

  2. linux hdmi输出快捷键,linux 下的 投影仪,HDMI 输出设置

    前些日子研究xmbc的源代码,发现它里面的一个小工具,xbmc_xrandr有点意思,可以设置x11信号分辨率, 输出通道(设备),当时我想,如果X11也有这么一个小工具,我把信号的输出通道选择VGA ...

  3. linux hdmi输出快捷键,Linux下的投影仪HDMI输出设置

    前些日子研究xmbc的源代码,发现它里面的一个小工具,xbmc_xrandr有点意思,可以设置x11信号分辨率, 输出通道(设备),当时我想,如果X11也有这么一个小工具,我把信号的输出通道选择VGA ...

  4. linux hdmi输出快捷键,Linux 下的投影仪 HDMI 输出设置

    前些日子研究xmbc的源代码,发现它里面的一个小工具,xbmc_xrandr有点意思,可以设置x11信号分辨率,输出通道(设备),当时我想, 前些日子研究xmbc的源代码,发现它里面的一个小工具,,x ...

  5. linux 下的 投影仪,HDMI 输出设置

    前些日子研究xmbc的源代码,发现它里面的一个小工具,xbmc_xrandr有点意思,可以设置x11信号分辨率, 输出通道(设备),当时我想,如果X11也有这么一个小工具,我把信号的输出通道选择VGA ...

  6. 怎么看电脑的hdmi是输出还是输入_【电脑切换hdmi信号】电脑切换hdmi模式_电脑hdmi输出设置...

    2017-11-16 15:20:31 现在的电视基本都有hdmi接口,hdmi可同时传送音频和影像信号,支持更高的清晰度.可是有很多win8用户不知道怎么设置,连接电视后显示无信号,在win8 hd ...

  7. android qq邮箱格式,android手机怎么使用QQ邮箱 android QQ邮箱设置流程图解

    大家在使用android手机时都发现,其邮箱功能是十分强大的,实时接收邮件,并有通知提醒,像看短信似的.这样方便的邮箱功能是每个邮箱使用者的福音.但是邮箱有那么多种,android手机上默认的是使用g ...

  8. android 恢复出厂设置 界面,android恢复出厂设置流程概括

    恢复出厂设置流程概括 ============================================= 恢复出厂设置流程概括: 一. 设置模块中进行恢复出厂设置操作,系统一共做了两件事: 1 ...

  9. Android恢复出厂设置流程分析【Android源码解析十】

    最近看恢复出厂的一个问题,以前也查过这方面的流程,所以这里整理一些AP+framework层的流程: 在setting-->备份与重置--->恢复出厂设置--->重置手机---> ...

最新文章

  1. 阿里腾讯裁员冲上热搜,消息称最高涉及30%,官方未回应
  2. 版本控制8(译文) -(完)
  3. UIPageControl
  4. PyQt4编程之自定义插槽
  5. SUM and REPLACE
  6. 洛谷 - P2324 - 骑士精神 - A*搜索
  7. 使用Chrome开发者工具调试Android端内网页(微信,QQ,UC,App内嵌页等)
  8. java简单模拟实现数据库连接池
  9. 全国程序员工资最新统计来了,平均 14,542 元!
  10. Qt QScrollArea and layout in code
  11. SQL常用替换字符串值的5种方法
  12. win7怎么看计算机信息,如何查看Win7版本信息
  13. android怎样换背景图片,手机怎么抠图换背景 安卓和iPhone一键抠图换背景教程
  14. 学习ubuntu基础看完这一篇就够了,我是貔貅带你打开ubuntu的大门
  15. 五级流水线CPU之低功耗设计 (一) :Bypassing(旁路)
  16. python打印小票_购物小票——Python字符串格式化练习
  17. 基于域集中式架构的汽车车载通信安全方案
  18. 《你的善良必须有点锋芒》-慕言歌
  19. UltraISO制作大于4G文件的光盘映像可启动U盘
  20. 小米6设置位置服务器,小米6手机这样设置最科学

热门文章

  1. JDK8新特性(三):集合之 Stream 流式操作
  2. leaflet + proj4 加载ARCGIS CGCS2000地理坐标栅格瓦片
  3. matlab 热传导方程,热传导方程有限差分法的MATLAB实现
  4. NLP基础之专家系统介绍
  5. 为什么我不再用 .NET 框架
  6. 转载:原文http://www.cnblogs.com/gao241/p/3522143.html
  7. maven的使用方法
  8. 把oracle19c数据导入oracle11g
  9. java 资源映射访问本地磁盘的文件或者访问项目静态资源
  10. TED很火,如何利用TED学习英语