• 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 
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                        &param_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