Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2112792
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: Android平台

2014-09-26 10:29:57

当有蓝牙耳机连接上时,系统由有线耳机切换到蓝牙耳机
一. 蓝牙耳机连上到audio的过程
对java不是很熟悉,大体上跟了一下代码
1. 当蓝牙耳机pair成功之后,会回调java
在蓝牙的packeges的app中,c回调java的onConnectionStateChanged
./packages/apps/Bluetooth/jni/com_android_bluetooth_a2dp.cpp
  1. static void classInitNative(JNIEnv* env, jclass clazz) {
  2.     method_onConnectionStateChanged = env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");
  3. }
java的onConnectionStateChanged又发送了一个EVENT_TYPE_CONNECTION_STATE_CHANGED的msg
./packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
  1. private void onConnectionStateChanged(int state, byte[] address) {
  2.     StackEvent event = new StackEvent(EVENT_TYPE_CONNECTION_STATE_CHANGED);
  3.     event.valueInt = state;
  4.     event.device = getDevice(address);
  5.     sendMessage(STACK_EVENT, event);
  6. }
在msg的处理Handler中:
  1. private class IntentBroadcastHandler extends Handler {    //b.msg处理
  2.     private void onConnectionStateChanged(BluetoothDevice device, int prevState, int state) {
  3.         Intent intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
  4.         intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
  5.         intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
  6.         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
  7.         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
  8.         mContext.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
  9.         mService.notifyProfileConnectionStateChanged(device, BluetoothProfile.A2DP, state, prevState);
  10.     }

  11.     @Override
  12.     public void handleMessage(Message msg) {
  13.         switch (msg.what) {
  14.             case MSG_CONNECTION_STATE_CHANGED:
  15.                 onConnectionStateChanged((BluetoothDevice) msg.obj, msg.arg1, msg.arg2);  //a.接收msg
  16.                 mWakeLock.release();
  17.                 break;
  18.         }
  19.     }
  20. }
上面的回调了java的onConnectionStateChanged,然后向AdapterService发送PROFILE_CONNECTION_STATE_CHANGED的消息
1.2 AdapterService接收到PROFILE_CONNECTION_STATE_CHANGED消息并处理
接收到这个MESSAGE_PROFILE_CONNECTION_STATE_CHANGED的msg,然后进调用processProfileStateChanged进行处理
./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
  1. public void onProfileConnectionStateChanged(BluetoothDevice device, int profileId, int newState, int prevState) {
  2.     Message m = mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED);
  3.     m.obj = device;
  4.     m.arg1 = profileId;
  5.     m.arg2 = newState;
  6.     Bundle b = new Bundle(1);
  7.     b.putInt("prevState", prevState);
  8.     m.setData(b);
  9.     mHandler.sendMessage(m);
  10. }

  11. private final Handler mHandler = new Handler() {
  12.     @Override
  13.     public void handleMessage(Message msg) {
  14.         switch (msg.what) {
  15.             case MESSAGE_PROFILE_CONNECTION_STATE_CHANGED: {
  16.                 processProfileStateChanged((BluetoothDevice) msg.obj, msg.arg1,msg.arg2, msg.getData().getInt("prevState",BluetoothAdapter.ERROR));
  17.             }
  18.             break;
  19.         }
  20.     }
  21. };
处理函数就是调用Binder的sendConnectionStateChange
  1. private void processProfileStateChanged(BluetoothDevice device, int profileId, int newState, int prevState) {
  2.     IBluetooth.Stub binder = mBinder;
  3.     binder.sendConnectionStateChange(device, profileId, newState,prevState);
  4. }
AdapterProperties的处理就是发送一个广播
./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java
  1. void sendConnectionStateChange(BluetoothDevice device, int profile, int state, int prevState) {
  2.     synchronized (mObject) {
  3.         updateProfileConnectionState(profile, state, prevState);
  4.         if (updateCountersAndCheckForConnectionStateChange(state, prevState)) {
  5.             setConnectionState(state);
  6.             Intent intent = new Intent(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
  7.             intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
  8.             intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, convertToAdapterState(state));
  9.             intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE, convertToAdapterState(prevState));
  10.             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
  11.             mService.sendBroadcastAsUser(intent, UserHandle.ALL, mService.BLUETOOTH_PERM);
  12.         }
  13.     }
  14. }
AdapterService的处理就是发送一个ACTION_CONNECTION_STATE_CHANGED的广播
1.3 谁来接收这个广播呢?
AudioService在初始化时,创建了intentFilter,就可以接收ACTION_CONNECTION_STATE_CHANGED
./frameworks/base/media/java/android/media/AudioService.java
  1. public AudioService(Context context) {
  2.     intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);   //初始化时,添加Filter
  3. }
  4. private class AudioServiceBroadcastReceiver extends BroadcastReceiver {
  5.     if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
  6.         //handleDeviceConnection(connected, device, address) //handle的处理就是调用AudioSystem的函数
  7.         AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_AVAILABLE, params);
  8.     }
  9. }
AudioSystem调用jni,由java进入c
./frameworks/base/media/java/android/media/AudioSystem.java
  1. public static native int setDeviceConnectionState(int device, int state, String device_address);
2. JNI
./frameworks/base/core/jni/android_media_AudioSystem.cpp
  1. android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address)
  2. {
  3.     const char *c_address = env->GetStringUTFChars(device_address, NULL);
  4.     int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
  5.                                           static_cast <audio_policy_dev_state_t>(state),
  6.                                           c_address));
  7.     env->ReleaseStringUTFChars(device_address, c_address);
  8.     return status;
  9. }

2.1 进入AudioSystem.cpp
./frameworks/av/media/libmedia/AudioSystem.cpp
  1. status_t AudioSystem::setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address)
  2. {
  3.     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
  4.     if (device_address != NULL) {
  5.         address = device_address;
  6.     }
  7.     return aps->setDeviceConnectionState(device, state, address);
  8. }
./frameworks/av/media/libmedia/AudioPolicyService.cpp
  1. status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,)
  2. {
  3.     return mpAudioPolicy->set_device_connection_state(mpAudioPolicy, device, state, device_address);
  4. }

3. audio_policy.default.so
  1. status_t AudioPolicyManagerBase::setDeviceConnectionState(audio_devices_t device,
  2.                                                   AudioSystem::device_connection_state state,
  3.                                                   const char *device_address)
  4. {
  5.     //先判断是输入输出:
  6.      硬件上己知是蓝牙设备,
  7.      蓝牙设备的标识 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET=0x20
  8.         AUDIO_DEVICE_OUT_BLUETOOTH_A2DP=0x80
  9.       然后再根据这个标识去查表即可判断是输出还是输出
  10. }
现在己经明白了,为什么回调时会到了audio_policy_default.so,
原因是回调时发了一个广播,这个广播时由AudioService接收的,AudioService又经过Jni等,调到了c层



阅读(1670) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~