Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 16cd94c3 authored by Ajay Panicker's avatar Ajay Panicker Committed by Hansong Zhang
Browse files

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
(cherry picked from commit 8bdea4b1)
parent 67374770
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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};
+22 −3
Original line number Diff line number Diff line
@@ -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;
+19 −0
Original line number Diff line number Diff line
@@ -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