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   virtual std::vector<std::shared_ptr<Device>> GetListOfDevices() const;
114 
115   /**
116    * Provide a custom ConnectionHandler that will be returned by Get().
117    * Initialize and CleanUp should not be called as the owner of the handler
118    * determines its lifetime.
119    */
120   static void InitForTesting(ConnectionHandler* handler);
121 
122  private:
123   AvrcpInterface* avrc_;
124   SdpInterface* sdp_;
125   VolumeInterface* vol_;
126 
127   ConnectionCallback connection_cb_;
128 
129   std::map<uint8_t, std::shared_ptr<Device>> device_map_;
130   // TODO (apanicke): Replace the features with a class that has individual
131   // fields.
132   std::map<RawAddress, uint16_t> feature_map_;
133 
134   static ConnectionHandler* instance_;
135 
136   using SdpCallback = base::Callback<void(uint16_t status, uint16_t version,
137                                           uint16_t features)>;
138   virtual bool SdpLookup(const RawAddress& bdaddr, SdpCallback cb, bool retry);
139   void SdpCb(const RawAddress& bdaddr, SdpCallback cb,
140              tSDP_DISCOVERY_DB* disc_db, bool retry, uint16_t status);
141 
142   virtual bool AvrcpConnect(bool initiator, const RawAddress& bdaddr);
143 
144   // Callbacks when connecting to a device
145   void InitiatorControlCb(uint8_t handle, uint8_t event, uint16_t result,
146                           const RawAddress* peer_addr);
147   void AcceptorControlCb(uint8_t handle, uint8_t event, uint16_t result,
148                          const RawAddress* peer_addr);
149   void MessageCb(uint8_t handle, uint8_t label, uint8_t opcode,
150                  tAVRC_MSG* p_msg);
151 
ConnectionHandler()152   ConnectionHandler() : weak_ptr_factory_(this){};
153   virtual ~ConnectionHandler() = default;
154 
155   // Callback for when sending a response to a device
156   void SendMessage(uint8_t handle, uint8_t label, bool browse,
157                    std::unique_ptr<::bluetooth::PacketBuilder> message);
158 
159   base::WeakPtrFactory<ConnectionHandler> weak_ptr_factory_;
160   DISALLOW_COPY_AND_ASSIGN(ConnectionHandler);
161 };
162 
163 }  // namespace avrcp
164 }  // namespace bluetooth
165