diff options
18 files changed, 187 insertions, 73 deletions
diff --git a/android/app/jni/com_android_bluetooth_vc.cpp b/android/app/jni/com_android_bluetooth_vc.cpp index ce760c2206..5bb744db7a 100644 --- a/android/app/jni/com_android_bluetooth_vc.cpp +++ b/android/app/jni/com_android_bluetooth_vc.cpp @@ -66,7 +66,7 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { } void OnVolumeStateChanged(const RawAddress& bd_addr, uint8_t volume, - bool mute) override { + bool mute, bool isAutonomous) override { LOG(INFO) << __func__; std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); @@ -83,11 +83,11 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), (jbyte*)&bd_addr); sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeStateChanged, - (jint)volume, (jboolean)mute, addr.get()); + (jint)volume, (jboolean)mute, addr.get(), (jboolean)isAutonomous); } void OnGroupVolumeStateChanged(int group_id, uint8_t volume, - bool mute) override { + bool mute, bool isAutonomous) override { LOG(INFO) << __func__; std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); @@ -96,7 +96,7 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGroupVolumeStateChanged, (jint)volume, - (jboolean)mute, group_id); + (jboolean)mute, group_id, (jboolean)isAutonomous); } }; @@ -107,10 +107,10 @@ static void classInitNative(JNIEnv* env, jclass clazz) { env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V"); method_onVolumeStateChanged = - env->GetMethodID(clazz, "onVolumeStateChanged", "(IZ[B)V"); + env->GetMethodID(clazz, "onVolumeStateChanged", "(IZ[BZ)V"); method_onGroupVolumeStateChanged = - env->GetMethodID(clazz, "onGroupVolumeStateChanged", "(IZI)V"); + env->GetMethodID(clazz, "onGroupVolumeStateChanged", "(IZIZ)V"); LOG(INFO) << __func__ << ": succeeds"; } diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java index 7a3b7df82b..2c71f6d463 100644 --- a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java +++ b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java @@ -216,8 +216,13 @@ public class A2dpService extends ProfileService { } if (mStateMachinesThread != null) { - mStateMachinesThread.quitSafely(); - mStateMachinesThread = null; + try { + mStateMachinesThread.quitSafely(); + mStateMachinesThread.join(); + mStateMachinesThread = null; + } catch (InterruptedException e) { + // Do not rethrow as we are shutting down anyway + } } // Step 2: Reset maximum number of connected audio devices mMaxConnectedAudioDevices = 1; diff --git a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java index dec6db2e4b..d66dbc01e3 100644 --- a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java +++ b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java @@ -182,8 +182,13 @@ public class CsipSetCoordinatorService extends ProfileService { } if (mStateMachinesThread != null) { - mStateMachinesThread.quitSafely(); - mStateMachinesThread = null; + try { + mStateMachinesThread.quitSafely(); + mStateMachinesThread.join(); + mStateMachinesThread = null; + } catch (InterruptedException e) { + // Do not rethrow as we are shutting down anyway + } } mDeviceGroupIdMap.clear(); diff --git a/android/app/src/com/android/bluetooth/hap/HapClientService.java b/android/app/src/com/android/bluetooth/hap/HapClientService.java index b8aaab841b..dca14bfdc7 100644 --- a/android/app/src/com/android/bluetooth/hap/HapClientService.java +++ b/android/app/src/com/android/bluetooth/hap/HapClientService.java @@ -208,8 +208,13 @@ public class HapClientService extends ProfileService { mPresetsMap.clear(); if (mStateMachinesThread != null) { - mStateMachinesThread.quitSafely(); - mStateMachinesThread = null; + try { + mStateMachinesThread.quitSafely(); + mStateMachinesThread.join(); + mStateMachinesThread = null; + } catch (InterruptedException e) { + // Do not rethrow as we are shutting down anyway + } } // Clear AdapterService diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java index 4f4a45ad6b..98cd2caadc 100644 --- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java +++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java @@ -189,8 +189,13 @@ public class HearingAidService extends ProfileService { mHiSyncIdConnectedMap.clear(); if (mStateMachinesThread != null) { - mStateMachinesThread.quitSafely(); - mStateMachinesThread = null; + try { + mStateMachinesThread.quitSafely(); + mStateMachinesThread.join(); + mStateMachinesThread = null; + } catch (InterruptedException e) { + // Do not rethrow as we are shutting down anyway + } } // Clear AdapterService, HearingAidNativeInterface diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java index b4eca8f538..361e247cdd 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java @@ -236,8 +236,14 @@ public class HeadsetService extends ProfileService { // Step 3: Destroy system interface mSystemInterface.stop(); // Step 2: Stop handler thread - mStateMachinesThread.quitSafely(); - mStateMachinesThread = null; + try { + mStateMachinesThread.quitSafely(); + mStateMachinesThread.join(); + mStateMachinesThread = null; + } catch (InterruptedException e) { + // Do not rethrow as we are shutting down anyway + } + mStateMachinesThreadHandler = null; // Step 1: Clear synchronized (mStateMachines) { diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java index a94a5687c1..e6d06e2e25 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java @@ -260,8 +260,13 @@ public class LeAudioService extends ProfileService { } if (mStateMachinesThread != null) { - mStateMachinesThread.quitSafely(); - mStateMachinesThread = null; + try { + mStateMachinesThread.quitSafely(); + mStateMachinesThread.join(); + mStateMachinesThread = null; + } catch (InterruptedException e) { + // Do not rethrow as we are shutting down anyway + } } mAudioManager = null; diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java b/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java index ee6fd37b26..0d2b0ec0af 100644 --- a/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java +++ b/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java @@ -154,7 +154,8 @@ public class VolumeControlNativeInterface { sendMessageToService(event); } - private void onVolumeStateChanged(int volume, boolean mute, byte[] address) { + private void onVolumeStateChanged(int volume, boolean mute, byte[] address, + boolean isAutonomous) { VolumeControlStackEvent event = new VolumeControlStackEvent( VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED); @@ -162,6 +163,7 @@ public class VolumeControlNativeInterface { event.valueInt1 = -1; event.valueInt2 = volume; event.valueBool1 = mute; + event.valueBool2 = isAutonomous; if (DBG) { Log.d(TAG, "onVolumeStateChanged: " + event); @@ -169,7 +171,8 @@ public class VolumeControlNativeInterface { sendMessageToService(event); } - private void onGroupVolumeStateChanged(int volume, boolean mute, int groupId) { + private void onGroupVolumeStateChanged(int volume, boolean mute, int groupId, + boolean isAutonomous) { VolumeControlStackEvent event = new VolumeControlStackEvent( VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED); @@ -177,6 +180,7 @@ public class VolumeControlNativeInterface { event.valueInt1 = groupId; event.valueInt2 = volume; event.valueBool1 = mute; + event.valueBool2 = isAutonomous; if (DBG) { Log.d(TAG, "onGroupVolumeStateChanged: " + event); diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java index 91fafa0c05..732679a366 100644 --- a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java +++ b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java @@ -32,6 +32,8 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.media.AudioDeviceAttributes; +import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.os.HandlerThread; import android.os.ParcelUuid; @@ -56,12 +58,20 @@ public class VolumeControlService extends ProfileService { // Upper limit of all VolumeControl devices: Bonded or Connected private static final int MAX_VC_STATE_MACHINES = 10; + private static final int LE_AUDIO_MAX_VOL = 255; + private static final int LE_AUDIO_MIN_VOL = 0; + private static VolumeControlService sVolumeControlService; private AdapterService mAdapterService; private HandlerThread mStateMachinesThread; private BluetoothDevice mPreviousAudioDevice; + private int mMusicMaxVolume = 0; + private int mMusicMinVolume = 0; + private int mVoiceCallMaxVolume = 0; + private int mVoiceCallMinVolume = 0; + @VisibleForTesting VolumeControlNativeInterface mVolumeControlNativeInterface; @VisibleForTesting @@ -106,6 +116,11 @@ public class VolumeControlService extends ProfileService { Objects.requireNonNull(mAudioManager, "AudioManager cannot be null when VolumeControlService starts"); + mMusicMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); + mMusicMinVolume = mAudioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC); + mVoiceCallMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL); + mVoiceCallMinVolume = mAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL); + // Start handler thread for state machines mStateMachines.clear(); mStateMachinesThread = new HandlerThread("VolumeControlService.StateMachines"); @@ -164,8 +179,13 @@ public class VolumeControlService extends ProfileService { if (mStateMachinesThread != null) { - mStateMachinesThread.quitSafely(); - mStateMachinesThread = null; + try { + mStateMachinesThread.quitSafely(); + mStateMachinesThread.join(); + mStateMachinesThread = null; + } catch (InterruptedException e) { + // Do not rethrow as we are shutting down anyway + } } // Clear AdapterService, VolumeControlNativeInterface @@ -422,18 +442,51 @@ public class VolumeControlService extends ProfileService { } void handleVolumeControlChanged(BluetoothDevice device, int groupId, - int volume, boolean mute) { - /* TODO handle volume change for group in case of unicast le audio - * or per device in case of broadcast or simple remote controller. - * Note: minimum volume is 0 and maximum 255. - */ + int volume, boolean mute, boolean isAutonomous) { + if (!isAutonomous) { + // If the change is triggered by Android device, the stream is already changed. + return; + } + // TODO: Handle the other arguments: device, groupId, mute. + + int streamType = getBluetoothContextualVolumeStream(); + mAudioManager.setStreamVolume(streamType, getDeviceVolume(streamType, volume), + AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_BLUETOOTH_ABS_VOLUME); + } + + int getDeviceVolume(int streamType, int bleVolume) { + int bleMaxVolume = 255; // min volume is zero + int deviceMaxVolume = (streamType == AudioManager.STREAM_VOICE_CALL) + ? mVoiceCallMaxVolume : mMusicMaxVolume; + int deviceMinVolume = (streamType == AudioManager.STREAM_VOICE_CALL) + ? mVoiceCallMinVolume : mMusicMinVolume; + + // TODO: Investigate what happens in classic BT when BT volume is changed to zero. + return (int) Math.floor( + (double) bleVolume * (deviceMaxVolume - deviceMinVolume) / bleMaxVolume); + } + + // Copied from AudioService.getBluetoothContextualVolumeStream() and modified it. + int getBluetoothContextualVolumeStream() { + int mode = mAudioManager.getMode(); + switch (mode) { + case AudioManager.MODE_IN_COMMUNICATION: + case AudioManager.MODE_IN_CALL: + return AudioManager.STREAM_VOICE_CALL; + case AudioManager.MODE_NORMAL: + default: + // other conditions will influence the stream type choice, read on... + break; + } + return AudioManager.STREAM_MUSIC; } void messageFromNative(VolumeControlStackEvent stackEvent) { if (stackEvent.type == VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED) { handleVolumeControlChanged(stackEvent.device, stackEvent.valueInt1, - stackEvent.valueInt2, stackEvent.valueBool1); + stackEvent.valueInt2, stackEvent.valueBool1, + stackEvent.valueBool2); return; } @@ -495,6 +548,14 @@ public class VolumeControlService extends ProfileService { sm = VolumeControlStateMachine.make(device, this, mVolumeControlNativeInterface, mStateMachinesThread.getLooper()); mStateMachines.put(device, sm); + + mAudioManager.setDeviceVolumeBehavior( + new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_OUTPUT, + // Currently, TYPE_BLUETOOTH_A2DP is the only thing that works. + AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, + ""), + AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE); return sm; } } diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java b/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java index c5d4aa336b..2750c7e694 100644 --- a/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java +++ b/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java @@ -37,6 +37,7 @@ public class VolumeControlStackEvent { public int valueInt1; public int valueInt2; public boolean valueBool1; + public boolean valueBool2; /* Might need more for other callbacks*/ VolumeControlStackEvent(int type) { @@ -52,6 +53,7 @@ public class VolumeControlStackEvent { result.append(", valueInt1:" + eventTypeValue1ToString(type, valueInt1)); result.append(", valueInt2:" + eventTypeValue2ToString(type, valueInt2)); result.append(", valueBool1:" + eventTypeValueBool1ToString(type, valueBool1)); + result.append(", valueBool2:" + eventTypeValueBool2ToString(type, valueBool2)); result.append("}"); return result.toString(); } @@ -124,4 +126,14 @@ public class VolumeControlStackEvent { } return Boolean.toString(value); } + + private static String eventTypeValueBool2ToString(int type, boolean value) { + switch (type) { + case EVENT_TYPE_VOLUME_STATE_CHANGED: + return "{isAutonomous:" + value + "}"; + default: + break; + } + return Boolean.toString(value); + } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java index b38c8423c2..2530facca4 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpStateMachineTest.java @@ -122,6 +122,7 @@ public class A2dpStateMachineTest { } mA2dpStateMachine.doQuit(); mHandlerThread.quit(); + mHandlerThread.join(); TestUtils.clearAdapterService(mAdapterService); } diff --git a/system/bta/vc/types.h b/system/bta/vc/types.h index 4461d65c92..a8a4b252c8 100644 --- a/system/bta/vc/types.h +++ b/system/bta/vc/types.h @@ -50,6 +50,7 @@ struct VolumeOperation { int group_id_; bool started_; + bool is_autonomous_; uint8_t opcode_; std::vector<uint8_t> arguments_; @@ -57,11 +58,12 @@ struct VolumeOperation { std::vector<RawAddress> devices_; alarm_t* operation_timeout_; - VolumeOperation(int operation_id, int group_id, uint8_t opcode, + VolumeOperation(int operation_id, int group_id, bool is_autonomous, uint8_t opcode, std::vector<uint8_t> arguments, std::vector<RawAddress> devices) : operation_id_(operation_id), group_id_(group_id), + is_autonomous_(is_autonomous), opcode_(opcode), arguments_(arguments), devices_(devices) { diff --git a/system/bta/vc/vc.cc b/system/bta/vc/vc.cc index 08f61e8774..23a20bf8c8 100644 --- a/system/bta/vc/vc.cc +++ b/system/bta/vc/vc.cc @@ -285,7 +285,7 @@ class VolumeControlImpl : public VolumeControl { if (!csis_api) { DLOG(INFO) << __func__ << " Csis is not available"; callbacks_->OnVolumeStateChanged(device->address, device->volume, - device->mute); + device->mute, true); return; } @@ -294,7 +294,7 @@ class VolumeControlImpl : public VolumeControl { if (group_id == bluetooth::groups::kGroupUnknown) { DLOG(INFO) << __func__ << " No group for device " << device->address; callbacks_->OnVolumeStateChanged(device->address, device->volume, - device->mute); + device->mute, true); return; } @@ -310,7 +310,7 @@ class VolumeControlImpl : public VolumeControl { if (is_volume_change) { std::vector<uint8_t> arg({device->volume}); - PrepareVolumeControlOperation(devices, group_id, + PrepareVolumeControlOperation(devices, group_id, true, kControlPointOpcodeSetAbsoluteVolume, arg); } @@ -318,7 +318,7 @@ class VolumeControlImpl : public VolumeControl { std::vector<uint8_t> arg; uint8_t opcode = device->mute ? kControlPointOpcodeMute : kControlPointOpcodeUnmute; - PrepareVolumeControlOperation(devices, group_id, opcode, arg); + PrepareVolumeControlOperation(devices, group_id, true, opcode, arg); } StartQueueOperation(); @@ -354,7 +354,7 @@ class VolumeControlImpl : public VolumeControl { /* This is just a read, send single notification */ if (!is_notification) { callbacks_->OnVolumeStateChanged(device->address, device->volume, - device->mute); + device->mute, false); return; } @@ -384,12 +384,15 @@ class VolumeControlImpl : public VolumeControl { return; } - if (op->IsGroupOperation()) + if (op->IsGroupOperation()) { callbacks_->OnGroupVolumeStateChanged(op->group_id_, device->volume, - device->mute); - else + device->mute, op->is_autonomous_); + } else { + /* op->is_autonomous_ will always be false, + since we only make it true for group operations */ callbacks_->OnVolumeStateChanged(device->address, device->volume, - device->mute); + device->mute, false); + } ongoing_operations_.erase(op); StartQueueOperation(); @@ -591,14 +594,16 @@ class VolumeControlImpl : public VolumeControl { } void PrepareVolumeControlOperation(std::vector<RawAddress>& devices, - int group_id, uint8_t opcode, + int group_id, bool is_autonomous, + uint8_t opcode, std::vector<uint8_t>& arguments) { DLOG(INFO) << __func__ << " num of devices: " << devices.size() - << " group_id: " << group_id << " opcode: " << +opcode + << " group_id: " << group_id << " is_autonomous: " << is_autonomous + << " opcode: " << +opcode << " arg size: " << arguments.size(); - ongoing_operations_.emplace_back(latest_operation_id_++, group_id, opcode, - arguments, devices); + ongoing_operations_.emplace_back(latest_operation_id_++, group_id, is_autonomous, + opcode, arguments, devices); } void SetVolume(std::variant<RawAddress, int> addr_or_group_id, @@ -613,7 +618,7 @@ class VolumeControlImpl : public VolumeControl { std::vector<RawAddress> devices = { std::get<RawAddress>(addr_or_group_id)}; - PrepareVolumeControlOperation(devices, bluetooth::groups::kGroupUnknown, + PrepareVolumeControlOperation(devices, bluetooth::groups::kGroupUnknown, false, opcode, arg); } else { /* Handle group change */ @@ -641,7 +646,7 @@ class VolumeControlImpl : public VolumeControl { return; } - PrepareVolumeControlOperation(devices, group_id, opcode, arg); + PrepareVolumeControlOperation(devices, group_id, false, opcode, arg); } StartQueueOperation(); @@ -681,7 +686,7 @@ class VolumeControlImpl : public VolumeControl { // once profile connected we can notify current states callbacks_->OnVolumeStateChanged(device->address, device->volume, - device->mute); + device->mute, false); device->EnqueueRemainingRequests(gatt_if_, chrc_read_callback_static, OnGattWriteCccStatic); diff --git a/system/bta/vc/vc_test.cc b/system/bta/vc/vc_test.cc index 41d4f20117..c4ccaa97d9 100644 --- a/system/bta/vc/vc_test.cc +++ b/system/bta/vc/vc_test.cc @@ -71,10 +71,10 @@ class MockVolumeControlCallbacks : public VolumeControlCallbacks { MOCK_METHOD((void), OnConnectionState, (ConnectionState state, const RawAddress& address), (override)); MOCK_METHOD((void), OnVolumeStateChanged, - (const RawAddress& address, uint8_t volume, bool mute), + (const RawAddress& address, uint8_t volume, bool mute, bool isAutonomous), (override)); MOCK_METHOD((void), OnGroupVolumeStateChanged, - (int group_id, uint8_t volume, bool mute), (override)); + (int group_id, uint8_t volume, bool mute, bool isAutonomous), (override)); private: DISALLOW_COPY_AND_ASSIGN(MockVolumeControlCallbacks); @@ -560,7 +560,7 @@ TEST_F(VolumeControlTest, test_subscribe_vcs_volume_state) { TEST_F(VolumeControlTest, test_read_vcs_volume_state) { const RawAddress test_address = GetTestAddress(0); - EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _)); + EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _, false)); std::vector<uint16_t> handles({0x0021}); TestReadCharacteristic(test_address, 1, handles); } @@ -605,12 +605,12 @@ class VolumeControlCallbackTest : public VolumeControlTest { TEST_F(VolumeControlCallbackTest, test_volume_state_changed) { std::vector<uint8_t> value({0x03, 0x01, 0x02}); - EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, 0x03, true)); + EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, 0x03, true, true)); GetNotificationEvent(0x0021, value); } TEST_F(VolumeControlCallbackTest, test_volume_state_changed_malformed) { - EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _)).Times(0); + EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _, _)).Times(0); std::vector<uint8_t> too_short({0x03, 0x01}); GetNotificationEvent(0x0021, too_short); std::vector<uint8_t> too_long({0x03, 0x01, 0x02, 0x03}); @@ -726,7 +726,7 @@ TEST_F(VolumeControlCsis, test_set_volume) { VolumeControl::Get()->SetVolume(group_id, 10); /* Now inject notification and make sure callback is sent up to Java layer */ - EXPECT_CALL(*callbacks, OnGroupVolumeStateChanged(group_id, 0x03, true)); + EXPECT_CALL(*callbacks, OnGroupVolumeStateChanged(group_id, 0x03, true, false)); std::vector<uint8_t> value({0x03, 0x01, 0x02}); GetNotificationEvent(conn_id_1, test_address_1, 0x0021, value); @@ -735,7 +735,7 @@ TEST_F(VolumeControlCsis, test_set_volume) { TEST_F(VolumeControlCsis, autonomus_test_set_volume) { /* Now inject notification and make sure callback is sent up to Java layer */ - EXPECT_CALL(*callbacks, OnGroupVolumeStateChanged(group_id, 0x03, false)); + EXPECT_CALL(*callbacks, OnGroupVolumeStateChanged(group_id, 0x03, false, true)); std::vector<uint8_t> value({0x03, 0x00, 0x02}); GetNotificationEvent(conn_id_1, test_address_1, 0x0021, value); diff --git a/system/btif/src/btif_av.cc b/system/btif/src/btif_av.cc index b2fc783c32..e67722156f 100644 --- a/system/btif/src/btif_av.cc +++ b/system/btif/src/btif_av.cc @@ -2320,6 +2320,15 @@ bool BtifAvStateMachine::StateClosing::ProcessEvent(uint32_t event, btif_a2dp_on_offload_started(peer_.PeerAddress(), BTA_AV_FAIL); break; + case BTIF_AV_CONNECT_REQ_EVT: + BTIF_TRACE_WARNING("%s: Peer %s : Ignore %s in StateClosing", + __PRETTY_FUNCTION__, + peer_.PeerAddress().ToString().c_str(), + BtifAvEvent::EventName(event).c_str()); + btif_queue_advance(); + peer_.StateMachine().TransitionTo(BtifAvStateMachine::kStateIdle); + break; + default: BTIF_TRACE_WARNING("%s: Peer %s : Unhandled event=%s", __PRETTY_FUNCTION__, diff --git a/system/btif/src/btif_vc.cc b/system/btif/src/btif_vc.cc index 66374e215e..61ecb20172 100644 --- a/system/btif/src/btif_vc.cc +++ b/system/btif/src/btif_vc.cc @@ -55,21 +55,21 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, } void OnVolumeStateChanged(const RawAddress& address, uint8_t volume, - bool mute) override { - DVLOG(2) << __func__ << " address: " << address << "volume: " << volume - << "mute: " << mute; + bool mute, bool isAutonomous) override { + DVLOG(2) << __func__ << " address: " << address << " volume: " << volume + << " mute: " << mute << " isAutonomous: " << isAutonomous; do_in_jni_thread(FROM_HERE, Bind(&VolumeControlCallbacks::OnVolumeStateChanged, - Unretained(callbacks_), address, volume, mute)); + Unretained(callbacks_), address, volume, mute, isAutonomous)); } void OnGroupVolumeStateChanged(int group_id, uint8_t volume, - bool mute) override { - DVLOG(2) << __func__ << "group_id: " << group_id << "volume: " << volume - << "mute: " << mute; + bool mute, bool isAutonomous) override { + DVLOG(2) << __func__ << " group_id: " << group_id << " volume: " << volume + << " mute: " << mute << " isAutonomous: " << isAutonomous; do_in_jni_thread(FROM_HERE, Bind(&VolumeControlCallbacks::OnGroupVolumeStateChanged, - Unretained(callbacks_), group_id, volume, mute)); + Unretained(callbacks_), group_id, volume, mute, isAutonomous)); } void Connect(const RawAddress& address) override { diff --git a/system/gd/rust/facade/src/main.rs b/system/gd/rust/facade/src/main.rs index 55cfb0ca8d..3ce456cdff 100644 --- a/system/gd/rust/facade/src/main.rs +++ b/system/gd/rust/facade/src/main.rs @@ -14,10 +14,7 @@ use futures::stream::StreamExt; use grpcio::*; use log::debug; use nix::sys::signal; -use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::sync::{Arc, Mutex}; -use tokio::io::AsyncWriteExt; -use tokio::net::TcpStream; use tokio::runtime::Runtime; fn main() { @@ -51,7 +48,6 @@ async fn async_main(rt: Arc<Runtime>, mut sigint: mpsc::UnboundedReceiver<()>) { let root_server_port = value_t!(matches, "root-server-port", u16).unwrap(); let grpc_port = value_t!(matches, "grpc-port", u16).unwrap(); - let signal_port = value_t!(matches, "signal-port", u16).unwrap(); let rootcanal_port = value_t!(matches, "rootcanal-port", u16).ok(); let env = Arc::new(Environment::new(2)); let mut server = ServerBuilder::new(env) @@ -66,17 +62,10 @@ async fn async_main(rt: Arc<Runtime>, mut sigint: mpsc::UnboundedReceiver<()>) { .unwrap(); server.start(); - indicate_started(signal_port).await; sigint.next().await; block_on(server.shutdown()).unwrap(); } -async fn indicate_started(signal_port: u16) { - let address = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), signal_port); - let mut stream = TcpStream::connect(address).await.unwrap(); - stream.shutdown().await.unwrap(); -} - // TODO: remove as this is a temporary nix-based hack to catch SIGINT fn install_sigint() -> mpsc::UnboundedReceiver<()> { let (tx, rx) = mpsc::unbounded(); diff --git a/system/include/hardware/bt_vc.h b/system/include/hardware/bt_vc.h index fb0b725fac..e7f498b6cb 100644 --- a/system/include/hardware/bt_vc.h +++ b/system/include/hardware/bt_vc.h @@ -42,11 +42,11 @@ class VolumeControlCallbacks { /* Callback for the volume change changed on the device */ virtual void OnVolumeStateChanged(const RawAddress& address, uint8_t volume, - bool mute) = 0; + bool mute, bool isAutonomous) = 0; /* Callback for the volume change changed on the group*/ virtual void OnGroupVolumeStateChanged(int group_id, uint8_t volume, - bool mute) = 0; + bool mute, bool isAutonomous) = 0; }; class VolumeControlInterface { |