Android 耳机插入过程分析

参考链接:
https://www.jianshu.com/p/d82a8dabb3e7 初始化:
10-26 07:40:43.932 1414 1414 I SystemServer: StartWiredAccessoryManager
10-26 07:40:43.936 1414 1414 W WiredAccessoryManager: This kernel does not have usb audio support
10-26 07:40:43.937 1414 1414 W WiredAccessoryManager: This kernel does not have HDMI audio support
10-26 07:40:43.937 1414 1414 W WiredAccessoryManager: This kernel does not have DP audio support
10-26 07:40:43.937 1414 1414 D SystemServerTiming: StartWiredAccessoryManager took to complete: 6ms
10-26 07:40:46.375 1414 1414 V WiredAccessoryManager: notifyWiredAccessoryChanged: when=0 bits= mask=54
10-26 07:40:46.375 1414 1414 V WiredAccessoryManager: newName=h2w newState=0 headsetState=0 prev headsetState=0
10-26 07:40:46.375 1414 1414 E WiredAccessoryManager: No state change.
10-26 07:40:46.375 1414 1414 V WiredAccessoryManager: init() 耳机插入
10-26 11:26:48.552 1414 1684 V WiredAccessoryManager: notifyWiredAccessoryChanged: when=13604972191000 bits=SW_HEADPHONE_INSERT SW_MICROPHONE_INSERT mask=94
10-26 11:26:48.552 1414 1684 V WiredAccessoryManager: newName=h2w newState=1 headsetState=1 prev headsetState=0
10-26 11:26:48.554 1414 1684 I WiredAccessoryManager: MSG_NEW_DEVICE_STATE
10-26 11:26:48.555 1414 1414 V WiredAccessoryManager: headsetName: connected 耳机拔出
10-26 11:26:53.134 1414 1684 V WiredAccessoryManager: notifyWiredAccessoryChanged: when=13609554723000 bits= mask=94
10-26 11:26:53.134 1414 1684 V WiredAccessoryManager: newName=h2w newState=0 headsetState=0 prev headsetState=1
10-26 11:26:53.136 1414 1684 I WiredAccessoryManager: MSG_NEW_DEVICE_STATE
10-26 11:26:53.137 1414 1414 V WiredAccessoryManager: headsetName: disconnected 高通读取外设插入方式有两种:
1. UEvent:
读取/sys/class/switch/h2w/state文件等状态
2. InputEvent:
读取/dev/input/event 通过属性值,判断采用何种方式。
frameworks\base\core\res\res\values\config.xml
<bool name="config_useDevInputEventForAudioJack">true</bool> getevent
add device 1: /dev/input/event7
name: "msm8953-snd-card-mtp Button Jack"
add device 2: /dev/input/event6
name: "msm8953-snd-card-mtp Headset Jack"
add device 3: /dev/input/event2
name: "goodix-ts"
add device 4: /dev/input/event3
name: "hbtp_vm"
could not get driver version for /dev/input/mouse0, Not a typewriter
add device 5: /dev/input/event0
name: "qpnp_pon"
could not get driver version for /dev/input/mice, Not a typewriter
add device 6: /dev/input/event1
name: "tsu6721"
add device 7: /dev/input/event4
name: "keyremap_virtual"
add device 8: /dev/input/event5
name: "gpio-keys" 插入:
/dev/input/event6: 0005 0002 00000001
/dev/input/event6: 0005 0004 00000001
/dev/input/event6: 0005 0007 00000001
/dev/input/event6: 0000 0000 00000000 拔出:
/dev/input/event6: 0005 0002 00000000
/dev/input/event6: 0005 0004 00000000
/dev/input/event6: 0005 0007 00000000
/dev/input/event6: 0000 0000 00000000 getevent -l
/dev/input/event6: EV_SW SW_HEADPHONE_INSERT 00000001
/dev/input/event6: EV_SW SW_MICROPHONE_INSERT 00000001
/dev/input/event6: EV_SW SW_JACK_PHYSICAL_INS 00000001
/dev/input/event6: EV_SYN SYN_REPORT 00000000 /dev/input/event6: EV_SW SW_HEADPHONE_INSERT 00000000
/dev/input/event6: EV_SW SW_MICROPHONE_INSERT 00000000
/dev/input/event6: EV_SW SW_JACK_PHYSICAL_INS 00000000
/dev/input/event6: EV_SYN SYN_REPORT 00000000 代码跟踪
frameworks\base\services\core\java\com\android\server\input\InputManagerService.java
mUseDevInputEventForAudioJack =
context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack); if (mUseDevInputEventForAudioJack && (switchMask & SW_JACK_BITS) != 0) {
mWiredAccessoryCallbacks.notifyWiredAccessoryChanged(whenNanos, switchValues,
switchMask);
} frameworks\base\services\core\java\com\android\server\WiredAccessoryManager.java
public void notifyWiredAccessoryChanged(long whenNanos, int switchValues, int switchMask) {
if (LOG) Slog.v(TAG, "notifyWiredAccessoryChanged: when=" + whenNanos
+ " bits=" + switchCodeToString(switchValues, switchMask)
+ " mask=" + Integer.toHexString(switchMask)); synchronized (mLock) {
int headset;
mSwitchValues = (mSwitchValues & ~switchMask) | switchValues;
switch (mSwitchValues &
(SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_LINEOUT_INSERT_BIT)) {
case 0:
headset = 0;
break; case SW_HEADPHONE_INSERT_BIT:
headset = BIT_HEADSET_NO_MIC;
break; case SW_LINEOUT_INSERT_BIT:
headset = BIT_LINEOUT;
break; case SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT:
headset = BIT_HEADSET;
break; case SW_MICROPHONE_INSERT_BIT:
headset = BIT_HEADSET;
break; default:
headset = 0;
break;
} updateLocked(NAME_H2W,
(mHeadsetState & ~(BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT)) | headset);
}
} private void updateLocked(String newName, int newState) {
// Retain only relevant bits
int headsetState = newState & SUPPORTED_HEADSETS;
int usb_headset_anlg = headsetState & BIT_USB_HEADSET_ANLG;
int usb_headset_dgtl = headsetState & BIT_USB_HEADSET_DGTL;
int h2w_headset = headsetState & (BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT);
boolean h2wStateChange = true;
boolean usbStateChange = true;
if (LOG) Slog.v(TAG, "newName=" + newName
+ " newState=" + newState
+ " headsetState=" + headsetState
+ " prev headsetState=" + mHeadsetState); if (mHeadsetState == headsetState) {
Log.e(TAG, "No state change.");
return;
} // reject all suspect transitions: only accept state changes from:
// - a: 0 headset to 1 headset
// - b: 1 headset to 0 headset
if (h2w_headset == (BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT)) {
Log.e(TAG, "Invalid combination, unsetting h2w flag");
h2wStateChange = false;
}
// - c: 0 usb headset to 1 usb headset
// - d: 1 usb headset to 0 usb headset
if (usb_headset_anlg == BIT_USB_HEADSET_ANLG && usb_headset_dgtl == BIT_USB_HEADSET_DGTL) {
Log.e(TAG, "Invalid combination, unsetting usb flag");
usbStateChange = false;
}
if (!h2wStateChange && !usbStateChange) {
Log.e(TAG, "invalid transition, returning ...");
return;
} mWakeLock.acquire();
// 发送数据给
Log.i(TAG, "MSG_NEW_DEVICE_STATE");
Message msg = mHandler.obtainMessage(MSG_NEW_DEVICE_STATE, headsetState,
mHeadsetState, "");
mHandler.sendMessage(msg); mHeadsetState = headsetState;
} private final Handler mHandler = new Handler(Looper.myLooper(), null, true) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_NEW_DEVICE_STATE:
setDevicesState(msg.arg1, msg.arg2, (String)msg.obj);
mWakeLock.release();
break;
case MSG_SYSTEM_READY:
onSystemReady();
mWakeLock.release();
break;
}
}
}; private void setDevicesState(
int headsetState, int prevHeadsetState, String headsetName) {
synchronized (mLock) {
int allHeadsets = SUPPORTED_HEADSETS;
for (int curHeadset = 1; allHeadsets != 0; curHeadset <<= 1) {
if ((curHeadset & allHeadsets) != 0) {
setDeviceStateLocked(curHeadset, headsetState, prevHeadsetState, headsetName);
allHeadsets &= ~curHeadset;
}
}
}
} private void setDeviceStateLocked(int headset,
int headsetState, int prevHeadsetState, String headsetName) {
if ((headsetState & headset) != (prevHeadsetState & headset)) {
int outDevice = 0;
int inDevice = 0;
int state; if ((headsetState & headset) != 0) {
state = 1;
} else {
state = 0;
} if (headset == BIT_HEADSET) {
outDevice = AudioManager.DEVICE_OUT_WIRED_HEADSET;
inDevice = AudioManager.DEVICE_IN_WIRED_HEADSET;
} else if (headset == BIT_HEADSET_NO_MIC){
outDevice = AudioManager.DEVICE_OUT_WIRED_HEADPHONE;
} else if (headset == BIT_LINEOUT){
outDevice = AudioManager.DEVICE_OUT_LINE;
} else if (headset == BIT_USB_HEADSET_ANLG) {
outDevice = AudioManager.DEVICE_OUT_ANLG_DOCK_HEADSET;
} else if (headset == BIT_USB_HEADSET_DGTL) {
outDevice = AudioManager.DEVICE_OUT_DGTL_DOCK_HEADSET;
} else if (headset == BIT_HDMI_AUDIO) {
outDevice = AudioManager.DEVICE_OUT_HDMI;
} else {
Slog.e(TAG, "setDeviceState() invalid headset type: "+headset);
return;
} if (LOG) {
Slog.v(TAG, "headsetName: " + headsetName +
(state == 1 ? " connected" : " disconnected"));
}
// 发送给audio manager.
if (outDevice != 0) {
mAudioManager.setWiredDeviceConnectionState(outDevice, state, "", headsetName);
}
if (inDevice != 0) {
mAudioManager.setWiredDeviceConnectionState(inDevice, state, "", headsetName);
}
}
}

