最近遇到一个bug: 当播放音乐时,插拔耳机,此时闹钟响起,闹钟响铃没有声音。
刚开始以为是闹钟问题,浪费了不少时间,后来发现,插拔耳机后,音乐播放也会出现没有声音。
使用命令,
adb shell getevent 发现,插拔耳机时,底层事件有正常上报。
adb shell parameter status > status.log 查看,log中,当耳机拔出后,还是HeadSet状态,此时扬声器模式是disabled的,所以没有声音,再次插入耳机就有声音了。log属于特定打印,不同机子不一样。
SelectedInputDevice = <none>
SelectedOutputDevice = Headset
因此,特地代码跟踪了一下耳机处理流程。 参考了几篇大牛们的博客。
代码版本主要以Android 4.4和Android 5.0的为主。
主要有两种处理方式、
- UEvent
- InputEvent
Android 系统默认是使用UEvent的方式。两种模式的切换可以使用配置项来完成。
在:android4.4/frameworks/base/core/res/res/values/config.xml 中有
config.xml:1151: <bool name="config_useDevInputEventForAudioJack">false</bool> 配置项。当为false 则使用UEVent方式,为true则使用InputEvent方式,现在大多使用后者,具体得看厂商的定制代码。
比如我这里的device目录下,配置为true,使用的InputEvent方式。
xxx_rtfsc@xxx-HP-EliteDesk-880-G1-TWR:~/rtfsc/xxxxx_5.0/device$ grep -rn config_useDevInputEventForAudioJack
xxxx/common/overlays_aosp/frameworks/base/core/res/res/values/config.xml:40: <bool name="config_useDevInputEventForAudioJack">true</bool>
一 InputEvent
这种方式主要InputManagerService.java(framework/base/services/java/com/android/server/input/InputManagerService.java)中处理。
在InputManagerService的构造函数中,获取config_useDevInputEventForAudioJack的值,判断当前是否是使用InputEvent模式。
//判断当前是否使用InputEvent实现插拔检测。
//true:InputEvent;fasle:UEvent模式
mUseDevInputEventForAudioJack =
context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
当底层事件上报后,会转到InputManagerService的 notifySwitch方法中处理,然后回调到 WiredAccessoryManager中,。
// Native callback.
private void notifySwitch(long whenNanos, int switchValues, int switchMask) {
if (DEBUG) {
Slog.d(TAG, "notifySwitch: values=" + Integer.toHexString(switchValues)
+ ", mask=" + Integer.toHexString(switchMask));
}
if ((switchMask & SW_LID_BIT) != 0) {
final boolean lidOpen = ((switchValues & SW_LID_BIT) == 0);
mWindowManagerCallbacks.notifyLidSwitchChanged(whenNanos, lidOpen);
}
if (mUseDevInputEventForAudioJack && (switchMask & SW_JACK_BITS) != 0) {
//此时回调到WiredAccessoryManager.java中
mWiredAccessoryCallbacks.notifyWiredAccessoryChanged(whenNanos, switchValues,
switchMask);
}
}
提问: notifyWiredAccessoryChanged传递的参数分别是?