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