// // Copyright 2015 Google, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "service/hal/bluetooth_avrcp_interface.h" #include #include #include #include #include "abstract_observer_list.h" #include "service/hal/bluetooth_interface.h" #include "service/logging_helpers.h" using std::lock_guard; using std::mutex; using std::shared_lock; using std::unique_lock; #if defined(OS_GENERIC) && defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION < 3500) using shared_mutex_impl = std::shared_mutex; #else using shared_mutex_impl = std::shared_timed_mutex; #endif namespace bluetooth { namespace hal { namespace { // The global BluetoothAvrcpInterface instance. BluetoothAvrcpInterface* g_interface = nullptr; // Mutex used by callbacks to access |g_interface|. If we initialize or clean it // use unique_lock. If only accessing |g_interface| use shared lock. // TODO(jpawlowski): this should be just shared_mutex, as we currently don't use // timed methods. Change to shared_mutex when we upgrade to C++14 shared_mutex_impl g_instance_lock; // Helper for obtaining the observer lists. This is forward declared here // and defined below since it depends on BluetoothInterfaceImpl. btbase::AbstractObserverList* GetTargetObservers(); btbase::AbstractObserverList* GetControlObservers(); #define VERIFY_INTERFACE_OR_RETURN() \ do { \ if (!g_interface) { \ LOG(WARNING) << "Callback received while |g_interface| is NULL"; \ return; \ } \ } while (0) void RemoteFeaturesCallback(const RawAddress& bd_addr, btrc_remote_features_t features) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.RemoteFeaturesCallback(bd_addr, features); } } void GetPlayStatusCallback(const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.GetPlayStatusCallback(bd_addr); } } void ListPlayerAppAttrCallback(const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.ListPlayerAppAttrCallback(bd_addr); } } void ListPlayerAppValuesCallback(btrc_player_attr_t attr_id, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.ListPlayerAppValuesCallback(attr_id, bd_addr); } } void GetPlayerAppValueCallback(uint8_t num_attr, btrc_player_attr_t* p_attrs, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.GetPlayerAppValueCallback(num_attr, p_attrs, bd_addr); } } void GetPlayerAppAttrsTextCallback(uint8_t num_attr, btrc_player_attr_t* p_attrs, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.GetPlayerAppAttrsTextCallback(num_attr, p_attrs, bd_addr); } } void GetPlayerAppValuesTextCallback(uint8_t attr_id, uint8_t num_val, uint8_t* p_vals, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.GetPlayerAppValuesTextCallback(attr_id, num_val, p_vals, bd_addr); } } void SetPlayerAppValueCallback(btrc_player_settings_t* p_vals, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.SetPlayerAppValueCallback(p_vals, bd_addr); } } void GetElementAttrCallback(uint8_t num_attr, btrc_media_attr_t* p_attrs, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.GetElementAttrCallback(num_attr, p_attrs, bd_addr); } } void RegisterNotificationCallback(btrc_event_id_t event_id, uint32_t param, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.RegisterNotificationCallback(event_id, param, bd_addr); } } void VolumeChangeCallback(uint8_t volume, uint8_t ctype, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.VolumeChangeCallback(volume, ctype, bd_addr); } } void PassthroughCmdCallback(int id, int key_state, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.PassthroughCmdCallback(id, key_state, bd_addr); } } void SetAddressedPlayerCallback(uint16_t player_id, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.SetAddressedPlayerCallback(player_id, bd_addr); } } void SetBrowsedPlayerCallback(uint16_t player_id, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.SetBrowsedPlayerCallback(player_id, bd_addr); } } void GetFolderItemsCallback(uint8_t scope, uint32_t start_item, uint32_t end_item, uint8_t num_attr, uint32_t* p_attr_ids, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.GetFolderItemsCallback(scope, start_item, end_item, num_attr, p_attr_ids, bd_addr); } } void ChangePathCallback(uint8_t direction, uint8_t* folder_uid, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.ChangePathCallback(direction, folder_uid, bd_addr); } } void GetItemAttrCallback(uint8_t scope, uint8_t* uid, uint16_t uid_counter, uint8_t num_attr, btrc_media_attr_t* p_attrs, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.GetItemAttrCallback(scope, uid, uid_counter, num_attr, p_attrs, bd_addr); } } void PlayItemCallback(uint8_t scope, uint16_t uid_counter, uint8_t* uid, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.PlayItemCallback(scope, uid_counter, uid, bd_addr); } } void GetTotalNumOfItemsCallback(uint8_t scope, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.GetTotalNumOfItemsCallback(scope, bd_addr); } } void SearchCallback(uint16_t charset_id, uint16_t str_len, uint8_t* p_str, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.SearchCallback(str_len, p_str, bd_addr); } } void AddToNowPlayingCallback(uint8_t scope, uint8_t* uid, uint16_t uid_counter, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetTargetObservers()) { observer.AddToNowPlayingCallback(scope, uid, uid_counter, bd_addr); } } void PassthroughRspCallback(const RawAddress& bd_addr, int id, int key_state) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.PassthroughRspCallback(bd_addr, id, key_state); } } void GroupnavigationRspCallback(int id, int key_state) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.GroupnavigationRspCallback(id, key_state); } } void ConnectionStateCallback(bool rc_connect, bool bt_connect, const RawAddress& bd_addr) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.ConnectionStateCallback(rc_connect, bt_connect, bd_addr); } } void CtrlGetrcfeaturesCallback(const RawAddress& bd_addr, int features) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.CtrlGetrcfeaturesCallback(bd_addr, features); } } void CtrlSetplayerapplicationsettingRspCallback(const RawAddress& bd_addr, uint8_t accepted) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.CtrlSetplayerapplicationsettingRspCallback(bd_addr, accepted); } } void CtrlPlayerapplicationsettingCallback( const RawAddress& bd_addr, uint8_t num_attr, btrc_player_app_attr_t* app_attrs, uint8_t num_ext_attr, btrc_player_app_ext_attr_t* ext_attrs) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.CtrlPlayerapplicationsettingCallback(bd_addr, num_attr, app_attrs, num_ext_attr, ext_attrs); } } void CtrlPlayerapplicationsettingChangedCallback( const RawAddress& bd_addr, const btrc_player_settings_t& vals) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.CtrlPlayerapplicationsettingChangedCallback(bd_addr, vals); } } void CtrlSetabsvolCmdCallback(const RawAddress& bd_addr, uint8_t abs_vol, uint8_t label) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.CtrlSetabsvolCmdCallback(bd_addr, abs_vol, label); } } void CtrlRegisternotificationAbsVolCallback(const RawAddress& bd_addr, uint8_t label) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.CtrlRegisternotificationAbsVolCallback(bd_addr, label); } } void CtrlTrackChangedCallback(const RawAddress& bd_addr, uint8_t num_attr, btrc_element_attr_val_t* p_attrs) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.CtrlTrackChangedCallback(bd_addr, num_attr, p_attrs); } } void CtrlPlayPositionChangedCallback(const RawAddress& bd_addr, uint32_t song_len, uint32_t song_pos) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.CtrlPlayPositionChangedCallback(bd_addr, song_len, song_pos); } } void CtrlPlayStatusChangedCallback(const RawAddress& bd_addr, btrc_play_status_t play_status) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.CtrlPlayStatusChangedCallback(bd_addr, play_status); } } void CtrlGetFolderItemsCallback(const RawAddress& bd_addr, btrc_status_t status, const btrc_folder_items_t* folder_items, uint8_t count) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.CtrlGetFolderItemsCallback(bd_addr, status, folder_items, count); } } void CtrlChangePathCallback(const RawAddress& bd_addr, uint32_t count) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.CtrlChangePathCallback(bd_addr, count); } } void CtrlSetBrowsedPlayerCallback(const RawAddress& bd_addr, uint8_t num_items, uint8_t depth) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.CtrlSetBrowsedPlayerCallback(bd_addr, num_items, depth); } } void CtrlSetAddressedPlayerCallback(const RawAddress& bd_addr, uint8_t status) { shared_lock lock(g_instance_lock); VLOG(2) << __func__; VERIFY_INTERFACE_OR_RETURN(); for (auto& observer : *GetControlObservers()) { observer.CtrlSetAddressedPlayerCallback(bd_addr, status); } } btrc_callbacks_t target_callbacks = { .size = sizeof(btrc_callbacks_t), .remote_features_cb = RemoteFeaturesCallback, .get_play_status_cb = GetPlayStatusCallback, .list_player_app_attr_cb = ListPlayerAppAttrCallback, .list_player_app_values_cb = ListPlayerAppValuesCallback, .get_player_app_value_cb = GetPlayerAppValueCallback, .get_player_app_attrs_text_cb = GetPlayerAppAttrsTextCallback, .get_player_app_values_text_cb = GetPlayerAppValuesTextCallback, .set_player_app_value_cb = SetPlayerAppValueCallback, .get_element_attr_cb = GetElementAttrCallback, .register_notification_cb = RegisterNotificationCallback, .volume_change_cb = VolumeChangeCallback, .passthrough_cmd_cb = PassthroughCmdCallback, .set_addressed_player_cb = SetAddressedPlayerCallback, .set_browsed_player_cb = SetBrowsedPlayerCallback, .get_folder_items_cb = GetFolderItemsCallback, .change_path_cb = ChangePathCallback, .get_item_attr_cb = GetItemAttrCallback, .play_item_cb = PlayItemCallback, .get_total_num_of_items_cb = GetTotalNumOfItemsCallback, .search_cb = SearchCallback, .add_to_now_playing_cb = AddToNowPlayingCallback, }; btrc_ctrl_callbacks_t control_callbacks = { .size = sizeof(btrc_ctrl_callbacks_t), .passthrough_rsp_cb = PassthroughRspCallback, .groupnavigation_rsp_cb = GroupnavigationRspCallback, .connection_state_cb = ConnectionStateCallback, .getrcfeatures_cb = CtrlGetrcfeaturesCallback, .setplayerappsetting_rsp_cb = CtrlSetplayerapplicationsettingRspCallback, .playerapplicationsetting_cb = CtrlPlayerapplicationsettingCallback, .playerapplicationsetting_changed_cb = CtrlPlayerapplicationsettingChangedCallback, .setabsvol_cmd_cb = CtrlSetabsvolCmdCallback, .registernotification_absvol_cb = CtrlRegisternotificationAbsVolCallback, .track_changed_cb = CtrlTrackChangedCallback, .play_position_changed_cb = CtrlPlayPositionChangedCallback, .play_status_changed_cb = CtrlPlayStatusChangedCallback, .get_folder_items_cb = CtrlGetFolderItemsCallback, .change_folder_path_cb = CtrlChangePathCallback, .set_browsed_player_cb = CtrlSetBrowsedPlayerCallback, .set_addressed_player_cb = CtrlSetAddressedPlayerCallback, }; } // namespace // BluetoothAvrcpInterface implementation for production. class BluetoothAvrcpInterfaceImpl : public BluetoothAvrcpInterface { public: BluetoothAvrcpInterfaceImpl() : control_iface_(nullptr) {} ~BluetoothAvrcpInterfaceImpl() override { if (control_iface_) control_iface_->cleanup(); } bool AvrcpControlEnable() override { if (control_enabled_) { return true; } if (control_iface_->init(&control_callbacks) != BT_STATUS_SUCCESS) { LOG(ERROR) << "Failed to initialize HAL AVRCP control interface"; return false; } control_enabled_ = true; return true; } void AvrcpControlDisable() override { if (!control_enabled_) { return; } control_iface_->cleanup(); control_enabled_ = false; } bool AvrcpTargetEnable() override { if (target_enabled_) { return true; } if (target_iface_->init(&target_callbacks) != BT_STATUS_SUCCESS) { LOG(ERROR) << "Failed to initialize HAL AVRCP target interface"; return false; } target_enabled_ = true; return true; } void AvrcpTargetDisable() override { if (!target_enabled_) { return; } target_iface_->cleanup(); target_enabled_ = false; } void AddTargetObserver(TargetObserver* observer) override { target_observers_.AddObserver(observer); } void RemoveTargetObserver(TargetObserver* observer) override { target_observers_.RemoveObserver(observer); } void AddControlObserver(ControlObserver* observer) override { control_observers_.AddObserver(observer); } void RemoveControlObserver(ControlObserver* observer) override { control_observers_.RemoveObserver(observer); } const btrc_interface_t* GetTargetHALInterface() const override { return target_iface_; } const btrc_ctrl_interface_t* GetControlHALInterface() const override { return control_iface_; } // Initialize the interface. bool Initialize() { const bt_interface_t* bt_iface = BluetoothInterface::Get()->GetHALInterface(); CHECK(bt_iface); auto* target_iface = reinterpret_cast( bt_iface->get_profile_interface(BT_PROFILE_AV_RC_ID)); if (!target_iface) { LOG(ERROR) << "Failed to obtain HAL AVRCP target interface handle"; return false; } auto* control_iface = reinterpret_cast( bt_iface->get_profile_interface(BT_PROFILE_AV_RC_CTRL_ID)); if (!control_iface) { LOG(ERROR) << "Failed to obtain HAL AVRCP control interface handle"; return false; } control_iface_ = control_iface; target_iface_ = target_iface; // Only initialize the control interface. return AvrcpControlEnable(); } btbase::AbstractObserverList* target_observers() { return &target_observers_; } btbase::AbstractObserverList* control_observers() { return &control_observers_; } private: // List of observers that are interested in notifications from us. // We're not using a base::ObserverListThreadSafe, which it posts observer // events automatically on the origin threads, as we want to avoid that // overhead and simply forward the events to the upper layer. btbase::AbstractObserverList target_observers_; btbase::AbstractObserverList control_observers_; // The HAL handle obtained from the shared library. We hold a weak reference // to this since the actual data resides in the shared Bluetooth library. const btrc_interface_t* target_iface_ = nullptr; const btrc_ctrl_interface_t* control_iface_ = nullptr; bool control_enabled_ = false; bool target_enabled_ = false; DISALLOW_COPY_AND_ASSIGN(BluetoothAvrcpInterfaceImpl); }; namespace { btbase::AbstractObserverList* GetTargetObservers() { CHECK(g_interface); return static_cast(g_interface) ->target_observers(); } btbase::AbstractObserverList* GetControlObservers() { CHECK(g_interface); return static_cast(g_interface) ->control_observers(); } } // namespace void BluetoothAvrcpInterface::TargetObserver::RemoteFeaturesCallback( const RawAddress& bd_addr, btrc_remote_features_t features) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::GetPlayStatusCallback( const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::ListPlayerAppAttrCallback( const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::ListPlayerAppValuesCallback( btrc_player_attr_t attr_id, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::GetPlayerAppValueCallback( uint8_t num_attr, btrc_player_attr_t* p_attrs, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::GetPlayerAppAttrsTextCallback( uint8_t num_attr, btrc_player_attr_t* p_attrs, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::GetPlayerAppValuesTextCallback( uint8_t attr_id, uint8_t num_val, uint8_t* p_vals, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::SetPlayerAppValueCallback( btrc_player_settings_t* p_vals, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::GetElementAttrCallback( uint8_t num_attr, btrc_media_attr_t* p_attrs, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::RegisterNotificationCallback( btrc_event_id_t event_id, uint32_t param, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::VolumeChangeCallback( uint8_t volume, uint8_t ctype, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::PassthroughCmdCallback( int id, int key_state, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::SetAddressedPlayerCallback( uint16_t player_id, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::SetBrowsedPlayerCallback( uint16_t player_id, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::GetFolderItemsCallback( uint8_t scope, uint32_t start_item, uint32_t end_item, uint8_t num_attr, uint32_t* p_attr_ids, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::ChangePathCallback( uint8_t direction, uint8_t* folder_uid, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::GetItemAttrCallback( uint8_t scope, uint8_t* uid, uint16_t uid_counter, uint8_t num_attr, btrc_media_attr_t* p_attrs, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::PlayItemCallback( uint8_t scope, uint16_t uid_counter, uint8_t* uid, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::GetTotalNumOfItemsCallback( uint8_t scope, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::SearchCallback( uint16_t str_len, uint8_t* p_str, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::TargetObserver::AddToNowPlayingCallback( uint8_t scope, uint8_t* uid, uint16_t uid_counter, const RawAddress& bd_addr) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver::PassthroughRspCallback( const RawAddress& /* bd_addr */, int /* id */, int /* key_state */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver::GroupnavigationRspCallback( int /* id */, int /* key_state */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver::ConnectionStateCallback( bool /* rc_connect */, bool /* bt_connect */, const RawAddress& /* bd_addr */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver::CtrlGetrcfeaturesCallback( const RawAddress& /* bd_addr */, int /* features */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver:: CtrlSetplayerapplicationsettingRspCallback(const RawAddress& /* bd_addr */, uint8_t /* accepted */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver:: CtrlPlayerapplicationsettingCallback( const RawAddress& /* bd_addr */, uint8_t /* num_attr */, btrc_player_app_attr_t* /* app_attrs */, uint8_t /* num_ext_attr */, btrc_player_app_ext_attr_t* /* ext_attrs */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver:: CtrlPlayerapplicationsettingChangedCallback( const RawAddress& /* bd_addr*/, const btrc_player_settings_t& /* vals */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver::CtrlSetabsvolCmdCallback( const RawAddress& /* bd_addr */, uint8_t /* abs_vol */, uint8_t /* label */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver:: CtrlRegisternotificationAbsVolCallback(const RawAddress& /* bd_addr */, uint8_t /* label */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver::CtrlTrackChangedCallback( const RawAddress& /*bd_addr */, uint8_t /* num_attr */, btrc_element_attr_val_t* /* p_attrs */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver::CtrlPlayPositionChangedCallback( const RawAddress& /* bd_addr */, uint32_t /* song_len */, uint32_t /* song_pos */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver::CtrlPlayStatusChangedCallback( const RawAddress& /* bd_addr */, btrc_play_status_t /* play_status */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver::CtrlGetFolderItemsCallback( const RawAddress& /* bd_addr */, btrc_status_t /* status */, const btrc_folder_items_t* /*folder_items */, uint8_t /* count */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver::CtrlChangePathCallback( const RawAddress& /* bd_addr */, uint32_t /* count */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver::CtrlSetBrowsedPlayerCallback( const RawAddress& /* bd_addr */, uint8_t /* num_items */, uint8_t /* depth */) { // Do nothing. } void BluetoothAvrcpInterface::ControlObserver::CtrlSetAddressedPlayerCallback( const RawAddress& /* bd_addr */, uint8_t /* status */) { // Do nothing. } // static bool BluetoothAvrcpInterface::Initialize() { unique_lock lock(g_instance_lock); CHECK(!g_interface); std::unique_ptr impl( new BluetoothAvrcpInterfaceImpl()); if (!impl->Initialize()) { LOG(ERROR) << "Failed to initialize BluetoothAvrcpInterface"; return false; } g_interface = impl.release(); return true; } // static void BluetoothAvrcpInterface::CleanUp() { unique_lock lock(g_instance_lock); CHECK(g_interface); delete g_interface; g_interface = nullptr; } // static bool BluetoothAvrcpInterface::IsInitialized() { shared_lock lock(g_instance_lock); return g_interface != nullptr; } // static BluetoothAvrcpInterface* BluetoothAvrcpInterface::Get() { shared_lock lock(g_instance_lock); CHECK(g_interface); return g_interface; } // static void BluetoothAvrcpInterface::InitializeForTesting( BluetoothAvrcpInterface* test_instance) { unique_lock lock(g_instance_lock); CHECK(test_instance); CHECK(!g_interface); g_interface = test_instance; } } // namespace hal } // namespace bluetooth