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