当有蓝牙耳机连接上时,系统由有线耳机切换到蓝牙耳机
一. 蓝牙耳机连上到audio的过程
对java不是很熟悉,大体上跟了一下代码
1. 当蓝牙耳机pair成功之后,会回调java
在蓝牙的packeges的app中,c回调java的 onConnectionStateChanged
./packages/apps/Bluetooth/jni/com_android_bluetooth_a2dp.cpp
java的
onConnectionStateChanged
又发送了一个EVENT_TYPE_CONNECTION_STATE_CHANGED的msg
./packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
在msg的处理Handler中:
上面的回调了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
处理函数就是调用Binder的
sendConnectionStateChange
AdapterProperties的处理就是发送一个广播
./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java
AdapterService的处理就是发送一个ACTION_CONNECTION_STATE_CHANGED的广播
1.3 谁来接收这个广播呢?
AudioService在初始化时,创建了intentFilter,就可以接收ACTION_CONNECTION_STATE_CHANGED
./frameworks/base/media/java/android/media/AudioService.java
AudioSystem调用jni,由java进入c
./frameworks/base/media/java/android/media/AudioSystem.java
2. JNI
./frameworks/base/core/jni/android_media_AudioSystem.cpp
2.1 进入AudioSystem.cpp
./frameworks/av/media/libmedia/AudioSystem.cpp
./frameworks/av/media/libmedia/AudioPolicyService.cpp
3. audio_policy.default.so
现在己经明白了,为什么回调时会到了audio_policy_default.so,
原因是回调时发了一个广播,这个广播时由AudioService接收的,AudioService又经过Jni等,调到了c层
一. 蓝牙耳机连上到audio的过程
对java不是很熟悉,大体上跟了一下代码
1. 当蓝牙耳机pair成功之后,会回调java
在蓝牙的packeges的app中,c回调java的 onConnectionStateChanged
./packages/apps/Bluetooth/jni/com_android_bluetooth_a2dp.cpp
- static void classInitNative(JNIEnv* env, jclass clazz) {
- method_onConnectionStateChanged = env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");
- }
./packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
- private void onConnectionStateChanged(int state, byte[] address) {
- StackEvent event = new StackEvent(EVENT_TYPE_CONNECTION_STATE_CHANGED);
- event.valueInt = state;
- event.device = getDevice(address);
- sendMessage(STACK_EVENT, event);
- }
- private class IntentBroadcastHandler extends Handler { //b.msg处理
- private void onConnectionStateChanged(BluetoothDevice device, int prevState, int state) {
- Intent intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
- intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
- intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mContext.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
- mService.notifyProfileConnectionStateChanged(device, BluetoothProfile.A2DP, state, prevState);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_CONNECTION_STATE_CHANGED:
- onConnectionStateChanged((BluetoothDevice) msg.obj, msg.arg1, msg.arg2); //a.接收msg
- mWakeLock.release();
- break;
- }
- }
- }
1.2 AdapterService接收到PROFILE_CONNECTION_STATE_CHANGED消息并处理
接收到这个 MESSAGE_PROFILE_CONNECTION_STATE_CHANGED 的msg,然后进调用processProfileStateChanged进行处理
./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
- public void onProfileConnectionStateChanged(BluetoothDevice device, int profileId, int newState, intprevState) {
- Message m = mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED);
- m.obj = device;
- m.arg1 = profileId;
- m.arg2 = newState;
- Bundle b = new Bundle(1);
- b.putInt("prevState", prevState);
- m.setData(b);
- mHandler.sendMessage(m);
- }
-
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_PROFILE_CONNECTION_STATE_CHANGED: {
- processProfileStateChanged((BluetoothDevice) msg.obj, msg.arg1,msg.arg2, msg.getData().getInt("prevState",BluetoothAdapter.ERROR));
- }
- break;
- }
- }
- };
- private void processProfileStateChanged(BluetoothDevice device, int profileId, int newState, int prevState) {
- IBluetooth.Stub binder = mBinder;
- binder.sendConnectionStateChange(device, profileId, newState,prevState);
- }
./packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java
- void sendConnectionStateChange(BluetoothDevice device, int profile, int state, int prevState) {
- synchronized (mObject) {
- updateProfileConnectionState(profile, state, prevState);
- if (updateCountersAndCheckForConnectionStateChange(state, prevState)) {
- setConnectionState(state);
- Intent intent = new Intent(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, convertToAdapterState(state));
- intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE, convertToAdapterState(prevState));
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mService.sendBroadcastAsUser(intent, UserHandle.ALL, mService.BLUETOOTH_PERM);
- }
- }
- }
1.3 谁来接收这个广播呢?
AudioService在初始化时,创建了intentFilter,就可以接收ACTION_CONNECTION_STATE_CHANGED
./frameworks/base/media/java/android/media/AudioService.java
- public AudioService(Context context) {
- intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); //初始化时,添加Filter
- }
- private class AudioServiceBroadcastReceiver extends BroadcastReceiver {
- if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
- //handleDeviceConnection(connected, device, address) //handle的处理就是调用AudioSystem的函数
- AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_AVAILABLE, params);
- }
- }
./frameworks/base/media/java/android/media/AudioSystem.java
- public static native int setDeviceConnectionState(int device, int state, String device_address);
./frameworks/base/core/jni/android_media_AudioSystem.cpp
- android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address)
- {
- const char *c_address = env->GetStringUTFChars(device_address, NULL);
- int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
- static_cast <audio_policy_dev_state_t>(state),
- c_address));
- env->ReleaseStringUTFChars(device_address, c_address);
- return status;
- }
2.1 进入AudioSystem.cpp
./frameworks/av/media/libmedia/AudioSystem.cpp
- status_t AudioSystem::setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address)
- {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
- if (device_address != NULL) {
- address = device_address;
- }
- return aps->setDeviceConnectionState(device, state, address);
- }
- status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,)
- {
- return mpAudioPolicy->set_device_connection_state(mpAudioPolicy, device, state, device_address);
- }
3. audio_policy.default.so
- status_t AudioPolicyManagerBase::setDeviceConnectionState(audio_devices_t device,
- AudioSystem::device_connection_state state,
- const char *device_address)
- {
- //先判断是输入输出:
- 硬件上己知是蓝牙设备,
- 蓝牙设备的标识 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET=0x20
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP=0x80
- 然后再根据这个标识去查表即可判断是输出还是输出
- }
原因是回调时发了一个广播,这个广播时由AudioService接收的,AudioService又经过Jni等,调到了c层