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
|
//
// Copyright (C) 2017 Google, Inc.
//
// 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 <atomic>
#include <mutex>
#include <string>
#include <vector>
#include "service/bluetooth_instance.h"
#include "service/common/bluetooth/a2dp_codec_config.h"
#include "service/hal/bluetooth_av_interface.h"
#include "types/raw_address.h"
namespace bluetooth {
class A2dpSource : public BluetoothInstance,
private hal::BluetoothAvInterface::A2dpSourceObserver {
public:
// We only allow one instance of this object at a time.
static const int kSingletonInstanceId;
class Delegate {
public:
virtual void OnConnectionState(const std::string& device_address,
int state) = 0;
virtual void OnAudioState(const std::string& device_address, int state) = 0;
virtual void OnAudioConfig(
const std::string& device_address, A2dpCodecConfig codec_config,
const std::vector<A2dpCodecConfig>& codecs_local_capabilities,
const std::vector<A2dpCodecConfig>& codecs_selectable_capabilities) = 0;
protected:
virtual ~Delegate() = default;
};
A2dpSource(const A2dpSource&) = delete;
A2dpSource& operator=(const A2dpSource&) = delete;
~A2dpSource() override;
void SetDelegate(Delegate* delegate);
// BluetoothInstance implementation:
const Uuid& GetAppIdentifier() const override;
int GetInstanceId() const override;
bool Enable(const std::vector<A2dpCodecConfig>& codec_priorities);
void Disable();
bool Connect(const std::string& device_address);
bool Disconnect(const std::string& device_address);
bool ConfigCodec(const std::string& device_address,
const std::vector<A2dpCodecConfig>& codec_preferences);
private:
friend class A2dpSourceFactory;
explicit A2dpSource(const Uuid& uuid);
// hal::bluetooth::hal::BluetoothAvInterface::Observer implementation:
void ConnectionStateCallback(hal::BluetoothAvInterface* iface,
const RawAddress& bd_addr,
btav_connection_state_t state) override;
void AudioStateCallback(hal::BluetoothAvInterface* iface,
const RawAddress& bd_addr,
btav_audio_state_t state) override;
void AudioConfigCallback(
hal::BluetoothAvInterface* iface, const RawAddress& bd_addr,
const btav_a2dp_codec_config_t& codec_config,
const std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities,
const std::vector<btav_a2dp_codec_config_t>
codecs_selectable_capabilities) override;
bool MandatoryCodecPreferredCallback(hal::BluetoothAvInterface* iface,
const RawAddress& bd_addr) override;
// For |GetAppIdentifier|.
const Uuid app_identifier_;
std::mutex mutex_;
// A second mutex is used only for |delegate_|. We cannot use |mutex_| because
// it may cause a deadlock if the caller and Delegate both take the same lock
// 'clock'.
// In that scenario, the caller may take 'clock' first and will try to take
// |mutex_| second. The callback will take |mutex_| first and invoke a
// delegate function which attempts to take 'clock'.
std::mutex delegate_mutex_;
Delegate* delegate_ = nullptr;
};
class A2dpSourceFactory : public BluetoothInstanceFactory {
public:
A2dpSourceFactory();
A2dpSourceFactory(const A2dpSourceFactory&) = delete;
A2dpSourceFactory& operator=(const A2dpSourceFactory&) = delete;
~A2dpSourceFactory() override;
// BluetoothInstanceFactory override:
bool RegisterInstance(const Uuid& uuid,
const RegisterCallback& callback) override;
};
} // namespace bluetooth
|