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 26 #include "avrcp_internal.h" 27 #include "hardware/avrcp/avrcp.h" 28 #include "packet/avrcp/avrcp_browse_packet.h" 29 #include "packet/avrcp/avrcp_packet.h" 30 #include "packet/avrcp/capabilities_packet.h" 31 #include "packet/avrcp/change_path.h" 32 #include "packet/avrcp/get_current_player_application_setting_value.h" 33 #include "packet/avrcp/get_element_attributes_packet.h" 34 #include "packet/avrcp/get_folder_items.h" 35 #include "packet/avrcp/get_item_attributes.h" 36 #include "packet/avrcp/get_total_number_of_items.h" 37 #include "packet/avrcp/list_player_application_setting_attributes.h" 38 #include "packet/avrcp/list_player_application_setting_values.h" 39 #include "packet/avrcp/play_item.h" 40 #include "packet/avrcp/register_notification_packet.h" 41 #include "packet/avrcp/set_addressed_player.h" 42 #include "packet/avrcp/set_browsed_player.h" 43 #include "packet/avrcp/set_player_application_setting_value.h" 44 #include "packet/avrcp/vendor_packet.h" 45 #include "profile/avrcp/media_id_map.h" 46 #include "raw_address.h" 47 48 namespace bluetooth { 49 namespace avrcp { 50 51 /** 52 * A class representing a connection with a remote AVRCP device. It holds all 53 * the state and message handling for the device that it represents. 54 */ 55 // TODO (apanicke): Once we move over to having the individual message 56 // responders for Browse and Classic AVRCP Messages move the device around via a 57 // weak pointer. 58 class Device { 59 public: 60 /** 61 * Device is friends with Avrcp::ConnectionHandler so that ConnectionHandler 62 * can deliver messages to individual devices. 63 */ 64 friend class ConnectionHandler; 65 66 Device( 67 const RawAddress& bdaddr, bool avrcp13_compatibility, 68 base::Callback<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, 119 A2dpInterface* a2dp_interface, 120 VolumeInterface* volume_interface, 121 PlayerSettingsInterface* player_settings_interface); 122 123 /** 124 * Set the maximum size of a AVRCP Browsing Packet. This is done after the 125 * connection of the Browsing channel. 126 */ 127 void SetBrowseMtu(uint16_t browse_mtu); 128 129 /** 130 * Notify the device that metadata, play_status, and/or queue have updated 131 * via a boolean. Each boolean represents whether its respective content has 132 * updated. 133 */ 134 virtual void SendMediaUpdate(bool metadata, bool play_status, bool queue); 135 136 /** 137 * Notify the device that the available_player, addressed_player, or UIDs 138 * have updated via a boolean. Each boolean represents whether its respective 139 * content has updated. 140 */ 141 virtual void SendFolderUpdate(bool available_player, bool addressed_player, 142 bool uids); 143 144 // TODO (apanicke): Split the message handlers into two files. One 145 // for handling Browse Messages and the other for handling all other 146 // messages. This prevents the .cc file from getting bloated like it is 147 // now. The Device class will then become a state holder for each message 148 // and all the functions in these handler classes can be static since the 149 // device will be passed in. The extensions of the Device class can contain 150 // any interop handling for specific messages on specific devices. 151 152 void MessageReceived(uint8_t label, std::shared_ptr<Packet> pkt); 153 void BrowseMessageReceived(uint8_t label, std::shared_ptr<BrowsePacket> pkt); 154 void VendorPacketHandler(uint8_t label, std::shared_ptr<VendorPacket> pkt); 155 156 /******************** 157 * MESSAGE RESPONSES 158 ********************/ 159 // CURRENT TRACK CHANGED 160 virtual void HandleTrackUpdate(); 161 virtual void TrackChangedNotificationResponse( 162 uint8_t label, bool interim, std::string curr_song_id, 163 std::vector<SongInfo> song_list); 164 165 // GET CAPABILITY 166 virtual void HandleGetCapabilities( 167 uint8_t label, const std::shared_ptr<GetCapabilitiesRequest>& pkt); 168 169 // REGISTER NOTIFICATION 170 virtual void HandleNotification( 171 uint8_t label, const std::shared_ptr<RegisterNotificationRequest>& pkt); 172 173 // PLAY STATUS CHANGED 174 virtual void HandlePlayStatusUpdate(); 175 176 // NOW PLAYING LIST CHANGED 177 virtual void HandleNowPlayingUpdate(); 178 virtual void HandleNowPlayingNotificationResponse( 179 uint8_t label, bool interim, std::string curr_song_id, 180 std::vector<SongInfo> song_list); 181 182 // PLAY POSITION CHANGED 183 virtual void HandlePlayPosUpdate(); 184 virtual void PlaybackPosNotificationResponse(uint8_t label, bool interim, 185 PlayStatus status); 186 187 // GET PLAY STATUS 188 virtual void GetPlayStatusResponse(uint8_t label, PlayStatus status); 189 virtual void PlaybackStatusNotificationResponse(uint8_t label, bool interim, 190 PlayStatus status); 191 192 // PLAYER APPLICATION SETTINGS CHANGED 193 virtual void HandlePlayerSettingChanged( 194 std::vector<PlayerAttribute> attributes, std::vector<uint8_t> values); 195 virtual void PlayerSettingChangedNotificationResponse( 196 uint8_t label, bool interim, std::vector<PlayerAttribute> attributes, 197 std::vector<uint8_t> values); 198 199 // GET ELEMENT ATTRIBUTE 200 // TODO (apanicke): Add a Handler function for this so if a specific device 201 // needs to implement an interop fix, you only need to overload the one 202 // function. 203 virtual void GetElementAttributesResponse( 204 uint8_t label, std::shared_ptr<GetElementAttributesRequest> pkt, 205 SongInfo info); 206 207 // AVAILABLE PLAYER CHANGED 208 virtual void HandleAvailablePlayerUpdate(); 209 210 // ADDRESSED PLAYER CHANGED 211 virtual void HandleAddressedPlayerUpdate(); 212 virtual void RejectNotification(); 213 virtual void AddressedPlayerNotificationResponse( 214 uint8_t label, bool interim, uint16_t curr_player, 215 std::vector<MediaPlayerInfo> /* unused */); 216 217 // GET FOLDER ITEMS 218 virtual void HandleGetFolderItems( 219 uint8_t label, std::shared_ptr<GetFolderItemsRequest> request); 220 virtual void GetMediaPlayerListResponse( 221 uint8_t label, std::shared_ptr<GetFolderItemsRequest> pkt, 222 uint16_t curr_player, std::vector<MediaPlayerInfo> players); 223 virtual void GetVFSListResponse(uint8_t label, 224 std::shared_ptr<GetFolderItemsRequest> pkt, 225 std::vector<ListItem> items); 226 virtual void GetNowPlayingListResponse( 227 uint8_t label, std::shared_ptr<GetFolderItemsRequest> pkt, 228 std::string curr_song_id, std::vector<SongInfo> song_list); 229 230 // GET TOTAL NUMBER OF ITEMS 231 virtual void HandleGetTotalNumberOfItems( 232 uint8_t label, std::shared_ptr<GetTotalNumberOfItemsRequest> pkt); 233 virtual void GetTotalNumberOfItemsMediaPlayersResponse( 234 uint8_t label, uint16_t curr_player, std::vector<MediaPlayerInfo> list); 235 virtual void GetTotalNumberOfItemsVFSResponse(uint8_t label, 236 std::vector<ListItem> items); 237 virtual void GetTotalNumberOfItemsNowPlayingResponse( 238 uint8_t label, std::string curr_song_id, std::vector<SongInfo> song_list); 239 240 // GET ITEM ATTRIBUTES 241 virtual void HandleGetItemAttributes( 242 uint8_t label, std::shared_ptr<GetItemAttributesRequest> request); 243 virtual void GetItemAttributesNowPlayingResponse( 244 uint8_t label, std::shared_ptr<GetItemAttributesRequest> pkt, 245 std::string curr_media_id, std::vector<SongInfo> song_list); 246 virtual void GetItemAttributesVFSResponse( 247 uint8_t label, std::shared_ptr<GetItemAttributesRequest> pkt, 248 std::vector<ListItem> item_list); 249 250 // SET BROWSED PLAYER 251 virtual void HandleSetBrowsedPlayer( 252 uint8_t label, std::shared_ptr<SetBrowsedPlayerRequest> request); 253 virtual void SetBrowsedPlayerResponse( 254 uint8_t label, std::shared_ptr<SetBrowsedPlayerRequest> pkt, bool success, 255 std::string root_id, uint32_t num_items); 256 257 // CHANGE PATH 258 virtual void HandleChangePath(uint8_t label, 259 std::shared_ptr<ChangePathRequest> request); 260 virtual void ChangePathResponse(uint8_t label, 261 std::shared_ptr<ChangePathRequest> request, 262 std::vector<ListItem> list); 263 264 // PLAY ITEM 265 virtual void HandlePlayItem(uint8_t label, 266 std::shared_ptr<PlayItemRequest> request); 267 268 // SET ADDRESSED PLAYER 269 virtual void HandleSetAddressedPlayer( 270 uint8_t label, std::shared_ptr<SetAddressedPlayerRequest> request, 271 uint16_t curr_player, std::vector<MediaPlayerInfo> players); 272 273 // LIST PLAYER APPLICATION SETTING ATTRIBUTES 274 virtual void ListPlayerApplicationSettingAttributesResponse( 275 uint8_t label, std::vector<PlayerAttribute> attributes); 276 277 // LIST PLAYER APPLICATION SETTING VALUES 278 virtual void ListPlayerApplicationSettingValuesResponse( 279 uint8_t label, PlayerAttribute setting, std::vector<uint8_t> values); 280 281 // GET CURRENT PLAYER APPLICATION SETTING VALUE 282 virtual void GetPlayerApplicationSettingValueResponse( 283 uint8_t label, std::vector<PlayerAttribute> attributes, 284 std::vector<uint8_t> values); 285 286 // SET PLAYER APPLICATION SETTING VALUE 287 virtual void SetPlayerApplicationSettingValueResponse(uint8_t label, 288 CommandPdu pdu, 289 bool success); 290 291 /******************** 292 * MESSAGE REQUESTS 293 ********************/ 294 // VOLUME CHANGED NOTIFICATION 295 virtual void RegisterVolumeChanged(); 296 virtual void HandleVolumeChanged( 297 uint8_t label, const std::shared_ptr<RegisterNotificationResponse>& pkt); 298 299 // SET VOLUME 300 virtual void SetVolume(int8_t volume); 301 302 /** 303 * This function is called by Avrcp::ConnectionHandler to signify that 304 * the remote device was disconnected. 305 * 306 * TODO (apanicke): Prevent allowing responses to messages while the device is 307 * disconnected by using a weak pointer handle to the device when we separate 308 * out the message handling. Also separate the logic in the future when 309 * disconnecting only browsing (Though this shouldn't matter as if we are 310 * disconnecting browsing then we should be fully disconnecting the device). 311 */ 312 void DeviceDisconnected(); 313 314 friend std::ostream& operator<<(std::ostream& out, const Device& c); 315 316 private: 317 // This should always contain one item which represents the root id on the 318 // current player. CurrentFolder()319 std::string CurrentFolder() const { 320 if (current_path_.empty()) return ""; 321 return current_path_.top(); 322 } 323 send_message(uint8_t label,bool browse,std::unique_ptr<::bluetooth::PacketBuilder> message)324 void send_message(uint8_t label, bool browse, 325 std::unique_ptr<::bluetooth::PacketBuilder> message) { 326 active_labels_.erase(label); 327 send_message_cb_.Run(label, browse, std::move(message)); 328 } 329 base::WeakPtrFactory<Device> weak_ptr_factory_; 330 331 // TODO (apanicke): Initialize all the variables in the constructor. 332 RawAddress address_; 333 334 // Enables AVRCP 1.3 Compatibility mode. This disables any AVRCP 1.4+ features 335 // such as browsing and playlists but has the highest chance of working. 336 bool avrcp13_compatibility_ = false; 337 base::Callback<void(uint8_t label, bool browse, 338 std::unique_ptr<::bluetooth::PacketBuilder> message)> 339 send_message_cb_; 340 uint16_t ctrl_mtu_; 341 uint16_t browse_mtu_; 342 bool has_bip_client_; 343 344 int curr_browsed_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