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
17 #include "service/avrcp_target.h"
18
19 #include <algorithm>
20 #include <cerrno>
21 #include <climits>
22 #include <string>
23
24 #include "base/logging.h"
25 #include "base/macros.h"
26 #include "base/memory/ptr_util.h"
27 #include "service/logging_helpers.h"
28
29 #include "array_utils.h"
30 #include "stack/include/avrc_defs.h"
31
32 #define PARSE_ADDR(str) \
33 ({ \
34 RawAddress tmp; \
35 if (!RawAddress::FromString((str), tmp)) { \
36 LOG(ERROR) << "Invalid device address given: " << (str); \
37 return false; \
38 } \
39 tmp; \
40 })
41
42 #define TRY_RET(expr, err_msg) \
43 do { \
44 if (!(expr)) { \
45 LOG(ERROR) << err_msg; \
46 return false; \
47 } \
48 return true; \
49 } while (0)
50
51 #define TRY_RET_FUNC(expr) TRY_RET(expr, __func__ << " failed")
52
53 using LockGuard = std::lock_guard<std::mutex>;
54
55 namespace bluetooth {
56
57 namespace {
58
StringValueToPlayerSettingsText(const std::vector<AvrcpStringValue> & attrs)59 std::vector<btrc_player_setting_text_t> StringValueToPlayerSettingsText(
60 const std::vector<AvrcpStringValue>& attrs) {
61 std::vector<btrc_player_setting_text_t> btrc_attrs(attrs.size());
62 for (size_t i = 0; i < attrs.size(); ++i) {
63 btrc_attrs[i].id = attrs[i].id();
64 std::string str(attrs[i].value());
65 size_t to_copy = std::min(sizeof(btrc_attrs[i].text) - 1, str.size());
66 if (to_copy < str.size()) {
67 LOG(WARNING) << "Value truncated";
68 }
69
70 memcpy(btrc_attrs[i].text, str.data(), to_copy);
71 btrc_attrs[i].text[to_copy] = '\0';
72 }
73
74 return btrc_attrs;
75 }
76
StringValueToElementAttrVal(const std::vector<AvrcpStringValue> & attrs)77 std::vector<btrc_element_attr_val_t> StringValueToElementAttrVal(
78 const std::vector<AvrcpStringValue>& attrs) {
79 std::vector<btrc_element_attr_val_t> btrc_attrs(attrs.size());
80 for (size_t i = 0; i < attrs.size(); ++i) {
81 btrc_attrs[i].attr_id = attrs[i].id();
82 std::string str(attrs[i].value());
83 size_t to_copy = std::min(sizeof(btrc_attrs[i].text) - 1, str.size());
84 if (to_copy < str.size()) {
85 LOG(WARNING) << "Value truncated";
86 }
87
88 memcpy(btrc_attrs[i].text, str.data(), to_copy);
89 btrc_attrs[i].text[to_copy] = '\0';
90 }
91
92 return btrc_attrs;
93 }
94
95 } // namespace
96
97 // static
98 const int AvrcpTarget::kSingletonInstanceId = 0;
99
AvrcpTarget(const Uuid & uuid)100 AvrcpTarget::AvrcpTarget(const Uuid& uuid) : app_identifier_(uuid) {
101 hal::BluetoothAvrcpInterface::Get()->AddTargetObserver(this);
102 }
103
~AvrcpTarget()104 AvrcpTarget::~AvrcpTarget() {
105 hal::BluetoothAvrcpInterface::Get()->RemoveTargetObserver(this);
106 }
107
GetAppIdentifier() const108 const Uuid& AvrcpTarget::GetAppIdentifier() const { return app_identifier_; }
109
GetInstanceId() const110 int AvrcpTarget::GetInstanceId() const { return kSingletonInstanceId; }
111
SetDelegate(Delegate * delegate)112 void AvrcpTarget::SetDelegate(Delegate* delegate) {
113 LockGuard lock(delegate_mutex_);
114 delegate_ = delegate;
115 }
116
Enable()117 bool AvrcpTarget::Enable() {
118 LockGuard lock(mutex_);
119 return hal::BluetoothAvrcpInterface::Get()->AvrcpTargetEnable();
120 }
121
Disable()122 void AvrcpTarget::Disable() {
123 LockGuard lock(mutex_);
124 hal::BluetoothAvrcpInterface::Get()->AvrcpTargetDisable();
125 }
126
GetPlayStatusResponse(const std::string & str_addr,int32_t play_status,uint32_t song_len,uint32_t song_pos)127 bool AvrcpTarget::GetPlayStatusResponse(const std::string& str_addr,
128 int32_t play_status, uint32_t song_len,
129 uint32_t song_pos) {
130 RawAddress addr = PARSE_ADDR(str_addr);
131 LockGuard lock(mutex_);
132 TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
133 ->GetTargetHALInterface()
134 ->get_play_status_rsp(
135 addr, static_cast<btrc_play_status_t>(play_status),
136 song_len, song_pos) == BT_STATUS_SUCCESS);
137 }
138
ListPlayerAppAttrResponse(const std::string & str_addr,const std::vector<int32_t> & attrs)139 bool AvrcpTarget::ListPlayerAppAttrResponse(const std::string& str_addr,
140 const std::vector<int32_t>& attrs) {
141 RawAddress addr = PARSE_ADDR(str_addr);
142
143 std::vector<btrc_player_attr_t> btrc_attrs;
144 btrc_attrs.reserve(attrs.size());
145 for (auto attr : attrs) {
146 btrc_attrs.push_back(static_cast<btrc_player_attr_t>(attr));
147 }
148
149 LockGuard lock(mutex_);
150 TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
151 ->GetTargetHALInterface()
152 ->list_player_app_attr_rsp(addr, btrc_attrs.size(),
153 btrc_attrs.data()) ==
154 BT_STATUS_SUCCESS);
155 }
156
GetPlayerAppValueResponse(const std::string & str_addr,const std::vector<AvrcpIntValue> & values)157 bool AvrcpTarget::GetPlayerAppValueResponse(
158 const std::string& str_addr, const std::vector<AvrcpIntValue>& values) {
159 RawAddress addr = PARSE_ADDR(str_addr);
160 btrc_player_settings_t btrc_values;
161 if (values.size() >= ARRAY_SIZE(btrc_values.attr_ids)) {
162 LOG(ERROR) << "Too many attribute values";
163 return false;
164 }
165
166 btrc_values.num_attr = values.size();
167 for (size_t i = 0; i < values.size(); ++i) {
168 btrc_values.attr_ids[i] = values[i].id();
169 btrc_values.attr_values[i] = values[i].value();
170 }
171
172 LockGuard lock(mutex_);
173 TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
174 ->GetTargetHALInterface()
175 ->get_player_app_value_rsp(addr, &btrc_values) ==
176 BT_STATUS_SUCCESS);
177 }
178
GetPlayerAppAttrTextResponse(const std::string & str_addr,const std::vector<AvrcpStringValue> & attrs)179 bool AvrcpTarget::GetPlayerAppAttrTextResponse(
180 const std::string& str_addr, const std::vector<AvrcpStringValue>& attrs) {
181 RawAddress addr = PARSE_ADDR(str_addr);
182 auto btrc_attrs = StringValueToPlayerSettingsText(attrs);
183 LockGuard lock(mutex_);
184 TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
185 ->GetTargetHALInterface()
186 ->get_player_app_attr_text_rsp(addr, btrc_attrs.size(),
187 btrc_attrs.data()) ==
188 BT_STATUS_SUCCESS);
189 }
190
GetPlayerAppValueTextResponse(const std::string & str_addr,const std::vector<AvrcpStringValue> & values)191 bool AvrcpTarget::GetPlayerAppValueTextResponse(
192 const std::string& str_addr, const std::vector<AvrcpStringValue>& values) {
193 RawAddress addr = PARSE_ADDR(str_addr);
194 auto btrc_values = StringValueToPlayerSettingsText(values);
195 LockGuard lock(mutex_);
196 TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
197 ->GetTargetHALInterface()
198 ->get_player_app_value_text_rsp(addr, btrc_values.size(),
199 btrc_values.data()) ==
200 BT_STATUS_SUCCESS);
201 }
202
GetElementAttrResponse(const std::string & str_addr,const std::vector<AvrcpStringValue> & attrs)203 bool AvrcpTarget::GetElementAttrResponse(
204 const std::string& str_addr, const std::vector<AvrcpStringValue>& attrs) {
205 RawAddress addr = PARSE_ADDR(str_addr);
206 auto btrc_attrs = StringValueToElementAttrVal(attrs);
207 LockGuard lock(mutex_);
208 TRY_RET_FUNC(
209 hal::BluetoothAvrcpInterface::Get()
210 ->GetTargetHALInterface()
211 ->get_element_attr_rsp(addr, btrc_attrs.size(), btrc_attrs.data()) ==
212 BT_STATUS_SUCCESS);
213 }
214
SetPlayerAppValueResponse(const std::string & str_addr,int32_t rsp_status)215 bool AvrcpTarget::SetPlayerAppValueResponse(const std::string& str_addr,
216 int32_t rsp_status) {
217 RawAddress addr = PARSE_ADDR(str_addr);
218 LockGuard lock(mutex_);
219 TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
220 ->GetTargetHALInterface()
221 ->set_player_app_value_rsp(
222 addr, static_cast<btrc_status_t>(rsp_status)) ==
223 BT_STATUS_SUCCESS);
224 }
225
RegisterNotificationResponse(int32_t event_id,int32_t type,const AvrcpRegisterNotificationResponse & param)226 bool AvrcpTarget::RegisterNotificationResponse(
227 int32_t event_id, int32_t type,
228 const AvrcpRegisterNotificationResponse& param) {
229 auto param_copy = param.data();
230 LockGuard lock(mutex_);
231 TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
232 ->GetTargetHALInterface()
233 ->register_notification_rsp(
234 static_cast<btrc_event_id_t>(event_id),
235 static_cast<btrc_notification_type_t>(type),
236 ¶m_copy) == BT_STATUS_SUCCESS);
237 }
238
SetVolume(int volume)239 bool AvrcpTarget::SetVolume(int volume) {
240 LockGuard lock(mutex_);
241 TRY_RET_FUNC(
242 hal::BluetoothAvrcpInterface::Get()->GetTargetHALInterface()->set_volume(
243 volume) == BT_STATUS_SUCCESS);
244 }
245
RemoteFeaturesCallback(const RawAddress & bd_addr,btrc_remote_features_t features)246 void AvrcpTarget::RemoteFeaturesCallback(const RawAddress& bd_addr,
247 btrc_remote_features_t features) {
248 auto str_addr = BtAddrString(&bd_addr);
249 LockGuard lock(delegate_mutex_);
250 if (delegate_)
251 delegate_->OnGetRemoteFeatures(str_addr, static_cast<int32_t>(features));
252 }
253
GetPlayStatusCallback(const RawAddress & bd_addr)254 void AvrcpTarget::GetPlayStatusCallback(const RawAddress& bd_addr) {
255 auto str_addr = BtAddrString(&bd_addr);
256 LockGuard lock(delegate_mutex_);
257 if (delegate_) delegate_->OnGetPlayStatus(str_addr);
258 }
259
ListPlayerAppAttrCallback(const RawAddress & bd_addr)260 void AvrcpTarget::ListPlayerAppAttrCallback(const RawAddress& bd_addr) {
261 auto str_addr = BtAddrString(&bd_addr);
262 LockGuard lock(delegate_mutex_);
263 if (delegate_) delegate_->OnListPlayerAppAttr(str_addr);
264 }
265
ListPlayerAppValuesCallback(btrc_player_attr_t attr_id,const RawAddress & bd_addr)266 void AvrcpTarget::ListPlayerAppValuesCallback(btrc_player_attr_t attr_id,
267 const RawAddress& bd_addr) {
268 auto str_addr = BtAddrString(&bd_addr);
269 LockGuard lock(delegate_mutex_);
270 if (delegate_)
271 delegate_->OnListPlayerAppValues(str_addr, static_cast<int32_t>(attr_id));
272 }
273
GetPlayerAppValueCallback(uint8_t num_attr,btrc_player_attr_t * p_attrs,const RawAddress & bd_addr)274 void AvrcpTarget::GetPlayerAppValueCallback(uint8_t num_attr,
275 btrc_player_attr_t* p_attrs,
276 const RawAddress& bd_addr) {
277 auto str_addr = BtAddrString(&bd_addr);
278 std::vector<int32_t> attr_vec;
279 attr_vec.reserve(num_attr);
280 for (auto* it = p_attrs; it != p_attrs + num_attr; ++it) {
281 attr_vec.push_back(*it);
282 }
283
284 LockGuard lock(delegate_mutex_);
285 if (delegate_) delegate_->OnGetPlayerAppValue(str_addr, attr_vec);
286 }
287
GetPlayerAppAttrsTextCallback(uint8_t num_attr,btrc_player_attr_t * p_attrs,const RawAddress & bd_addr)288 void AvrcpTarget::GetPlayerAppAttrsTextCallback(uint8_t num_attr,
289 btrc_player_attr_t* p_attrs,
290 const RawAddress& bd_addr) {
291 auto str_addr = BtAddrString(&bd_addr);
292 std::vector<int32_t> attr_vec;
293 attr_vec.reserve(num_attr);
294 for (auto* it = p_attrs; it != p_attrs + num_attr; ++it) {
295 attr_vec.push_back(*it);
296 }
297
298 LockGuard lock(delegate_mutex_);
299 if (delegate_) delegate_->OnGetPlayerAppAttrsText(str_addr, attr_vec);
300 }
301
GetPlayerAppValuesTextCallback(uint8_t attr_id,uint8_t num_val,uint8_t * p_vals,const RawAddress & bd_addr)302 void AvrcpTarget::GetPlayerAppValuesTextCallback(uint8_t attr_id,
303 uint8_t num_val,
304 uint8_t* p_vals,
305 const RawAddress& bd_addr) {
306 auto str_addr = BtAddrString(&bd_addr);
307 std::vector<int32_t> val_vec;
308 val_vec.reserve(num_val);
309 for (auto* it = p_vals; it != p_vals + num_val; ++it) {
310 val_vec.push_back(*it);
311 }
312 LockGuard lock(delegate_mutex_);
313 if (delegate_)
314 delegate_->OnGetPlayerAppValuesText(str_addr, attr_id, val_vec);
315 }
316
SetPlayerAppValueCallback(btrc_player_settings_t * p_vals,const RawAddress & bd_addr)317 void AvrcpTarget::SetPlayerAppValueCallback(btrc_player_settings_t* p_vals,
318 const RawAddress& bd_addr) {
319 auto str_addr = BtAddrString(&bd_addr);
320 std::vector<AvrcpIntValue> values;
321 values.reserve(p_vals->num_attr);
322 for (size_t i = 0; i < p_vals->num_attr; ++i) {
323 values.emplace_back(p_vals->attr_ids[i], p_vals->attr_values[i]);
324 }
325
326 LockGuard lock(delegate_mutex_);
327 if (delegate_) delegate_->OnSetPlayerAppValue(str_addr, values);
328 }
329
GetElementAttrCallback(uint8_t num_attr,btrc_media_attr_t * p_attrs,const RawAddress & bd_addr)330 void AvrcpTarget::GetElementAttrCallback(uint8_t num_attr,
331 btrc_media_attr_t* p_attrs,
332 const RawAddress& bd_addr) {
333 auto str_addr = BtAddrString(&bd_addr);
334 std::vector<int32_t> attr_vec;
335 attr_vec.reserve(num_attr);
336 for (auto* it = p_attrs; it != p_attrs + num_attr; ++it) {
337 attr_vec.push_back(*it);
338 }
339 LockGuard lock(delegate_mutex_);
340 if (delegate_) delegate_->OnGetElementAttrs(str_addr, attr_vec);
341 }
342
RegisterNotificationCallback(btrc_event_id_t event_id,uint32_t param,const RawAddress & bd_addr)343 void AvrcpTarget::RegisterNotificationCallback(btrc_event_id_t event_id,
344 uint32_t param,
345 const RawAddress& bd_addr) {
346 auto str_addr = BtAddrString(&bd_addr);
347 LockGuard lock(delegate_mutex_);
348 if (delegate_)
349 delegate_->OnRegisterNotification(str_addr, static_cast<int32_t>(event_id),
350 param);
351 }
352
VolumeChangeCallback(uint8_t volume,uint8_t ctype,const RawAddress & bd_addr)353 void AvrcpTarget::VolumeChangeCallback(uint8_t volume, uint8_t ctype,
354 const RawAddress& bd_addr) {
355 auto str_addr = BtAddrString(&bd_addr);
356 LockGuard lock(delegate_mutex_);
357 if (delegate_) delegate_->OnVolumeChange(str_addr, volume, ctype);
358 }
359
PassthroughCmdCallback(int id,int key_state,const RawAddress & bd_addr)360 void AvrcpTarget::PassthroughCmdCallback(int id, int key_state,
361 const RawAddress& bd_addr) {
362 auto str_addr = BtAddrString(&bd_addr);
363 LockGuard lock(delegate_mutex_);
364 if (delegate_) delegate_->OnPassThroughCommand(str_addr, id, key_state);
365 }
366
367 // AvrcpTargetFactory implementation
368 // ========================================================
369
370 AvrcpTargetFactory::AvrcpTargetFactory() = default;
371 AvrcpTargetFactory::~AvrcpTargetFactory() = default;
372
RegisterInstance(const Uuid & uuid,const RegisterCallback & callback)373 bool AvrcpTargetFactory::RegisterInstance(const Uuid& uuid,
374 const RegisterCallback& callback) {
375 VLOG(1) << __func__ << " - UUID: " << uuid.ToString();
376
377 auto avrcp_target = base::WrapUnique(new AvrcpTarget(uuid));
378 callback(BLE_STATUS_SUCCESS, uuid, std::move(avrcp_target));
379 return true;
380 }
381
382 } // namespace bluetooth
383