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