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