// // Copyright (C) 2017 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/ipc/binder/bluetooth_avrcp_target_binder_server.h" #include <string> #include "base/logging.h" #include "service/adapter.h" #define AIDL_RET(value) \ do { \ *_aidl_return = (value); \ return Status::ok(); \ } while (0) #define TRY_GET_TARGET() \ ({ \ auto target = GetAvrcpTarget(); \ if (!target) { \ LOG(ERROR) << __func__ << ": " \ << "Failed to get AVRCP target interface"; \ AIDL_RET(false); \ } \ target; \ }) #define TRY_GET_CB() \ ({ \ auto cb = GetAvrcpTargetCallback(); \ if (!cb.get()) { \ LOG(WARNING) << "Callback for AVRCP target was deleted"; \ return; \ } \ cb; \ }) #define TRY_RET(expr, msg) \ do { \ if (!(expr)) { \ LOG(ERROR) << msg; \ AIDL_RET(false); \ } \ AIDL_RET(true); \ } while (0) #define TRY_RET_FUNC(expr) TRY_RET(expr, __func__ << " failed") using android::String16; using android::String8; using android::binder::Status; using android::bluetooth::BluetoothAvrcpIntValue; using android::bluetooth::IBluetoothAvrcpTargetCallback; using LockGuard = std::lock_guard<std::mutex>; namespace ipc { namespace binder { BluetoothAvrcpTargetBinderServer::BluetoothAvrcpTargetBinderServer( bluetooth::Adapter* adapter) : adapter_(adapter) { CHECK(adapter_); } BluetoothAvrcpTargetBinderServer::~BluetoothAvrcpTargetBinderServer() = default; bool BluetoothAvrcpTargetBinderServer::HasInstance() { return GetAvrcpTarget() != nullptr; } Status BluetoothAvrcpTargetBinderServer::Register( const android::sp<IBluetoothAvrcpTargetCallback>& callback, bool* _aidl_return) { VLOG(2) << __func__; bluetooth::AvrcpTargetFactory* gatt_client_factory = adapter_->GetAvrcpTargetFactory(); *_aidl_return = RegisterInstanceBase(callback, gatt_client_factory); return Status::ok(); } Status BluetoothAvrcpTargetBinderServer::Unregister(int32_t id) { VLOG(2) << __func__; UnregisterInstanceBase(id); return Status::ok(); } Status BluetoothAvrcpTargetBinderServer::UnregisterAll() { VLOG(2) << __func__; UnregisterAllBase(); return Status::ok(); } Status BluetoothAvrcpTargetBinderServer::Enable(bool* _aidl_return) { auto avrcp_target = TRY_GET_TARGET(); TRY_RET_FUNC(avrcp_target->Enable()); } Status BluetoothAvrcpTargetBinderServer::Disable(bool* _aidl_return) { auto avrcp_target = TRY_GET_TARGET(); avrcp_target->Disable(); AIDL_RET(true); } Status BluetoothAvrcpTargetBinderServer::GetPlayStatusResponse( const android::String16& addr, int32_t play_status, int32_t song_len, int32_t song_pos, bool* _aidl_return) { auto avrcp_target = TRY_GET_TARGET(); TRY_RET_FUNC(avrcp_target->GetPlayStatusResponse( String8(addr).string(), play_status, song_len, song_pos)); } Status BluetoothAvrcpTargetBinderServer::ListPlayerAppAttrResponse( const android::String16& addr, const std::vector<int32_t>& attrs, bool* _aidl_return) { auto avrcp_target = TRY_GET_TARGET(); TRY_RET_FUNC( avrcp_target->ListPlayerAppAttrResponse(String8(addr).string(), attrs)); } Status BluetoothAvrcpTargetBinderServer::GetPlayerAppValueResponse( const android::String16& addr, const std::vector<::android::bluetooth::BluetoothAvrcpIntValue>& values, bool* _aidl_return) { auto avrcp_target = TRY_GET_TARGET(); std::vector<bluetooth::AvrcpIntValue> non_binder; non_binder.reserve(values.size()); for (const auto& val : values) { non_binder.push_back(val); } TRY_RET_FUNC(avrcp_target->GetPlayerAppValueResponse(String8(addr).string(), non_binder)); } Status BluetoothAvrcpTargetBinderServer::GetPlayerAppAttrTextResponse( const android::String16& addr, const std::vector<::android::bluetooth::BluetoothAvrcpStringValue>& attrs, bool* _aidl_return) { auto avrcp_target = TRY_GET_TARGET(); std::vector<bluetooth::AvrcpStringValue> non_binder; non_binder.reserve(attrs.size()); for (const auto& val : attrs) { non_binder.push_back(val); } TRY_RET_FUNC(avrcp_target->GetPlayerAppAttrTextResponse( String8(addr).string(), non_binder)); } Status BluetoothAvrcpTargetBinderServer::GetPlayerAppValueTextResponse( const android::String16& addr, const std::vector<::android::bluetooth::BluetoothAvrcpStringValue>& values, bool* _aidl_return) { auto avrcp_target = TRY_GET_TARGET(); std::vector<bluetooth::AvrcpStringValue> non_binder; non_binder.reserve(values.size()); for (const auto& val : values) { non_binder.push_back(val); } TRY_RET_FUNC(avrcp_target->GetPlayerAppValueTextResponse( String8(addr).string(), non_binder)); } Status BluetoothAvrcpTargetBinderServer::GetElementAttrResponse( const android::String16& addr, const std::vector<::android::bluetooth::BluetoothAvrcpStringValue>& attrs, bool* _aidl_return) { auto avrcp_target = TRY_GET_TARGET(); std::vector<bluetooth::AvrcpStringValue> non_binder; non_binder.reserve(attrs.size()); for (const auto& val : attrs) { non_binder.push_back(val); } TRY_RET_FUNC( avrcp_target->GetElementAttrResponse(String8(addr).string(), non_binder)); } Status BluetoothAvrcpTargetBinderServer::SetPlayerAppValueResponse( const android::String16& addr, int32_t rsp_status, bool* _aidl_return) { auto avrcp_target = TRY_GET_TARGET(); TRY_RET_FUNC(avrcp_target->SetPlayerAppValueResponse(String8(addr).string(), rsp_status)); } Status BluetoothAvrcpTargetBinderServer::RegisterNotificationResponse( int32_t event_id, int32_t type, const ::android::bluetooth::BluetoothAvrcpRegisterNotificationResponse& param, bool* _aidl_return) { auto avrcp_target = TRY_GET_TARGET(); TRY_RET_FUNC( avrcp_target->RegisterNotificationResponse(event_id, type, param)); } Status BluetoothAvrcpTargetBinderServer::SetVolume(int32_t volume, bool* _aidl_return) { auto avrcp_target = TRY_GET_TARGET(); TRY_RET_FUNC(avrcp_target->SetVolume(volume)); } void BluetoothAvrcpTargetBinderServer::OnGetRemoteFeatures( const std::string& addr, int32_t features) { LockGuard lock(*maps_lock()); auto cb = TRY_GET_CB(); cb->OnGetRemoteFeatures(String16(addr.data(), addr.size()), features); } void BluetoothAvrcpTargetBinderServer::OnGetPlayStatus( const std::string& addr) { LockGuard lock(*maps_lock()); auto cb = TRY_GET_CB(); cb->OnGetPlayStatus(String16(addr.data(), addr.size())); } void BluetoothAvrcpTargetBinderServer::OnListPlayerAppAttr( const std::string& addr) { LockGuard lock(*maps_lock()); auto cb = TRY_GET_CB(); cb->OnListPlayerAppAttr(String16(addr.data(), addr.size())); } void BluetoothAvrcpTargetBinderServer::OnListPlayerAppValues( const std::string& addr, int32_t attr_id) { LockGuard lock(*maps_lock()); auto cb = TRY_GET_CB(); cb->OnListPlayerAppValues(String16(addr.data(), addr.size()), attr_id); } void BluetoothAvrcpTargetBinderServer::OnGetPlayerAppValue( const std::string& addr, const std::vector<int32_t>& attrs) { LockGuard lock(*maps_lock()); auto cb = TRY_GET_CB(); cb->OnGetPlayerAppValue(String16(addr.data(), addr.size()), attrs); } void BluetoothAvrcpTargetBinderServer::OnGetPlayerAppAttrsText( const std::string& addr, const std::vector<int32_t>& attrs) { LockGuard lock(*maps_lock()); auto cb = TRY_GET_CB(); cb->OnGetPlayerAppAttrsText(String16(addr.data(), addr.size()), attrs); } void BluetoothAvrcpTargetBinderServer::OnGetPlayerAppValuesText( const std::string& addr, int32_t attr_id, const std::vector<int32_t>& values) { LockGuard lock(*maps_lock()); auto cb = TRY_GET_CB(); cb->OnGetPlayerAppValuesText(String16(addr.data(), addr.size()), attr_id, values); } void BluetoothAvrcpTargetBinderServer::OnSetPlayerAppValue( const std::string& addr, const std::vector<bluetooth::AvrcpIntValue>& values) { std::vector<BluetoothAvrcpIntValue> binder_values; binder_values.reserve(values.size()); for (const auto& val : values) { binder_values.push_back(val); } LockGuard lock(*maps_lock()); auto cb = TRY_GET_CB(); cb->OnSetPlayerAppValue(String16(addr.data(), addr.size()), binder_values); } void BluetoothAvrcpTargetBinderServer::OnGetElementAttrs( const std::string& addr, const std::vector<int32_t>& attrs) { LockGuard lock(*maps_lock()); auto cb = TRY_GET_CB(); cb->OnGetElementAttrs(String16(addr.data(), addr.size()), attrs); } void BluetoothAvrcpTargetBinderServer::OnRegisterNotification( const std::string& addr, int32_t event_id, uint32_t param) { LockGuard lock(*maps_lock()); auto cb = TRY_GET_CB(); cb->OnRegisterNotification(String16(addr.data(), addr.size()), event_id, param); } void BluetoothAvrcpTargetBinderServer::OnVolumeChange(const std::string& addr, int32_t volume, int32_t ctype) { LockGuard lock(*maps_lock()); auto cb = TRY_GET_CB(); cb->OnVolumeChange(String16(addr.data(), addr.size()), volume, ctype); } void BluetoothAvrcpTargetBinderServer::OnPassThroughCommand( const std::string& addr, int32_t id, int32_t key_state) { LockGuard lock(*maps_lock()); auto cb = TRY_GET_CB(); cb->OnPassThroughCommand(String16(addr.data(), addr.size()), id, key_state); } android::sp<IBluetoothAvrcpTargetCallback> BluetoothAvrcpTargetBinderServer::GetAvrcpTargetCallback() { auto cb = GetCallback(bluetooth::AvrcpTarget::kSingletonInstanceId); return android::sp<IBluetoothAvrcpTargetCallback>( static_cast<IBluetoothAvrcpTargetCallback*>(cb.get())); } std::shared_ptr<bluetooth::AvrcpTarget> BluetoothAvrcpTargetBinderServer::GetAvrcpTarget() { return std::static_pointer_cast<bluetooth::AvrcpTarget>( GetInstance(bluetooth::AvrcpTarget::kSingletonInstanceId)); } void BluetoothAvrcpTargetBinderServer::OnRegisterInstanceImpl( bluetooth::BLEStatus status, android::sp<IInterface> callback, bluetooth::BluetoothInstance* instance) { VLOG(1) << __func__ << " client ID: " << instance->GetInstanceId() << " status: " << status; bluetooth::AvrcpTarget* avrcp_target = static_cast<bluetooth::AvrcpTarget*>(instance); avrcp_target->SetDelegate(this); android::sp<IBluetoothAvrcpTargetCallback> cb( static_cast<IBluetoothAvrcpTargetCallback*>(callback.get())); cb->OnRegistered(status); } } // namespace binder } // namespace ipc