You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

893 lines
29 KiB

//
// 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 <mutex>
#include <shared_mutex>
#include <base/logging.h>
#include <base/observer_list.h>
#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<BluetoothAvrcpInterface::TargetObserver>*
GetTargetObservers();
btbase::AbstractObserverList<BluetoothAvrcpInterface::ControlObserver>*
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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<shared_mutex_impl> 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<const btrc_interface_t*>(
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<const btrc_ctrl_interface_t*>(
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<TargetObserver>* target_observers() {
return &target_observers_;
}
btbase::AbstractObserverList<ControlObserver>* 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<TargetObserver> target_observers_;
btbase::AbstractObserverList<ControlObserver> 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<BluetoothAvrcpInterface::TargetObserver>*
GetTargetObservers() {
CHECK(g_interface);
return static_cast<BluetoothAvrcpInterfaceImpl*>(g_interface)
->target_observers();
}
btbase::AbstractObserverList<BluetoothAvrcpInterface::ControlObserver>*
GetControlObservers() {
CHECK(g_interface);
return static_cast<BluetoothAvrcpInterfaceImpl*>(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<shared_mutex_impl> lock(g_instance_lock);
CHECK(!g_interface);
std::unique_ptr<BluetoothAvrcpInterfaceImpl> 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<shared_mutex_impl> lock(g_instance_lock);
CHECK(g_interface);
delete g_interface;
g_interface = nullptr;
}
// static
bool BluetoothAvrcpInterface::IsInitialized() {
shared_lock<shared_mutex_impl> lock(g_instance_lock);
return g_interface != nullptr;
}
// static
BluetoothAvrcpInterface* BluetoothAvrcpInterface::Get() {
shared_lock<shared_mutex_impl> lock(g_instance_lock);
CHECK(g_interface);
return g_interface;
}
// static
void BluetoothAvrcpInterface::InitializeForTesting(
BluetoothAvrcpInterface* test_instance) {
unique_lock<shared_mutex_impl> lock(g_instance_lock);
CHECK(test_instance);
CHECK(!g_interface);
g_interface = test_instance;
}
} // namespace hal
} // namespace bluetooth