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