• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //  Copyright (C) 2017 Google, Inc.
3 //
4 //  Licensed under the Apache License, Version 2.0 (the "License");
5 //  you may not use this file except in compliance with the License.
6 //  You may obtain a copy of the License at:
7 //
8 //  http://www.apache.org/licenses/LICENSE-2.0
9 //
10 //  Unless required by applicable law or agreed to in writing, software
11 //  distributed under the License is distributed on an "AS IS" BASIS,
12 //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 //  See the License for the specific language governing permissions and
14 //  limitations under the License.
15 //
16 #include "service/ipc/binder/bluetooth_a2dp_source_binder_server.h"
17 
18 #include <base/logging.h>
19 
20 #include "service/adapter.h"
21 
22 #define AIDL_RET(value)      \
23   do {                       \
24     *_aidl_return = (value); \
25     return Status::ok();     \
26   } while (0)
27 
28 #define TRY_GET_SOURCE()                                   \
29   ({                                                       \
30     auto source = GetA2dpSource();                         \
31     if (!source) {                                         \
32       LOG(ERROR) << __func__ << ": "                       \
33                  << "Failed to get A2DP source interface"; \
34       AIDL_RET(false);                                     \
35     }                                                      \
36     source;                                                \
37   })
38 
39 #define TRY_GET_CB()                                          \
40   ({                                                          \
41     auto cb = GetA2dpSourceCallback();                        \
42     if (!cb.get()) {                                          \
43       LOG(WARNING) << "Callback for A2DP SOURCE was deleted"; \
44       return;                                                 \
45     }                                                         \
46     cb;                                                       \
47   })
48 
49 #define TRY_RET(expr, msg) \
50   do {                     \
51     if (!(expr)) {         \
52       LOG(ERROR) << msg;   \
53       AIDL_RET(false);     \
54     }                      \
55     AIDL_RET(true);        \
56   } while (0)
57 
58 #define TRY_RET_FUNC(expr) TRY_RET(expr, __func__ << " failed")
59 
60 using android::String16;
61 using android::String8;
62 using android::binder::Status;
63 using android::bluetooth::BluetoothA2dpCodecConfig;
64 using android::bluetooth::IBluetoothA2dpSourceCallback;
65 
66 using LockGuard = std::lock_guard<std::mutex>;
67 
68 namespace ipc {
69 namespace binder {
70 
71 namespace {
72 
A2dpCodecsFromBinder(const std::vector<BluetoothA2dpCodecConfig> & codecs)73 std::vector<bluetooth::A2dpCodecConfig> A2dpCodecsFromBinder(
74     const std::vector<BluetoothA2dpCodecConfig>& codecs) {
75   std::vector<bluetooth::A2dpCodecConfig> ret;
76   ret.reserve(codecs.size());
77   for (const auto& config : codecs) {
78     ret.push_back(config);
79   }
80 
81   return ret;
82 }
83 
A2dpCodecsToBinder(const std::vector<bluetooth::A2dpCodecConfig> & codecs)84 std::vector<BluetoothA2dpCodecConfig> A2dpCodecsToBinder(
85     const std::vector<bluetooth::A2dpCodecConfig>& codecs) {
86   std::vector<BluetoothA2dpCodecConfig> ret;
87   ret.reserve(codecs.size());
88   for (const auto& config : codecs) {
89     ret.push_back(config);
90   }
91 
92   return ret;
93 }
94 
95 }  // namespace
96 
BluetoothA2dpSourceBinderServer(bluetooth::Adapter * adapter)97 BluetoothA2dpSourceBinderServer::BluetoothA2dpSourceBinderServer(
98     bluetooth::Adapter* adapter)
99     : adapter_(adapter) {
100   CHECK(adapter);
101 }
102 
103 BluetoothA2dpSourceBinderServer::~BluetoothA2dpSourceBinderServer() = default;
104 
HasInstance()105 bool BluetoothA2dpSourceBinderServer::HasInstance() {
106   return GetA2dpSource() != nullptr;
107 }
108 
Register(const android::sp<IBluetoothA2dpSourceCallback> & callback,bool * _aidl_return)109 Status BluetoothA2dpSourceBinderServer::Register(
110     const android::sp<IBluetoothA2dpSourceCallback>& callback,
111     bool* _aidl_return) {
112   auto factory = adapter_->GetA2dpSourceFactory();
113   *_aidl_return = RegisterInstanceBase(callback, factory);
114   return Status::ok();
115 }
116 
Unregister()117 Status BluetoothA2dpSourceBinderServer::Unregister() {
118   UnregisterAllBase();
119   return Status::ok();
120 }
121 
Enable(const std::vector<android::bluetooth::BluetoothA2dpCodecConfig> & codec_priorities,bool * _aidl_return)122 Status BluetoothA2dpSourceBinderServer::Enable(
123     const std::vector<android::bluetooth::BluetoothA2dpCodecConfig>&
124         codec_priorities,
125     bool* _aidl_return) {
126   auto codec_priorities_non_binder = A2dpCodecsFromBinder(codec_priorities);
127 
128   LockGuard lock(*maps_lock());
129   auto a2dp_source = TRY_GET_SOURCE();
130   TRY_RET_FUNC(a2dp_source->Enable(codec_priorities_non_binder));
131 }
132 
Disable(bool * _aidl_return)133 Status BluetoothA2dpSourceBinderServer::Disable(bool* _aidl_return) {
134   LockGuard lock(*maps_lock());
135   auto a2dp_source = TRY_GET_SOURCE();
136   a2dp_source->Disable();
137   AIDL_RET(true);
138 }
139 
Connect(const String16 & device_address,bool * _aidl_return)140 Status BluetoothA2dpSourceBinderServer::Connect(const String16& device_address,
141                                                 bool* _aidl_return) {
142   LockGuard lock(*maps_lock());
143   auto a2dp_source = TRY_GET_SOURCE();
144   TRY_RET_FUNC(a2dp_source->Connect(String8(device_address).string()));
145 }
146 
Disconnect(const String16 & device_address,bool * _aidl_return)147 Status BluetoothA2dpSourceBinderServer::Disconnect(
148     const String16& device_address, bool* _aidl_return) {
149   LockGuard lock(*maps_lock());
150   auto a2dp_source = TRY_GET_SOURCE();
151   TRY_RET_FUNC(a2dp_source->Disconnect(String8(device_address).string()));
152 }
153 
ConfigCodec(const android::String16 & device_address,const std::vector<android::bluetooth::BluetoothA2dpCodecConfig> & codec_preferences,bool * _aidl_return)154 Status BluetoothA2dpSourceBinderServer::ConfigCodec(
155     const android::String16& device_address,
156     const std::vector<android::bluetooth::BluetoothA2dpCodecConfig>&
157         codec_preferences,
158     bool* _aidl_return) {
159   auto codec_preferences_non_binder = A2dpCodecsFromBinder(codec_preferences);
160 
161   LockGuard lock(*maps_lock());
162   auto a2dp_source = TRY_GET_SOURCE();
163   TRY_RET_FUNC(a2dp_source->ConfigCodec(String8(device_address).string(),
164                                         codec_preferences_non_binder));
165 }
166 
OnConnectionState(const std::string & device_address,int state)167 void BluetoothA2dpSourceBinderServer::OnConnectionState(
168     const std::string& device_address, int state) {
169   LockGuard lock(*maps_lock());
170   auto cb = TRY_GET_CB();
171   cb->OnConnectionState(String16(device_address.c_str()), state);
172 }
173 
OnAudioState(const std::string & device_address,int state)174 void BluetoothA2dpSourceBinderServer::OnAudioState(
175     const std::string& device_address, int state) {
176   LockGuard lock(*maps_lock());
177   auto cb = TRY_GET_CB();
178   cb->OnAudioState(String16(device_address.c_str()), state);
179 }
180 
OnAudioConfig(const std::string & device_address,bluetooth::A2dpCodecConfig codec_config,const std::vector<bluetooth::A2dpCodecConfig> & codecs_local_capabilities,const std::vector<bluetooth::A2dpCodecConfig> & codecs_selectable_capabilities)181 void BluetoothA2dpSourceBinderServer::OnAudioConfig(
182     const std::string& device_address, bluetooth::A2dpCodecConfig codec_config,
183     const std::vector<bluetooth::A2dpCodecConfig>& codecs_local_capabilities,
184     const std::vector<bluetooth::A2dpCodecConfig>&
185         codecs_selectable_capabilities) {
186   auto binder_codecs_local_capabilities =
187       A2dpCodecsToBinder(codecs_local_capabilities);
188   auto binder_codecs_selectable_capabilities =
189       A2dpCodecsToBinder(codecs_selectable_capabilities);
190 
191   LockGuard lock(*maps_lock());
192   auto cb = TRY_GET_CB();
193   cb->OnAudioConfig(String16(device_address.c_str()), codec_config,
194                     binder_codecs_local_capabilities,
195                     binder_codecs_selectable_capabilities);
196 }
197 
198 android::sp<IBluetoothA2dpSourceCallback>
GetA2dpSourceCallback()199 BluetoothA2dpSourceBinderServer::GetA2dpSourceCallback() {
200   auto cb = GetCallback(bluetooth::A2dpSource::kSingletonInstanceId);
201   return android::sp<IBluetoothA2dpSourceCallback>(
202       static_cast<IBluetoothA2dpSourceCallback*>(cb.get()));
203 }
204 
205 std::shared_ptr<bluetooth::A2dpSource>
GetA2dpSource()206 BluetoothA2dpSourceBinderServer::GetA2dpSource() {
207   return std::static_pointer_cast<bluetooth::A2dpSource>(
208       GetInstance(bluetooth::A2dpSource::kSingletonInstanceId));
209 }
210 
OnRegisterInstanceImpl(bluetooth::BLEStatus status,android::sp<IInterface> callback,bluetooth::BluetoothInstance * instance)211 void BluetoothA2dpSourceBinderServer::OnRegisterInstanceImpl(
212     bluetooth::BLEStatus status, android::sp<IInterface> callback,
213     bluetooth::BluetoothInstance* instance) {
214   VLOG(1) << __func__ << " instance ID: " << instance->GetInstanceId()
215           << " status: " << status;
216   bluetooth::A2dpSource* a2dp_source =
217       static_cast<bluetooth::A2dpSource*>(instance);
218   a2dp_source->SetDelegate(this);
219 
220   android::sp<IBluetoothA2dpSourceCallback> cb(
221       static_cast<IBluetoothA2dpSourceCallback*>(callback.get()));
222   cb->OnRegistered(status);
223 }
224 
225 }  // namespace binder
226 }  // namespace ipc
227