avrcp_control.cc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. //
  2. // Copyright 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/avrcp_control.h"
  17. #include <cerrno>
  18. #include <climits>
  19. #include <string>
  20. #include <base/logging.h>
  21. #include <base/memory/ptr_util.h>
  22. #include <base/strings/string_number_conversions.h>
  23. #include "service/logging_helpers.h"
  24. #include "stack/include/avrc_defs.h"
  25. namespace bluetooth {
  26. AvrcpControl::AvrcpControl(const Uuid& uuid, int control_id)
  27. : app_identifier_(uuid), control_id_(control_id) {
  28. hal::BluetoothAvrcpInterface::Get()->AddControlObserver(this);
  29. }
  30. AvrcpControl::~AvrcpControl() {
  31. hal::BluetoothAvrcpInterface::Get()->RemoveControlObserver(this);
  32. }
  33. const Uuid& AvrcpControl::GetAppIdentifier() const { return app_identifier_; }
  34. int AvrcpControl::GetInstanceId() const { return control_id_; }
  35. void AvrcpControl::SetDelegate(Delegate* delegate) {
  36. std::lock_guard<std::mutex> lock(delegate_mutex_);
  37. delegate_ = delegate;
  38. }
  39. bool AvrcpControl::Enable() {
  40. std::lock_guard<std::mutex> lock(mutex_);
  41. return hal::BluetoothAvrcpInterface::Get()->AvrcpControlEnable();
  42. }
  43. void AvrcpControl::Disable() {
  44. std::lock_guard<std::mutex> lock(mutex_);
  45. hal::BluetoothAvrcpInterface::Get()->AvrcpControlDisable();
  46. }
  47. bool AvrcpControl::SendPassThroughCommand(const std::string& device_address,
  48. uint8_t key_code, bool key_pressed) {
  49. RawAddress addr;
  50. if (!RawAddress::FromString(device_address, addr)) {
  51. LOG(ERROR) << "Invalid device address given: " << device_address;
  52. return false;
  53. }
  54. uint8_t key_state = key_pressed ? AVRC_STATE_PRESS : AVRC_STATE_RELEASE;
  55. bt_status_t status;
  56. {
  57. std::lock_guard<std::mutex> lock(mutex_);
  58. status = hal::BluetoothAvrcpInterface::Get()
  59. ->GetControlHALInterface()
  60. ->send_pass_through_cmd(addr, key_code, key_state);
  61. }
  62. if (status != BT_STATUS_SUCCESS) {
  63. LOG(ERROR) << "Failed to send passthrough command";
  64. return false;
  65. }
  66. return true;
  67. }
  68. bool AvrcpControl::SetAbsVolumeResponse(const std::string& device_address,
  69. int32_t abs_vol, int32_t label) {
  70. RawAddress addr;
  71. if (!RawAddress::FromString(device_address, addr)) {
  72. LOG(ERROR) << "Invalid device address given: " << device_address;
  73. return false;
  74. }
  75. bt_status_t status;
  76. {
  77. std::lock_guard<std::mutex> lock(mutex_);
  78. status = hal::BluetoothAvrcpInterface::Get()
  79. ->GetControlHALInterface()
  80. ->set_volume_rsp(addr, abs_vol, label);
  81. }
  82. if (status != BT_STATUS_SUCCESS) {
  83. LOG(ERROR) << "Failed to send set absolute volume response";
  84. return false;
  85. }
  86. return true;
  87. }
  88. bool AvrcpControl::RegisterForAbsVolumeCallbackResponse(
  89. const std::string& device_address, int32_t response_type, int32_t abs_vol,
  90. int32_t label) {
  91. RawAddress addr;
  92. if (!RawAddress::FromString(device_address, addr)) {
  93. LOG(ERROR) << "Invalid device address given: " << device_address;
  94. return false;
  95. }
  96. bt_status_t status;
  97. {
  98. std::lock_guard<std::mutex> lock(mutex_);
  99. status = hal::BluetoothAvrcpInterface::Get()
  100. ->GetControlHALInterface()
  101. ->register_abs_vol_rsp(
  102. addr, static_cast<btrc_notification_type_t>(response_type),
  103. abs_vol, label);
  104. }
  105. if (status != BT_STATUS_SUCCESS) {
  106. LOG(ERROR)
  107. << "Failed to send send register for absolute volume change callback";
  108. return false;
  109. }
  110. return true;
  111. }
  112. void AvrcpControl::ConnectionStateCallback(bool rc_connect, bool bt_connect,
  113. const RawAddress& bd_addr) {
  114. std::string device_address = BtAddrString(&bd_addr);
  115. std::lock_guard<std::mutex> lock(delegate_mutex_);
  116. if (delegate_)
  117. delegate_->OnConnectionState(rc_connect, bt_connect, device_address);
  118. }
  119. void AvrcpControl::CtrlSetabsvolCmdCallback(const RawAddress& bd_addr,
  120. uint8_t abs_vol, uint8_t label) {
  121. std::string device_address = BtAddrString(&bd_addr);
  122. std::lock_guard<std::mutex> lock(delegate_mutex_);
  123. if (delegate_)
  124. delegate_->OnSetAbsVolumeRequest(device_address, abs_vol, label);
  125. }
  126. void AvrcpControl::CtrlRegisternotificationAbsVolCallback(
  127. const RawAddress& bd_addr, uint8_t label) {
  128. std::string device_address = BtAddrString(&bd_addr);
  129. std::lock_guard<std::mutex> lock(delegate_mutex_);
  130. if (delegate_)
  131. delegate_->OnRegisterForAbsVolumeCallbackRequest(device_address, label);
  132. }
  133. void AvrcpControl::CtrlTrackChangedCallback(const RawAddress& bd_addr,
  134. uint8_t num_attr,
  135. btrc_element_attr_val_t* p_attrs) {
  136. std::string device_address = BtAddrString(&bd_addr);
  137. std::string title;
  138. std::string artist;
  139. std::string album;
  140. std::string genre;
  141. int track_num = -1;
  142. int num_tracks = -1;
  143. int play_time = -1;
  144. for (size_t i = 0; i < num_attr; ++i) {
  145. auto attr_text = reinterpret_cast<char*>(p_attrs[i].text);
  146. switch (p_attrs[i].attr_id) {
  147. case BTRC_MEDIA_ATTR_ID_TITLE:
  148. title = attr_text;
  149. break;
  150. case BTRC_MEDIA_ATTR_ID_ARTIST:
  151. artist = attr_text;
  152. break;
  153. case BTRC_MEDIA_ATTR_ID_ALBUM:
  154. album = attr_text;
  155. break;
  156. case BTRC_MEDIA_ATTR_ID_TRACK_NUM:
  157. if (!base::StringToInt(attr_text, &track_num)) {
  158. LOG(ERROR) << "Failed to parse track number";
  159. }
  160. break;
  161. case BTRC_MEDIA_ATTR_ID_NUM_TRACKS:
  162. if (!base::StringToInt(attr_text, &num_tracks)) {
  163. LOG(ERROR) << "Failed to parse number of tracks";
  164. }
  165. break;
  166. case BTRC_MEDIA_ATTR_ID_GENRE:
  167. genre = attr_text;
  168. break;
  169. case BTRC_MEDIA_ATTR_ID_PLAYING_TIME:
  170. if (!base::StringToInt(attr_text, &play_time)) {
  171. LOG(ERROR) << "Failed to parse playing time";
  172. }
  173. break;
  174. default:
  175. NOTREACHED();
  176. }
  177. }
  178. const AvrcpMediaAttr attr(title, artist, album, genre, track_num, num_tracks,
  179. play_time);
  180. std::lock_guard<std::mutex> lock(delegate_mutex_);
  181. if (delegate_) delegate_->OnTrackChanged(device_address, attr);
  182. }
  183. // AvrcpControlFactory implementation
  184. // ========================================================
  185. AvrcpControlFactory::AvrcpControlFactory() = default;
  186. AvrcpControlFactory::~AvrcpControlFactory() = default;
  187. bool AvrcpControlFactory::RegisterInstance(const Uuid& uuid,
  188. const RegisterCallback& callback) {
  189. VLOG(1) << __func__ << " - Uuid: " << uuid.ToString();
  190. int control_id = next_control_id_++;
  191. std::unique_ptr<AvrcpControl> hf_client(new AvrcpControl(uuid, control_id));
  192. callback(BLE_STATUS_SUCCESS, uuid, std::move(hf_client));
  193. return true;
  194. }
  195. } // namespace bluetooth