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/functional/bind.h>
20 #include <base/memory/weak_ptr.h>
21 
22 #include <map>
23 #include <memory>
24 #include <vector>
25 
26 #include "avrcp_internal.h"
27 #include "packet/avrcp/avrcp_packet.h"
28 #include "packet/base/packet.h"
29 #include "profile/avrcp/device.h"
30 #include "raw_address.h"
31 
32 namespace bluetooth {
33 namespace avrcp {
34 
35 // TODO: Remove the singleton design structure for this class.
36 // AvrcpTargetService is already a singleton and can manage the lifetime of this
37 // object. multiple singleton objects can lead to code that is hard to test and
38 // have hard to debug lifetimes.
39 
40 // TODO (apanicke): Use a device factory instead of just the constructor in
41 // order to create device objects. This will allow us to create specific device
42 // classes that can provide interop fixes for certain badly behaving devices.
43 
44 /**
45  * ConnectionHandler handles SDP, connecting to remote AVRCP devices
46  * and multiplexing/delivering messages to devices.
47  */
48 class ConnectionHandler {
49  public:
50   /**
51    * This callback is used to return a new device after a connection attempt.
52    * A reference to the new Avrcp device is located in the shared_ptr.
53    * If there was an issue during connection the pointer value will be null.
54    */
55   using ConnectionCallback =
56       base::RepeatingCallback<void(std::shared_ptr<Device>)>;
57 
58   /**
59    * Initializes the singleton instance and sets up SDP. Also Opens the
60    * AVRCP Acceptor to receive connection requests from a remote device.
61    *
62    * Params:
63    * callback - A callback that gets called any time a new AVRCP Device
64    *            is connected. Will return nullpointer if a device fails
65    *            to connect via ConnectDevice();
66    *
67    * TODO: Add message loop to determine which thread events are posted to
68    */
69   static bool Initialize(const ConnectionCallback& callback,
70                          AvrcpInterface* avrcp, SdpInterface* sdp,
71                          VolumeInterface* vol);
72 
73   /**
74    * Clears the singleton and tears down SDP
75    */
76   static bool CleanUp();
77 
78   /**
79    * Get the singleton instance of Connection Handler
80    */
81   static ConnectionHandler* Get();
82 
83   /**
84    * Attempt to connect AVRCP on a device. The callback will be called with
85    * either a smart pointer pointing to the connected AVRCP device or null
86    * if the connection failed.
87    *
88    * The order of operations for this function is as follows.
89    *   1. Perform SDP on remote device
90    *   2. Connect the AVCTP Channel
91    *   2. (Optional) If supported connect the AVCTP Browse channel
92    *   4. Call the provided callback with the new
93    *
94    * Params:
95    * bdaddr - Bluetooth address of device to connect to
96    * callback - The function that gets called when a connection succeeds or
97    *            fails. The pointer being cleared implies that the connection
98    *            failed.
99    *
100    * Returns:
101    * true if the connection attempt starts, false if there are no resources to
102    * connect AVRCP
103    */
104   virtual bool ConnectDevice(const RawAddress& bdaddr);
105 
106   /**
107    * Disconnects AVRCP from a device that was successfully connected too using
108    * ConnectionHandler::ConnectDevice
109    *
110    * Returns:
111    * true if the AVRCP was successfully disconnected for the device or false
112    * if the device was already disconnected or in an invalid state
113    */
114   virtual bool DisconnectDevice(const RawAddress& bdaddr);
115 
116   /**
117    * Indicates the connection status of a device on the BIP OBEX server.
118    *
119    * This status is used to determine whether we should include image handles
120    * when building responses for media item metadata queries.
121    */
122   virtual void SetBipClientStatus(const RawAddress& bdaddr, bool connected);
123 
124   virtual std::vector<std::shared_ptr<Device>> GetListOfDevices() const;
125 
126   /**
127    * Provide a custom ConnectionHandler that will be returned by Get().
128    * Initialize and CleanUp should not be called as the owner of the handler
129    * determines its lifetime.
130    */
131   static void InitForTesting(ConnectionHandler* handler);
132 
133   virtual void RegisterVolChanged(const RawAddress& bdaddr);
134 
135  private:
136   AvrcpInterface* avrc_;
137   SdpInterface* sdp_;
138   VolumeInterface* vol_;
139 
140   ConnectionCallback connection_cb_;
141 
142   std::map<uint8_t, std::shared_ptr<Device>> device_map_;
143   // TODO (apanicke): Replace the features with a class that has individual
144   // fields.
145   std::map<RawAddress, uint16_t> feature_map_;
146 
147   static ConnectionHandler* instance_;
148 
149   using SdpCallback = base::Callback<void(uint16_t status, uint16_t version,
150                                           uint16_t features)>;
151   virtual bool SdpLookup(const RawAddress& bdaddr, SdpCallback cb, bool retry);
152   void SdpCb(RawAddress bdaddr, SdpCallback cb,
153              tSDP_DISCOVERY_DB* disc_db, bool retry, uint16_t status);
154 
155   virtual bool AvrcpConnect(bool initiator, const RawAddress& bdaddr);
156 
157   // Callbacks when connecting to a device
158   void InitiatorControlCb(uint8_t handle, uint8_t event, uint16_t result,
159                           const RawAddress* peer_addr);
160   void AcceptorControlCb(uint8_t handle, uint8_t event, uint16_t result,
161                          const RawAddress* peer_addr);
162   void MessageCb(uint8_t handle, uint8_t label, uint8_t opcode,
163                  tAVRC_MSG* p_msg);
164 
ConnectionHandler()165   ConnectionHandler() : weak_ptr_factory_(this){};
166   ConnectionHandler(const ConnectionHandler&) = delete;
167   ConnectionHandler& operator=(const ConnectionHandler&) = delete;
168 
169   virtual ~ConnectionHandler() = default;
170 
171   // Callback for when sending a response to a device
172   void SendMessage(uint8_t handle, uint8_t label, bool browse,
173                    std::unique_ptr<::bluetooth::PacketBuilder> message);
174 
175   // Check peer role: audio src or sink. If any role supported send
176   // delayed a2dp connect request
177   bool SdpLookupAudioRole(uint16_t handle);
178   void SdpLookupAudioRoleCb(uint16_t handle, bool found,
179                             tA2DP_Service* p_service,
180                             const RawAddress& peer_address);
181 
182   base::WeakPtrFactory<ConnectionHandler> weak_ptr_factory_;
183 };
184 
185 }  // namespace avrcp
186 }  // namespace bluetooth
187