From 8bdea4b19d0b65331e3a28abf735e49ea99a4e75 Mon Sep 17 00:00:00 2001 From: Ajay Panicker <apanicke@google.com> Date: Tue, 3 Apr 2018 22:28:06 -0700 Subject: [PATCH] Disable absolute volume if the remote device rejects registration Instead of trying to re-register for a rejected volume changed notification, disable absolute volume. This prevents spinning if a remote device continuously rejects all attempts to register. A volume level of -2 will be used to represent that the volume notification was rejected. Bug: 77238060 Test: Run host native test net_test_avrcp Change-Id: I228524fb30348ca691d0792f0c7bcc4653d1fcef --- .../packet/tests/avrcp/avrcp_test_packets.h | 4 +++ system/profile/avrcp/device.cc | 25 ++++++++++++++++--- .../profile/avrcp/tests/avrcp_device_test.cc | 19 ++++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/system/packet/tests/avrcp/avrcp_test_packets.h b/system/packet/tests/avrcp/avrcp_test_packets.h index cd07de375c1..f5c914e2c01 100644 --- a/system/packet/tests/avrcp/avrcp_test_packets.h +++ b/system/packet/tests/avrcp/avrcp_test_packets.h @@ -134,6 +134,10 @@ std::vector<uint8_t> interim_uids_notificaiton = {0x0f, 0x48, 0x00, 0x00, 0x19, std::vector<uint8_t> interim_volume_changed_notification = { 0x0f, 0x48, 0x00, 0x00, 0x19, 0x58, 0x31, 0x00, 0x00, 0x02, 0x0d, 0x47}; +// AVRCP Rejected Volume Changed Notification with volume at 0% +std::vector<uint8_t> rejected_volume_changed_notification = { + 0x0a, 0x48, 0x00, 0x00, 0x19, 0x58, 0x31, 0x00, 0x00, 0x02, 0x0d, 0x00}; + // AVRCP Changed Volume Changed Notification with volume at 55% (0x47) std::vector<uint8_t> changed_volume_changed_notification = { 0x0d, 0x48, 0x00, 0x00, 0x19, 0x58, 0x31, 0x00, 0x00, 0x02, 0x0d, 0x47}; diff --git a/system/profile/avrcp/device.cc b/system/profile/avrcp/device.cc index 734dc241246..e66caa7b075 100644 --- a/system/profile/avrcp/device.cc +++ b/system/profile/avrcp/device.cc @@ -25,6 +25,9 @@ namespace avrcp { #define DEVICE_LOG(LEVEL) LOG(LEVEL) << address_.ToString() << " : " #define DEVICE_VLOG(LEVEL) VLOG(LEVEL) << address_.ToString() << " : " +#define VOL_NOT_SUPPORTED -1 +#define VOL_REGISTRATION_FAILED -2 + Device::Device( const RawAddress& bdaddr, bool avrcp13_compatibility, base::Callback<void(uint8_t label, bool browse, @@ -253,6 +256,14 @@ void Device::HandleVolumeChanged( DEVICE_VLOG(1) << __func__ << ": interim=" << pkt->IsInterim(); if (volume_interface_ == nullptr) return; + if (pkt->GetCType() == CType::REJECTED) { + // Disable Absolute Volume + active_labels_.erase(label); + volume_interface_ = nullptr; + volume_ = VOL_REGISTRATION_FAILED; + return; + } + // We only update on interim and just re-register on changes. if (!pkt->IsInterim()) { active_labels_.erase(label); @@ -261,7 +272,7 @@ void Device::HandleVolumeChanged( } // Handle the first volume update. - if (volume_ == -1) { + if (volume_ == VOL_NOT_SUPPORTED) { volume_ = pkt->GetVolume(); volume_interface_->DeviceConnected( GetAddress(), base::Bind(&Device::SetVolume, base::Unretained(this))); @@ -290,6 +301,7 @@ void Device::SetVolume(int8_t volume) { } } + volume_ = volume; send_message_cb_.Run(label, false, std::move(request)); } @@ -1055,6 +1067,13 @@ void Device::DeviceDisconnected() { volume_interface_->DeviceDisconnected(GetAddress()); } +static std::string volumeToStr(int8_t volume) { + if (volume == VOL_NOT_SUPPORTED) return "Absolute Volume not supported"; + if (volume == VOL_REGISTRATION_FAILED) + return "Volume changed notification was rejected"; + return std::to_string(volume); +} + std::ostream& operator<<(std::ostream& out, const Device& d) { out << "Avrcp Device: Address=" << d.address_.ToString() << std::endl; out << " â”” isActive: " << (d.IsActive() ? "YES" : "NO") << std::endl; @@ -1072,7 +1091,7 @@ std::ostream& operator<<(std::ostream& out, const Device& d) { out << " â”” UIDs Changed: " << d.uids_changed_.first << std::endl; out << " â”” Last Song Sent ID: " << d.last_song_info_.media_id << std::endl; out << " â”” Last Play State: " << d.last_play_status_.state << std::endl; - out << " â”” Current Volume: " << d.volume_ << std::endl; + out << " â”” Current Volume: " << volumeToStr(d.volume_) << std::endl; out << " â”” Current Folder: " << d.CurrentFolder(); out << " â”” Control MTU Size: " << d.ctrl_mtu_ << std::endl; out << " â”” Browse MTU Size: " << d.browse_mtu_ << std::endl; @@ -1083,4 +1102,4 @@ std::ostream& operator<<(std::ostream& out, const Device& d) { } } // namespace avrcp -} // namespace bluetooth \ No newline at end of file +} // namespace bluetooth diff --git a/system/profile/avrcp/tests/avrcp_device_test.cc b/system/profile/avrcp/tests/avrcp_device_test.cc index e9dde53b077..2207bb07cc0 100644 --- a/system/profile/avrcp/tests/avrcp_device_test.cc +++ b/system/profile/avrcp/tests/avrcp_device_test.cc @@ -678,5 +678,24 @@ TEST_F(AvrcpDeviceTest, volumeChangedTest) { SendMessage(1, response); } +TEST_F(AvrcpDeviceTest, volumeRejectedTest) { + MockMediaInterface interface; + NiceMock<MockA2dpInterface> a2dp_interface; + MockVolumeInterface vol_interface; + + test_device->RegisterInterfaces(&interface, &a2dp_interface, &vol_interface); + + auto reg_notif = + RegisterNotificationRequestBuilder::MakeBuilder(Event::VOLUME_CHANGED, 0); + EXPECT_CALL(response_cb, Call(_, false, matchPacket(std::move(reg_notif)))) + .Times(1); + test_device->RegisterVolumeChanged(); + + auto response = TestAvrcpPacket::Make(rejected_volume_changed_notification); + SendMessage(1, response); + + EXPECT_CALL(response_cb, Call(_, _, _)).Times(0); +} + } // namespace avrcp } // namespace bluetooth \ No newline at end of file -- GitLab