aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-06-07 07:23:24 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-06-07 07:23:24 +0000
commit7101b2be6a3a1b9bb19d2b90eac0d6227a441e0a (patch)
treee07c4021fcb2fc124424d03cb60d604d28f2832b
parenta1a1412af1cc50f26ac6c59341e43a730d2888e4 (diff)
parent99428a2cf3b7d7e1d7950918462cd9938e5792f2 (diff)
downloadbt-7101b2be6a3a1b9bb19d2b90eac0d6227a441e0a.tar.gz
Snap for 4826885 from 99428a2cf3b7d7e1d7950918462cd9938e5792f2 to pi-release
Change-Id: I139ee39202fc51350a44decb0cddd01e3d01e2bf
-rw-r--r--btif/avrcp/avrcp_service.cc88
-rw-r--r--btif/avrcp/avrcp_service.h11
-rw-r--r--btif/src/btif_a2dp_source.cc4
3 files changed, 57 insertions, 46 deletions
diff --git a/btif/avrcp/avrcp_service.cc b/btif/avrcp/avrcp_service.cc
index 26b826cf9..8c22365b2 100644
--- a/btif/avrcp/avrcp_service.cc
+++ b/btif/avrcp/avrcp_service.cc
@@ -282,19 +282,11 @@ class VolumeInterfaceWrapper : public VolumeInterface {
void AvrcpService::Init(MediaInterface* media_interface,
VolumeInterface* volume_interface) {
LOG(INFO) << "AVRCP Target Service started";
- if (instance_ == nullptr) {
- instance_ = new AvrcpService();
- }
-
- {
- std::lock_guard<std::mutex> lock(jni_mutex_);
- 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)
- instance_->media_interface_ = new MediaInterfaceWrapper(media_interface);
+ media_interface_ = new MediaInterfaceWrapper(media_interface);
media_interface->RegisterUpdateCallback(instance_);
VolumeInterfaceWrapper* wrapped_volume_interface = nullptr;
@@ -302,28 +294,23 @@ void AvrcpService::Init(MediaInterface* media_interface,
wrapped_volume_interface = new VolumeInterfaceWrapper(volume_interface);
}
- instance_->volume_interface_ = wrapped_volume_interface;
+ volume_interface_ = wrapped_volume_interface;
ConnectionHandler::Initialize(
base::Bind(&AvrcpService::DeviceCallback, base::Unretained(instance_)),
&avrcp_interface_, &sdp_interface_, wrapped_volume_interface);
- instance_->connection_handler_ = ConnectionHandler::Get();
+ connection_handler_ = ConnectionHandler::Get();
}
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;
- if (instance_->volume_interface_ != nullptr) {
- delete instance_->volume_interface_;
+ connection_handler_->CleanUp();
+ connection_handler_ = nullptr;
+ if (volume_interface_ != nullptr) {
+ delete volume_interface_;
}
- delete instance_->media_interface_;
+ delete media_interface_;
}
AvrcpService* AvrcpService::Get() {
@@ -339,15 +326,15 @@ ServiceInterface* AvrcpService::GetServiceInterface() {
return service_interface_;
}
-bool AvrcpService::ConnectDevice(const RawAddress& bdaddr) {
+void AvrcpService::ConnectDevice(const RawAddress& bdaddr) {
LOG(INFO) << __PRETTY_FUNCTION__ << ": address=" << bdaddr.ToString();
- return connection_handler_->ConnectDevice(bdaddr);
+ connection_handler_->ConnectDevice(bdaddr);
}
-bool AvrcpService::DisconnectDevice(const RawAddress& bdaddr) {
+void AvrcpService::DisconnectDevice(const RawAddress& bdaddr) {
LOG(INFO) << __PRETTY_FUNCTION__ << ": address=" << bdaddr.ToString();
- return connection_handler_->DisconnectDevice(bdaddr);
+ connection_handler_->DisconnectDevice(bdaddr);
}
void AvrcpService::SendMediaUpdate(bool track_changed, bool play_state,
@@ -398,37 +385,62 @@ void AvrcpService::DeviceCallback(std::shared_ptr<Device> new_device) {
// Service Interface
void AvrcpService::ServiceInterfaceImpl::Init(
- MediaInterface* mediaInterface, VolumeInterface* volume_interface) {
- // TODO (apanicke): Run this in a message loop. This currently works though
- // since the underlying AVRC_API will correctly run this in a message loop so
- // no race conditions can occur, but if that changes it could change the
- // behaviour here.
+ MediaInterface* media_interface, VolumeInterface* volume_interface) {
+ std::lock_guard<std::mutex> lock(service_interface_lock_);
+
+ // TODO: This function should block until the service is completely up so
+ // that its possible to call Get() on the service immediately after calling
+ // init without issues.
+
CHECK(instance_ == nullptr);
+ instance_ = new AvrcpService();
+
+ {
+ std::lock_guard<std::mutex> jni_lock(jni_mutex_);
+ jni_message_loop_ = get_jni_message_loop();
+ }
- AvrcpService::Init(mediaInterface, volume_interface);
+ do_in_bta_thread(FROM_HERE,
+ base::Bind(&AvrcpService::Init, base::Unretained(instance_),
+ media_interface, volume_interface));
}
bool AvrcpService::ServiceInterfaceImpl::ConnectDevice(
const RawAddress& bdaddr) {
- // TODO (apanicke): Same as above
+ std::lock_guard<std::mutex> lock(service_interface_lock_);
CHECK(instance_ != nullptr);
- return instance_->ConnectDevice(bdaddr);
+ do_in_bta_thread(FROM_HERE, base::Bind(&AvrcpService::ConnectDevice,
+ base::Unretained(instance_), bdaddr));
+ return true;
}
bool AvrcpService::ServiceInterfaceImpl::DisconnectDevice(
const RawAddress& bdaddr) {
- // TODO (apanicke): Same as above
+ std::lock_guard<std::mutex> lock(service_interface_lock_);
CHECK(instance_ != nullptr);
- return instance_->DisconnectDevice(bdaddr);
+ do_in_bta_thread(FROM_HERE, base::Bind(&AvrcpService::DisconnectDevice,
+ base::Unretained(instance_), bdaddr));
+ return true;
}
bool AvrcpService::ServiceInterfaceImpl::Cleanup() {
- // TODO (apanicke): Same as above
+ std::lock_guard<std::mutex> lock(service_interface_lock_);
+
if (instance_ == nullptr) return false;
- instance_->Cleanup();
- delete instance_;
+ {
+ std::lock_guard<std::mutex> jni_lock(jni_mutex_);
+ task_tracker_.TryCancelAll();
+ jni_message_loop_ = nullptr;
+ }
+
+ do_in_bta_thread(FROM_HERE,
+ base::Bind(&AvrcpService::Cleanup, base::Owned(instance_)));
+
+ // Setting instance to nullptr here is fine since it will be deleted on the
+ // other thread.
instance_ = nullptr;
+
return true;
}
diff --git a/btif/avrcp/avrcp_service.h b/btif/avrcp/avrcp_service.h
index 16f8dbf8e..d26b200b2 100644
--- a/btif/avrcp/avrcp_service.h
+++ b/btif/avrcp/avrcp_service.h
@@ -37,9 +37,6 @@ namespace avrcp {
*/
class AvrcpService : public MediaCallbacks {
public:
- static void Init(MediaInterface* media_interface,
- VolumeInterface* volume_interface);
-
/**
* Gets a handle to the AvrcpService
*
@@ -56,10 +53,11 @@ class AvrcpService : public MediaCallbacks {
*/
static ServiceInterface* GetServiceInterface();
+ void Init(MediaInterface* media_interface, VolumeInterface* volume_interface);
void Cleanup();
- bool ConnectDevice(const RawAddress& bdaddr);
- bool DisconnectDevice(const RawAddress& bdaddr);
+ void ConnectDevice(const RawAddress& bdaddr);
+ void DisconnectDevice(const RawAddress& bdaddr);
// Functions inherited from MediaCallbacks in order to receive updates
void SendMediaUpdate(bool track_changed, bool play_state,
@@ -75,6 +73,9 @@ class AvrcpService : public MediaCallbacks {
bool ConnectDevice(const RawAddress& bdaddr) override;
bool DisconnectDevice(const RawAddress& bdaddr) override;
bool Cleanup() override;
+
+ private:
+ std::mutex service_interface_lock_;
};
static void DebugDump(int fd);
diff --git a/btif/src/btif_a2dp_source.cc b/btif/src/btif_a2dp_source.cc
index 70e2522b4..2a4ec8f04 100644
--- a/btif/src/btif_a2dp_source.cc
+++ b/btif/src/btif_a2dp_source.cc
@@ -786,8 +786,6 @@ static void btif_a2dp_source_audio_tx_stop_event(void) {
if (btif_av_is_a2dp_offload_enabled()) return;
- const bool send_ack = btif_a2dp_source_is_streaming();
-
uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2];
uint16_t event;
@@ -814,7 +812,7 @@ static void btif_a2dp_source_audio_tx_stop_event(void) {
* to get the ACK for any pending command in such cases.
*/
- if (send_ack) btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
+ btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
/* audio engine stopped, reset tx suspended flag */
btif_a2dp_source_cb.tx_flush = false;