Android 耳机插入过程分析的更多相关文章

  1. Android 耳机插入过程分析 (AudioManager部分)

    接上一篇,记录audioManager对耳机插入的操作 https://www.cnblogs.com/helloworldtoyou/p/9868890.html 主要是发送广播,另外更新音频通路 ...

  2. 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?

    腾讯优测是专业的移动自动化测试平台,提供多维度的自动化测试服务,让测试更简单! 近期有报道称,澳大利亚悉尼市新某大学的一名男生在课堂上看电影,不料耳机没有插好,变成了现场直播... 如果你认为耳机没插 ...

  3. Android -- 检测耳机插入状态

    原理                                                                                    其实android系统在耳机 ...

  4. 联想Y50耳机插入耳机孔后没有声音解决办法

    症状:博主本子Y50,前阵子关机时,提示win10要下载更新并安装,开机后发现将耳机插入耳机孔后死活听不到声音(笔记本自带的音响有声音).期间怀疑过耳机坏了的问题,检查过耳机在手机上能正常播放声音.最 ...

  5. Android 批量插入数据到SQLite数据库

    Android中在sqlite插入数据的时候默认一条语句就是一个事务,因此如果存在上万条数据插入的话,那就需要执行上万次插入操作,操作速度可想而知.因此在Android中插入数据时,使用批量插入的方式 ...

  6. android 语言切换过程分析

    android 语言切换过程分析 2014-02-27 18:13 1207人阅读 评论(0) 收藏 举报 语言切换android语言切换android改变语言 最近在看一个bug,系统切换语言后,本 ...

  7. Android批量插入数据到SQLite数据库

    Android中在sqlite插入数据的时候默认一条语句就是一个事务,因此如果存在上万条数据插入的话,那就需要执行上万次插入操作,操作速度可想而知.因此在Android中插入数据时,使用批量插入的方式 ...

  8. iOS 检测耳机插入/拔出

    http://www.verydemo.com/demo_c134_i28481.html 开发过程中录音和播放这块碰到了一些问题,麻烦的主要有三个: 检测是否有声音输入设备 当有多个声音输出设备时, ...

  9. MTK Android 耳机线控的实现方法

    android 耳机线控的实现方法 keycodeonkeydownkeyevent 耳机线控的功能 耳机线控是一种很好用,并且能提升用户体验的功能.可以用来实现一些常用和基本的功能.比如:实现音乐播 ...

