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