• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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