Android HDMI输出设置流程
来源:互联网 发布:淘宝app框架 编辑:程序博客网 时间:2024/05/16 09:42
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输出设置流程
- PC设置HDMI输出
- linux 下的 投影仪,HDMI 输出设置
- 电脑HDMI接电视 设置耳机输出声音
- HDMI介绍与流程
- HDMI介绍与流程
- android HDMI:HDMI基础篇
- 树莓派HDMI线设置
- s5pv210 linux hdmi tv输出
- LT8612EX业界最新两路输出,HDMI转VGA/HDMI,HDMI转HDMI加VGA
- Freescale IMX6 Android (1): 使用HDMI作为Android显示输出的配置
- android 铃声设置流程
- android HDMI (一):HDMI基础篇
- android HDMI (一):HDMI基础篇
- android HDMI (一):HDMI基础篇
- android HDMI (一):HDMI基础篇
- android HDMI (一):HDMI基础篇
- android HDMI (一):HDMI基础篇
- GazeTrackingFramework视线跟踪项目试用
- 集合嵌套之HashMap嵌套HashMap
- 教女朋友学Python(3)——把老公装进电脑里
- 单链表的创建(静态链表,动态链表)
- 1016. Phone Bills 解析
- Android HDMI输出设置流程
- win10解决.net framework3.5无法安装的问题
- 在Android app应用内打开链接
- 高校云平台(十):Jboss远程访问流程总结
- 学习的感想
- 1017. Queueing at Bank 解析
- Problem A. Vote Google APAC 2017 University Test Round D
- [BZOJ3688]折线统计(dp+bit优化)
- 建最小堆min_heap_sort