Android设备耳机插拔流程

有线耳机插入流程:
一、UEventObserver.java

有线设备输入输出插入消息处理
二、WiredAccessoryManager.java
1、消息处理

private final Handler mHandler = new Handler(Looper.myLooper(), null, true)
        public void handleMessage(Message msg) 
            switch (msg.what) {
               case MSG_NEW_DEVICE_STATE:
                   setDevicesState(msg.arg1, msg.arg2, (String)msg.obj);
                   mWakeLock.release();

2、收到需要处理的设备消息进行状态设置setDevicesState()

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;
                }
            }
        }
    }

3、来到setDeviceStateLocked添加有线连接设备:

private void setDeviceStateLocked(int headset,
          int headsetState, int prevHeadsetState, String headsetName) 
          if (outDevice != 0) {
             mAudioManager.setWiredDeviceConnectionState(outDevice, state, "", headsetName);
           }        
        if (inDevice != 0) {
             mAudioManager.setWiredDeviceConnectionState(inDevice, state, "", headsetName);
            }

三、提供audio音频管理接口AudioManager.java

   public void setWiredDeviceConnectionState(int type, int state, String address, String name) {
       final IAudioService service = getService();
       try {
           service.setWiredDeviceConnectionState(type, state, address, name,
                    mApplicationContext.getOpPackageName());
       } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
       }
    }

四、 获取相关audioservice AudioService.java

1、sendMsg()
     MSG_SET_WIRED_DEVICE_CONNECTION_STATE
2handleMessage(Message msg) 

3、onSetWiredDeviceConnectionState()

4handleDeviceConnection(boolean connect, int device, String address,
    final int res = AudioSystem.setDeviceConnectionState(device,
                      AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName);

五、AudioSystem.java

     public static native int setDeviceConnectionState(int device, int state,
                                                    String device_address, String device_name);

六、提供设备选择JNIandroid_media_AudioSystem.cpp

      AudioSystem::setDeviceConnectionState()

七、获取Native层的服务AudioSystem.cpp

      const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
      return aps->setDeviceConnectionState(device, state, address, name);

八、用于选择输入输出设备AudioPolicyInterfaceImpl.cpp

   return mAudioPolicyManager->setDeviceConnectionState(device, state, device_address, device_name);

九、 具体是通过AudioPolicyManager.cpp对可用输入输出设备的选择:
AudioPolicyManager.cpp

AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
                                                      audio_policy_dev_state_t state,
                                                      const char *device_address,
                                                      const char *device_name)
 AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
                                                         audio_policy_dev_state_t state,
                                                         const char *device_address,
                                                         const char *device_name)

下面是引用别人的一些分析
在这里插入图片描述
Android UEventObserver 使用

UEventObserver是android Java层利用uevent与获取Kernel层状态变化的机制。

通过grep发现framework有如下模块使用UEventObserver的功能来提供服务:
电池状态:services/java/com/android/server/BatteryService.java
耳机状态:services/java/com/android/server/HeadsetObserver.java
DOCK状态:services/java/com/android/server/DockObserver.java
USB状态:services/java/com/android/server/usb/UsbService.java

它们全部继承自UEventObserver,先看看这个类的构造和原理:
./core/java/android/os/UEventObserver.java
|
[ native_setup(), next_event() ]
|/
./core/jni/android_os_UEventObserver.cpp
|
[ uevent_init(),uevent_next_event() ]
|/
/hardware/libhardware_legacy/uevent/uevent.c
| [userspace]
---------------------[socket]-----------------------------------------------------------------------------
|
|/ [kernel]
socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)

下面用HeadsetObserver作为例子说明如何使用UEventObserver来监听kernel的uevent。
继承UEventObserver的类必须实现自己的public abstract void onUEvent(UEvent event):
[java] view plaincopy
@Override
public void onUEvent(UEventObserver.UEvent event) {
if (LOG) Slog.v(TAG, "Headset UEVENT: " + event.toString());

try {  
    update(event.get("SWITCH_NAME"), Integer.parseInt(event.get("SWITCH_STATE"))); // update中处理事务  
} catch (NumberFormatException e) {  
    Slog.e(TAG, "Could not parse switch state from event " + event);  
}  

}

这个函数会在UEventObserver接收到event的时候由UEventObserver来回调,HeadsetObserver使用startObserving(“DEVPATH=/devices/virtual/switch/h2w”)来开始监听,这个API会确保sThread已经运行并且以字串参数作为匹配参数增加一个observer:
public final synchronized void startObserving(String match) {
ensureThreadStarted();
sThread.addObserver(match, this);
}

UEventObserver的核心部分就是sThread的run:
[java] view plaincopy
public void run() {
native_setup(); //调用uevent.c中的API来打开socket

byte[] buffer = new byte[1024];  
int len;  
while (true) {  
    len = next_event(buffer); // 在uevent.c中用poll调用来获取event,会阻塞  
    if (len > 0) {  
        String bufferStr = new String(buffer, 0, len);  // easier to search a String  
        synchronized (mObservers) {  
            for (int i = 0; i < mObservers.size(); i += 2) {  
                if (bufferStr.indexOf((String)mObservers.get(i)) != -1) { // 找到匹配的match参数,说明某个observer的监听的event发生了  
                    ((UEventObserver)mObservers.get(i+1))  
                            .onUEvent(new UEvent(bufferStr)); // 调用这个observer的onUEvent函数  
                }  
            }  
        }  
    }  
}  

}

// TODO: 分析kernel层如何上报uevent事件

在线查看Android源码推荐使用:http://androidxref.com/

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值