Loading system/btif/avrcp/avrcp_service.cc +56 −30 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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_; Loading Loading @@ -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)); } Loading @@ -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)); } Loading @@ -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)); } Loading @@ -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)); } Loading @@ -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)); } Loading @@ -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)); } Loading @@ -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)); } Loading @@ -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)); Loading @@ -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)); } Loading @@ -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) Loading @@ -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; Loading system/btif/include/btif_common.h +2 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 Loading system/btif/src/btif_core.cc +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
system/btif/avrcp/avrcp_service.cc +56 −30 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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_; Loading Loading @@ -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)); } Loading @@ -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)); } Loading @@ -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)); } Loading @@ -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)); } Loading @@ -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)); } Loading @@ -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)); } Loading @@ -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)); } Loading @@ -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)); Loading @@ -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)); } Loading @@ -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) Loading @@ -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; Loading
system/btif/include/btif_common.h +2 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 Loading
system/btif/src/btif_core.cc +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading