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. Win8/Win10下程序经常无响应的解决办法

    如果你使用Win8/Win10系统时经常出现程序无响应的问题不仿试下如下解决办法. 表现症状: 任何程序都有可能出现无响应(记事本.Visual Studio.QQ.视频播放器等) 一旦一个程序出现未 ...

  2. tcp拥堵算法

    http://m.blog.csdn.net/article/details?id=6739189

  3. Gluster vs Ceph:开源存储领域的正面较量

    https://www.oschina.net/news/49048/gluster-vs-ceph 引言:开源存储软件Ceph和Gluster能够提供相似的特性并且能够为用户节省不小的开支.那么谁更 ...

  4. 读取本地已有的.db数据库

    public class MyDB extends SQLiteOpenHelper { // 数据库的缺省路径 private static String DB_PATH ; private sta ...

  5. Beginning SDL 2.0(4) YUV加载及渲染

    本文主要内容是基于的“Beginning SDL 2.0(3) SDL介绍及BMP渲染”(以下简称BS3)基础上,将BMP加载及渲染修改为YUV420或I420的原始视频格式.阅读完本部分内容相信你可 ...

  6. 如何使cmd窗口正确显示utf-8编码的文字

    http://blog.csdn.net/ehcoing/article/details/51865922 ********************************************** ...

  7. HP管理工具System Management Homepage安装配置

    如果用HP的启动光盘进行系统安装时,HP SMH 及相关组件会自动安装完成,但如果是用操作系统光盘进行系统安装,则HP SMH相关组件需要手动进行安装及相关设置!HP SMH由三部分组成:HP Sys ...

  8. Python3在指定路径下递归定位文件中出现的字符串

    [本文出自天外归云的博客园] 脚本功能:在指定的路径下递归搜索,找出指定字符串在文件中出现的位置(行信息). 用到的python特性: 1. PEP 318 -- Decorators for Fun ...

  9. java---简单的ATM存取系统,

    新手练手必备~ 密码账户为: 先创建账户类: package cn.Atm; /** * @author 偶my耶 */ import java.io.*; import com.project.pr ...

  10. android中画图类的介绍Path

    Paint类相关属性: /** * Paint类介绍 * * Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色, * 样式等绘制信息,指定了如何绘制文本和图形,画笔对象有很多设置 ...