随机推荐

  1. ElasticSearch + xpack 使用

    ElasticSearch 是一个高可用开源全文检索和分析组件.提供存储服务,搜索服务,大数据准实时分析等.一般用于提供一些提供复杂搜索的应.我们为什么要选择 ElasticSearch ?因为它是一 ...

  2. Fluent UDF【1】:简介

    前面基本完成了动网格专题的发布,不过还是有一些内容并没有更新进去,比如说in-cylinder.接触检测.2.5D网格重构等.不过这些都是小技巧,写起来挺麻烦,以后有时间再通过案例视频的方式讲解好了. ...

  3. (原创)c++11改进我们的模式之改进命令模式

    模式虽然精妙,却难完美,比如观察者模式中观察者生命周期的问题:比如访问者模式中循环依赖的问题等等:其它很多模式也存在这样那样的一些不足之处,如使用场景受限.实现复杂.不够简洁.不够通用等.但我觉得不足 ...

  4. ubuntu 查看软件安装目录以及安装版本

    1.aptitude show 软件名 例如:aptitude show kde-runtime ****@ubuntu:~$ aptitude show kde-runtime 软件包: kde-r ...

  5. tornado源码分析-多进程

    1.源码文件 process.py 2.fork子进程 def fork_processes(num_processes, max_restarts=100): ... def start_child ...

  6. VirtualBox与VMWare网络冲突

    VirtualBox安装一个XP后,发现老是上不到网,怎么折腾都不行, 后来发现设备管理器中 vmware accelerated amd pcnet adapter #2显示黄色感叹号 不对呀,这是 ...

  7. Asp.Net MVC绑定DropDownList等控件

    测试环境:vs2013..Net4.5.mvc5 一.Asp.Net MVC绑定控件原理说明 以Html.TextBox为例 /// <param name="name"&g ...

  8. 将map中的查询参数拼装到URL路径中

    被调接口的URL路径: //被调接口url String apiUrl = "http://api.open.xxxxxx.com/implatform/interview/send?acc ...

  9. 三角形(css3)

    .userCard .sanjiao {//三角形的制作: width: 0; height: 0; border-left: 10px solid transparent; border-right ...

  10. iOS - UITableView加载网络图片 cell适应图片高度

    使用xib创建自定制cell   显示图片   创建一个继承UITableViewCell的类   勾选xib 如下是xib创建图 xib 向.h拖拽一个关联线 .h .m 2.代码创建(使用三方适配 ...