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

Commit 3121d902 authored by Ajay Panicker's avatar Ajay Panicker
Browse files

AVRCP: Cancel all pending messages and prevent future messages after cleanup

Bug: 79859133
Test: Regression test and repeatedly turn Bluetooth off and on
Change-Id: I1aa05cc5430dbda1d4bae6aa9543f655baed77b4
parent 8b141c79
Loading
Loading
Loading
Loading
+56 −30
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@

#include <base/bind.h>
#include <base/logging.h>
#include <base/task/cancelable_task_tracker.h>
#include <base/threading/thread.h>
#include <mutex>
#include <sstream>

#include "bta_closure_api.h"
@@ -31,6 +34,22 @@ namespace avrcp {
AvrcpService* AvrcpService::instance_ = nullptr;
AvrcpService::ServiceInterfaceImpl* AvrcpService::service_interface_ = nullptr;

std::mutex jni_mutex_;
base::MessageLoop* jni_message_loop_ = nullptr;
base::CancelableTaskTracker task_tracker_;

void do_in_avrcp_jni(const base::Closure& task) {
  std::lock_guard<std::mutex> lock(jni_mutex_);

  if (jni_message_loop_ == nullptr) {
    LOG(WARNING) << __func__ << ": jni_message_loop_ is null";
    return;
  }

  task_tracker_.PostTask(jni_message_loop_->task_runner().get(), FROM_HERE,
                         task);
}

class A2dpInterfaceImpl : public A2dpInterface {
  RawAddress active_peer() override { return btif_av_source_active_peer(); }
} a2dp_interface_;
@@ -116,7 +135,7 @@ class MediaInterfaceWrapper : public MediaInterface {
  MediaInterfaceWrapper(MediaInterface* cb) : wrapped_(cb){};

  void SendKeyEvent(uint8_t key, KeyState state) override {
    do_in_jni_thread(base::Bind(&MediaInterface::SendKeyEvent,
    do_in_avrcp_jni(base::Bind(&MediaInterface::SendKeyEvent,
                               base::Unretained(wrapped_), key, state));
  }

@@ -127,7 +146,7 @@ class MediaInterfaceWrapper : public MediaInterface {

    auto bound_cb = base::Bind(cb_lambda, info_cb);

    do_in_jni_thread(base::Bind(&MediaInterface::GetSongInfo,
    do_in_avrcp_jni(base::Bind(&MediaInterface::GetSongInfo,
                               base::Unretained(wrapped_), bound_cb));
  }

@@ -138,7 +157,7 @@ class MediaInterfaceWrapper : public MediaInterface {

    auto bound_cb = base::Bind(cb_lambda, status_cb);

    do_in_jni_thread(base::Bind(&MediaInterface::GetPlayStatus,
    do_in_avrcp_jni(base::Bind(&MediaInterface::GetPlayStatus,
                               base::Unretained(wrapped_), bound_cb));
  }

@@ -151,7 +170,7 @@ class MediaInterfaceWrapper : public MediaInterface {

    auto bound_cb = base::Bind(cb_lambda, now_playing_cb);

    do_in_jni_thread(base::Bind(&MediaInterface::GetNowPlayingList,
    do_in_avrcp_jni(base::Bind(&MediaInterface::GetNowPlayingList,
                               base::Unretained(wrapped_), bound_cb));
  }

@@ -164,7 +183,7 @@ class MediaInterfaceWrapper : public MediaInterface {

    auto bound_cb = base::Bind(cb_lambda, list_cb);

    do_in_jni_thread(base::Bind(&MediaInterface::GetMediaPlayerList,
    do_in_avrcp_jni(base::Bind(&MediaInterface::GetMediaPlayerList,
                               base::Unretained(wrapped_), bound_cb));
  }

@@ -177,7 +196,7 @@ class MediaInterfaceWrapper : public MediaInterface {

    auto bound_cb = base::Bind(cb_lambda, folder_cb);

    do_in_jni_thread(base::Bind(&MediaInterface::GetFolderItems,
    do_in_avrcp_jni(base::Bind(&MediaInterface::GetFolderItems,
                               base::Unretained(wrapped_), player_id, media_id,
                               bound_cb));
  }
@@ -191,20 +210,20 @@ class MediaInterfaceWrapper : public MediaInterface {

    auto bound_cb = base::Bind(cb_lambda, browse_cb);

    do_in_jni_thread(base::Bind(&MediaInterface::SetBrowsedPlayer,
    do_in_avrcp_jni(base::Bind(&MediaInterface::SetBrowsedPlayer,
                               base::Unretained(wrapped_), player_id,
                               bound_cb));
  }

  void PlayItem(uint16_t player_id, bool now_playing,
                std::string media_id) override {
    do_in_jni_thread(base::Bind(&MediaInterface::PlayItem,
    do_in_avrcp_jni(base::Bind(&MediaInterface::PlayItem,
                               base::Unretained(wrapped_), player_id,
                               now_playing, media_id));
  }

  void SetActiveDevice(const RawAddress& address) override {
    do_in_jni_thread(base::Bind(&MediaInterface::SetActiveDevice,
    do_in_avrcp_jni(base::Bind(&MediaInterface::SetActiveDevice,
                               base::Unretained(wrapped_), address));
  }

@@ -227,7 +246,7 @@ class VolumeInterfaceWrapper : public VolumeInterface {
  VolumeInterfaceWrapper(VolumeInterface* interface) : wrapped_(interface){};

  void DeviceConnected(const RawAddress& bdaddr) override {
    do_in_jni_thread(
    do_in_avrcp_jni(
        base::Bind(static_cast<void (VolumeInterface::*)(const RawAddress&)>(
                       &VolumeInterface::DeviceConnected),
                   base::Unretained(wrapped_), bdaddr));
@@ -240,19 +259,19 @@ class VolumeInterfaceWrapper : public VolumeInterface {

    auto bound_cb = base::Bind(cb_lambda, cb);

    do_in_jni_thread(base::Bind(static_cast<void (VolumeInterface::*)(
    do_in_avrcp_jni(base::Bind(static_cast<void (VolumeInterface::*)(
                                   const RawAddress&, VolumeChangedCb)>(
                                   &VolumeInterface::DeviceConnected),
                               base::Unretained(wrapped_), bdaddr, bound_cb));
  }

  void DeviceDisconnected(const RawAddress& bdaddr) override {
    do_in_jni_thread(base::Bind(&VolumeInterface::DeviceDisconnected,
    do_in_avrcp_jni(base::Bind(&VolumeInterface::DeviceDisconnected,
                               base::Unretained(wrapped_), bdaddr));
  }

  void SetVolume(int8_t volume) override {
    do_in_jni_thread(base::Bind(&VolumeInterface::SetVolume,
    do_in_avrcp_jni(base::Bind(&VolumeInterface::SetVolume,
                               base::Unretained(wrapped_), volume));
  }

@@ -263,10 +282,13 @@ class VolumeInterfaceWrapper : public VolumeInterface {
void AvrcpService::Init(MediaInterface* media_interface,
                        VolumeInterface* volume_interface) {
  LOG(INFO) << "AVRCP Target Service started";
  std::lock_guard<std::mutex> lock(jni_mutex_);
  if (instance_ == nullptr) {
    instance_ = new AvrcpService();
  }

  jni_message_loop_ = get_jni_message_loop();

  // TODO (apanicke): Add a function that sets up the SDP records once we
  // remove the AVRCP SDP setup in AVDTP (bta_av_main.cc)

@@ -288,6 +310,10 @@ void AvrcpService::Init(MediaInterface* media_interface,

void AvrcpService::Cleanup() {
  LOG(INFO) << "AVRCP Target Service stopped";
  std::lock_guard<std::mutex> lock(jni_mutex_);

  task_tracker_.TryCancelAll();
  jni_message_loop_ = nullptr;

  instance_->connection_handler_->CleanUp();
  instance_->connection_handler_ = nullptr;
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <stdlib.h>

#include <base/bind.h>
#include <base/message_loop/message_loop.h>
#include <base/tracked_objects.h>
#include <hardware/bluetooth.h>

@@ -177,6 +178,7 @@ extern bt_status_t do_in_jni_thread(const base::Closure& task);
extern bt_status_t do_in_jni_thread(const tracked_objects::Location& from_here,
                                    const base::Closure& task);
extern bool is_on_jni_thread();
extern base::MessageLoop* get_jni_message_loop();
/**
 * This template wraps callback into callback that will be executed on jni
 * thread
+2 −0
Original line number Diff line number Diff line
@@ -252,6 +252,8 @@ bool is_on_jni_thread() {
  return btif_thread_id_ == PlatformThread::CurrentId();
}

base::MessageLoop* get_jni_message_loop() { return message_loop_; }

/*******************************************************************************
 *
 * Function         btif_is_dut_mode