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