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