插入拔出framework部分相关源码流程分析涉及到的类文件
./framework/base/services/core/java/com/android/server/input/InputManagerService.java
./framework/base/services/core/java/com/android/server/WiredAccessoryManager.java
./framework/base/core/res/res/values/config.xml
./framework/base/services/java/com/android/server/SystemServer.java
./base/media/java/android/media/AudioManager.java
./base/media/java/android/media/AudioService.java
UEvent和InputEvent的选择
这两个的切换主要是通过设置属性来的。该属性开关位于config.xml中:
从注释里面我们可以看到设置为true,选择/dev/input/event ,设置为false 选择uevent 来控制事件的上报。
在InputManagerService.java 构造方法中,config_useDevInputEventForAudioJack的值初始化mUseDevInputEventForAudioJack 决定采用哪种方式。
notifySwitch
WiredAccessoryCallbacks
看看这个回调注册的地方,在systemServer的startOtherServices中
从上面的代码可以看到WiredAccessoryManager对象直接被注册为callBack
因此mWiredAccessoryCallbacks.notifyWiredAccessoryChanged直接将后面的任务交给了WiredAccessoryManager类
WiredAccessoryManager.java -> notifyWiredAccessoryChanged
接着转到updateLocked方法,该方法作用是check当前模式是否变化。也就是是否发生耳机拔出了或者插入了(0->1;1->0的变化)。state无变化则不会继续处理。
updateLocked
mHandler
setDeviceStateLocked
接下来的流程就交给了AudioManager,不过真正的实现是在AudioService中
AudioDeviceBroker.java -> setWiredDeviceConnectionState
AudioDeviceInventory.java -> setWiredDeviceConnectionState
postSetWiredDeviceConnectionState
handleMessage
onSetWiredDeviceConnectionState
handleDeviceConnection
sendDeviceConnectionIntent
从这个方法,可以看到intent耳机插拔的广播我们可以在app层通过监听ACTION_HEADSET_PLUG。 intent携带了,当前最新状态state ,name以及microphone(耳机是否带麦)。
在PhoneStatusBarPolicy.java注册ACTION_HEADSET_PLUG广播
接收到ACTION_HEADSET_PLUG广播之后决定是否显示耳机图标
通知底层,在上面的handleDeviceConnection 中会调用AudioSystem.setDeviceConnectionState
这个会往下调用到AudioPolicyManager的setDeviceConnectionState中去
以上就是插拔耳机的整个流程