1 /* 2 * Copyright 2018 The Android Open Source Project 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 #pragma once 18 19 #include <base/cancelable_callback.h> 20 #include <base/functional/bind.h> 21 22 #include <iostream> 23 #include <memory> 24 #include <stack> 25 #include <vector> 26 27 #include "avrcp_internal.h" 28 #include "hardware/avrcp/avrcp.h" 29 #include "packet/avrcp/avrcp_browse_packet.h" 30 #include "packet/avrcp/avrcp_packet.h" 31 #include "packet/avrcp/capabilities_packet.h" 32 #include "packet/avrcp/change_path.h" 33 #include "packet/avrcp/get_current_player_application_setting_value.h" 34 #include "packet/avrcp/get_element_attributes_packet.h" 35 #include "packet/avrcp/get_folder_items.h" 36 #include "packet/avrcp/get_item_attributes.h" 37 #include "packet/avrcp/get_total_number_of_items.h" 38 #include "packet/avrcp/list_player_application_setting_attributes.h" 39 #include "packet/avrcp/list_player_application_setting_values.h" 40 #include "packet/avrcp/play_item.h" 41 #include "packet/avrcp/register_notification_packet.h" 42 #include "packet/avrcp/set_addressed_player.h" 43 #include "packet/avrcp/set_browsed_player.h" 44 #include "packet/avrcp/set_player_application_setting_value.h" 45 #include "packet/avrcp/vendor_packet.h" 46 #include "profile/avrcp/media_id_map.h" 47 #include "raw_address.h" 48 49 namespace bluetooth { 50 namespace avrcp { 51 52 /** 53 * A class representing a connection with a remote AVRCP device. It holds all 54 * the state and message handling for the device that it represents. 55 */ 56 // TODO (apanicke): Once we move over to having the individual message 57 // responders for Browse and Classic AVRCP Messages move the device around via a 58 // weak pointer. 59 class Device { 60 public: 61 /** 62 * Device is friends with Avrcp::ConnectionHandler so that ConnectionHandler 63 * can deliver messages to individual devices. 64 */ 65 friend class ConnectionHandler; 66 67 Device(const RawAddress& bdaddr, bool avrcp13_compatibility, 68 base::RepeatingCallback< 69 void(uint8_t label, bool browse, 70 std::unique_ptr<::bluetooth::PacketBuilder> message)> 71 send_msg_cb, 72 uint16_t ctrl_mtu, uint16_t browse_mtu); 73 74 Device(const Device&) = delete; 75 Device& operator=(const Device&) = delete; 76 77 virtual ~Device() = default; 78 79 /** 80 * Gets a weak pointer to this device that is invalidated when the device is 81 * disconnected. 82 */ 83 base::WeakPtr<Device> Get(); 84 GetAddress()85 const RawAddress& GetAddress() const { return address_; }; 86 87 /** 88 * Disconnects the AVRCP connection that this device represents. 89 */ 90 bool Disconnect(); 91 92 /** 93 * Set the status of the BIP obex client 94 */ 95 void SetBipClientStatus(bool connected); 96 97 /** 98 * Returns true if the current device has a BIP OBEX client. 99 */ 100 bool HasBipClient() const; 101 102 /** 103 * Returns true if the current device is silenced. 104 */ 105 bool IsInSilenceMode() const; 106 107 /** 108 * Returns true if the current device is active. 109 */ 110 bool IsActive() const; 111 112 /** 113 * Register the interfaces that the device uses to get information. If the 114 * Volume Interface is null, then absolute volume is disabled. 115 * TODO (apanicke): Add these to the constructor/factory so that each device 116 * is created valid and can't be accidentally interacted with when no 117 * interfaces are registered. 118 */ 119 void RegisterInterfaces(MediaInterface* interface, 120 A2dpInterface* a2dp_interface, 121 VolumeInterface* volume_interface, 122 PlayerSettingsInterface* player_settings_interface); 123 124 /** 125 * Set the maximum size of a AVRCP Browsing Packet. This is done after the 126 * connection of the Browsing channel. 127 */ 128 void SetBrowseMtu(uint16_t browse_mtu); 129 130 /** 131 * Notify the device that metadata, play_status, and/or queue have updated 132 * via a boolean. Each boolean represents whether its respective content has 133 * updated. 134 */ 135 virtual void SendMediaUpdate(bool metadata, bool play_status, bool queue); 136 137 /** 138 * Notify the device that the available_player, addressed_player, or UIDs 139 * have updated via a boolean. Each boolean represents whether its respective 140 * content has updated. 141 */ 142 virtual void SendFolderUpdate(bool available_player, bool addressed_player, 143 bool uids); 144 145 // TODO (apanicke): Split the message handlers into two files. One 146 // for handling Browse Messages and the other for handling all other 147 // messages. This prevents the .cc file from getting bloated like it is 148 // now. The Device class will then become a state holder for each message 149 // and all the functions in these handler classes can be static since the 150 // device will be passed in. The extensions of the Device class can contain 151 // any interop handling for specific messages on specific devices. 152 153 void MessageReceived(uint8_t label, std::shared_ptr<Packet> pkt); 154 void BrowseMessageReceived(uint8_t label, std::shared_ptr<BrowsePacket> pkt); 155 void VendorPacketHandler(uint8_t label, std::shared_ptr<VendorPacket> pkt); 156 157 /******************** 158 * MESSAGE RESPONSES 159 ********************/ 160 // CURRENT TRACK CHANGED 161 virtual void HandleTrackUpdate(); 162 virtual void TrackChangedNotificationResponse( 163 uint8_t label, bool interim, std::string curr_song_id, 164 std::vector<SongInfo> song_list); 165 166 // GET CAPABILITY 167 virtual void HandleGetCapabilities( 168 uint8_t label, const std::shared_ptr<GetCapabilitiesRequest>& pkt); 169 170 // REGISTER NOTIFICATION 171 virtual void HandleNotification( 172 uint8_t label, const std::shared_ptr<RegisterNotificationRequest>& pkt); 173 174 // PLAY STATUS CHANGED 175 virtual void HandlePlayStatusUpdate(); 176 177 // NOW PLAYING LIST CHANGED 178 virtual void HandleNowPlayingUpdate(); 179 virtual void HandleNowPlayingNotificationResponse( 180 uint8_t label, bool interim, std::string curr_song_id, 181 std::vector<SongInfo> song_list); 182 183 // PLAY POSITION CHANGED 184 virtual void HandlePlayPosUpdate(); 185 virtual void PlaybackPosNotificationResponse(uint8_t label, bool interim, 186 PlayStatus status); 187 188 // GET PLAY STATUS 189 virtual void GetPlayStatusResponse(uint8_t label, PlayStatus status); 190 virtual void PlaybackStatusNotificationResponse(uint8_t label, bool interim, 191 PlayStatus status); 192 193 // PLAYER APPLICATION SETTINGS CHANGED 194 virtual void HandlePlayerSettingChanged( 195 std::vector<PlayerAttribute> attributes, std::vector<uint8_t> values); 196 virtual void PlayerSettingChangedNotificationResponse( 197 uint8_t label, bool interim, std::vector<PlayerAttribute> attributes, 198 std::vector<uint8_t> values); 199 200 // GET ELEMENT ATTRIBUTE 201 // TODO (apanicke): Add a Handler function for this so if a specific device 202 // needs to implement an interop fix, you only need to overload the one 203 // function. 204 virtual void GetElementAttributesResponse( 205 uint8_t label, std::shared_ptr<GetElementAttributesRequest> pkt, 206 SongInfo info); 207 208 // AVAILABLE PLAYER CHANGED 209 virtual void HandleAvailablePlayerUpdate(); 210 211 // ADDRESSED PLAYER CHANGED 212 virtual void HandleAddressedPlayerUpdate(); 213 virtual void RejectNotification(); 214 virtual void AddressedPlayerNotificationResponse( 215 uint8_t label, bool interim, uint16_t curr_player, 216 std::vector<MediaPlayerInfo> /* unused */); 217 218 // GET FOLDER ITEMS 219 virtual void HandleGetFolderItems( 220 uint8_t label, std::shared_ptr<GetFolderItemsRequest> request); 221 virtual void GetMediaPlayerListResponse( 222 uint8_t label, std::shared_ptr<GetFolderItemsRequest> pkt, 223 uint16_t curr_player, std::vector<MediaPlayerInfo> players); 224 virtual void GetVFSListResponse(uint8_t label, 225 std::shared_ptr<GetFolderItemsRequest> pkt, 226 std::vector<ListItem> items); 227 virtual void GetNowPlayingListResponse( 228 uint8_t label, std::shared_ptr<GetFolderItemsRequest> pkt, 229 std::string curr_song_id, std::vector<SongInfo> song_list); 230 231 // GET TOTAL NUMBER OF ITEMS 232 virtual void HandleGetTotalNumberOfItems( 233 uint8_t label, std::shared_ptr<GetTotalNumberOfItemsRequest> pkt); 234 virtual void GetTotalNumberOfItemsMediaPlayersResponse( 235 uint8_t label, uint16_t curr_player, std::vector<MediaPlayerInfo> list); 236 virtual void GetTotalNumberOfItemsVFSResponse(uint8_t label, 237 std::vector<ListItem> items); 238 virtual void GetTotalNumberOfItemsNowPlayingResponse( 239 uint8_t label, std::string curr_song_id, std::vector<SongInfo> song_list); 240 241 // GET ITEM ATTRIBUTES 242 virtual void HandleGetItemAttributes( 243 uint8_t label, std::shared_ptr<GetItemAttributesRequest> request); 244 virtual void GetItemAttributesNowPlayingResponse( 245 uint8_t label, std::shared_ptr<GetItemAttributesRequest> pkt, 246 std::string curr_media_id, std::vector<SongInfo> song_list); 247 virtual void GetItemAttributesVFSResponse( 248 uint8_t label, std::shared_ptr<GetItemAttributesRequest> pkt, 249 std::vector<ListItem> item_list); 250 251 // SET BROWSED PLAYER 252 virtual void HandleSetBrowsedPlayer( 253 uint8_t label, std::shared_ptr<SetBrowsedPlayerRequest> request); 254 virtual void SetBrowsedPlayerResponse( 255 uint8_t label, std::shared_ptr<SetBrowsedPlayerRequest> pkt, bool success, 256 std::string root_id, uint32_t num_items); 257 258 // CHANGE PATH 259 virtual void HandleChangePath(uint8_t label, 260 std::shared_ptr<ChangePathRequest> request); 261 virtual void ChangePathResponse(uint8_t label, 262 std::shared_ptr<ChangePathRequest> request, 263 std::vector<ListItem> list); 264 265 // PLAY ITEM 266 virtual void HandlePlayItem(uint8_t label, 267 std::shared_ptr<PlayItemRequest> request); 268 269 // SET ADDRESSED PLAYER 270 virtual void HandleSetAddressedPlayer( 271 uint8_t label, std::shared_ptr<SetAddressedPlayerRequest> request, 272 uint16_t curr_player, std::vector<MediaPlayerInfo> players); 273 274 // LIST PLAYER APPLICATION SETTING ATTRIBUTES 275 virtual void ListPlayerApplicationSettingAttributesResponse( 276 uint8_t label, std::vector<PlayerAttribute> attributes); 277 278 // LIST PLAYER APPLICATION SETTING VALUES 279 virtual void ListPlayerApplicationSettingValuesResponse( 280 uint8_t label, PlayerAttribute setting, std::vector<uint8_t> values); 281 282 // GET CURRENT PLAYER APPLICATION SETTING VALUE 283 virtual void GetPlayerApplicationSettingValueResponse( 284 uint8_t label, std::vector<PlayerAttribute> attributes, 285 std::vector<uint8_t> values); 286 287 // SET PLAYER APPLICATION SETTING VALUE 288 virtual void SetPlayerApplicationSettingValueResponse(uint8_t label, 289 CommandPdu pdu, 290 bool success); 291 292 /******************** 293 * MESSAGE REQUESTS 294 ********************/ 295 // VOLUME CHANGED NOTIFICATION 296 virtual void RegisterVolumeChanged(); 297 virtual void HandleVolumeChanged( 298 uint8_t label, const std::shared_ptr<RegisterNotificationResponse>& pkt); 299 300 // SET VOLUME 301 virtual void SetVolume(int8_t volume); 302 303 /** 304 * This function is called by Avrcp::ConnectionHandler to signify that 305 * the remote device was disconnected. 306 * 307 * TODO (apanicke): Prevent allowing responses to messages while the device is 308 * disconnected by using a weak pointer handle to the device when we separate 309 * out the message handling. Also separate the logic in the future when 310 * disconnecting only browsing (Though this shouldn't matter as if we are 311 * disconnecting browsing then we should be fully disconnecting the device). 312 */ 313 void DeviceDisconnected(); 314 315 friend std::ostream& operator<<(std::ostream& out, const Device& c); 316 317 private: 318 // This should always contain one item which represents the root id on the 319 // current player. CurrentFolder()320 std::string CurrentFolder() const { 321 if (current_path_.empty()) return ""; 322 return current_path_.top(); 323 } 324 send_message(uint8_t label,bool browse,std::unique_ptr<::bluetooth::PacketBuilder> message)325 void send_message(uint8_t label, bool browse, 326 std::unique_ptr<::bluetooth::PacketBuilder> message) { 327 active_labels_.erase(label); 328 send_message_cb_.Run(label, browse, std::move(message)); 329 } 330 331 // A2DP interface implementation connect_a2dp_sink_delayed(uint8_t handle)332 void connect_a2dp_sink_delayed(uint8_t handle) const { 333 a2dp_interface_->connect_audio_sink_delayed(handle, address_); 334 } 335 find_sink_service(tA2DP_FIND_CBACK p_cback)336 bool find_sink_service(tA2DP_FIND_CBACK p_cback) const { 337 return a2dp_interface_->find_audio_sink_service(address_, p_cback) == 338 A2DP_SUCCESS; 339 } 340 341 base::WeakPtrFactory<Device> weak_ptr_factory_; 342 343 // TODO (apanicke): Initialize all the variables in the constructor. 344 RawAddress address_; 345 346 // Enables AVRCP 1.3 Compatibility mode. This disables any AVRCP 1.4+ features 347 // such as browsing and playlists but has the highest chance of working. 348 bool avrcp13_compatibility_ = false; 349 base::RepeatingCallback<void( 350 uint8_t label, bool browse, 351 std::unique_ptr<::bluetooth::PacketBuilder> message)> 352 send_message_cb_; 353 uint16_t ctrl_mtu_; 354 uint16_t browse_mtu_; 355 bool has_bip_client_; 356 357 int curr_browsed_player_id_ = -1; 358 359 std::stack<std::string> current_path_; 360 361 // Notification Trackers 362 using Notification = std::pair<bool, uint8_t>; 363 Notification track_changed_ = Notification(false, 0); 364 Notification play_status_changed_ = Notification(false, 0); 365 Notification play_pos_changed_ = Notification(false, 0); 366 Notification player_setting_changed_ = Notification(false, 0); 367 Notification now_playing_changed_ = Notification(false, 0); 368 Notification addr_player_changed_ = Notification(false, 0); 369 Notification avail_players_changed_ = Notification(false, 0); 370 Notification uids_changed_ = Notification(false, 0); 371 372 MediaIdMap vfs_ids_; 373 MediaIdMap now_playing_ids_; 374 375 uint32_t play_pos_interval_ = 0; 376 377 SongInfo last_song_info_; 378 PlayStatus last_play_status_; 379 380 base::CancelableClosure play_pos_update_cb_; 381 382 MediaInterface* media_interface_ = nullptr; 383 A2dpInterface* a2dp_interface_ = nullptr; 384 VolumeInterface* volume_interface_ = nullptr; 385 PlayerSettingsInterface* player_settings_interface_ = nullptr; 386 387 // Labels used for messages currently in flight. 388 std::set<uint8_t> active_labels_; 389 390 int8_t volume_ = -1; 391 }; 392 393 } // namespace avrcp 394 } // namespace bluetooth 395