1 //
2 // Copyright 2017 Google, Inc.
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 #include "service/a2dp_sink.h"
18
19 #include <base/logging.h>
20 #include <base/memory/ptr_util.h>
21
22 #include "service/logging_helpers.h"
23
24 using bluetooth::hal::BluetoothAvInterface;
25
26 namespace bluetooth {
27
28 // static
29 const int A2dpSink::kSingletonInstanceId = 0;
30
A2dpSink(const Uuid & uuid)31 A2dpSink::A2dpSink(const Uuid& uuid) : app_identifier_(uuid) {
32 hal::BluetoothAvInterface::Get()->AddA2dpSinkObserver(this);
33 }
34
~A2dpSink()35 A2dpSink::~A2dpSink() {
36 hal::BluetoothAvInterface::Get()->RemoveA2dpSinkObserver(this);
37 }
38
GetAppIdentifier() const39 const Uuid& A2dpSink::GetAppIdentifier() const { return app_identifier_; }
40
GetInstanceId() const41 int A2dpSink::GetInstanceId() const { return kSingletonInstanceId; }
42
SetDelegate(Delegate * delegate)43 void A2dpSink::SetDelegate(Delegate* delegate) {
44 std::lock_guard<std::mutex> lock(delegate_mutex_);
45 delegate_ = delegate;
46 }
47
Enable()48 bool A2dpSink::Enable() {
49 std::lock_guard<std::mutex> lock(mutex_);
50 return hal::BluetoothAvInterface::Get()->A2dpSinkEnable();
51 }
52
Disable()53 void A2dpSink::Disable() {
54 std::lock_guard<std::mutex> lock(mutex_);
55 hal::BluetoothAvInterface::Get()->A2dpSinkDisable();
56 }
57
Connect(const std::string & device_address)58 bool A2dpSink::Connect(const std::string& device_address) {
59 std::lock_guard<std::mutex> lock(mutex_);
60 RawAddress addr;
61 if (!RawAddress::FromString(device_address, addr)) {
62 LOG(ERROR) << "Invalid device address given: " << device_address;
63 return false;
64 }
65
66 bt_status_t status =
67 hal::BluetoothAvInterface::Get()->GetA2dpSinkHALInterface()->connect(
68 addr);
69 if (status != BT_STATUS_SUCCESS) {
70 LOG(ERROR) << "Failed to connect";
71 return false;
72 }
73
74 return true;
75 }
76
Disconnect(const std::string & device_address)77 bool A2dpSink::Disconnect(const std::string& device_address) {
78 std::lock_guard<std::mutex> lock(mutex_);
79 RawAddress addr;
80 if (!RawAddress::FromString(device_address, addr)) {
81 LOG(ERROR) << "Invalid device address given: " << device_address;
82 return false;
83 }
84
85 bt_status_t status =
86 hal::BluetoothAvInterface::Get()->GetA2dpSinkHALInterface()->disconnect(
87 addr);
88 if (status != BT_STATUS_SUCCESS) {
89 LOG(ERROR) << "Failed to disconnect";
90 return false;
91 }
92
93 return true;
94 }
95
SetAudioFocusState(int focus_state)96 void A2dpSink::SetAudioFocusState(int focus_state) {
97 std::lock_guard<std::mutex> lock(mutex_);
98 hal::BluetoothAvInterface::Get()
99 ->GetA2dpSinkHALInterface()
100 ->set_audio_focus_state(focus_state);
101 }
102
SetAudioTrackGain(float gain)103 void A2dpSink::SetAudioTrackGain(float gain) {
104 std::lock_guard<std::mutex> lock(mutex_);
105 hal::BluetoothAvInterface::Get()
106 ->GetA2dpSinkHALInterface()
107 ->set_audio_track_gain(gain);
108 }
109
ConnectionStateCallback(BluetoothAvInterface * iface,const RawAddress & bd_addr,btav_connection_state_t state)110 void A2dpSink::ConnectionStateCallback(BluetoothAvInterface* iface,
111 const RawAddress& bd_addr,
112 btav_connection_state_t state) {
113 std::string device_address = BtAddrString(&bd_addr);
114 std::lock_guard<std::mutex> lock(delegate_mutex_);
115
116 if (delegate_)
117 delegate_->OnConnectionState(device_address, static_cast<int>(state));
118 }
119
AudioStateCallback(BluetoothAvInterface * iface,const RawAddress & bd_addr,btav_audio_state_t state)120 void A2dpSink::AudioStateCallback(BluetoothAvInterface* iface,
121 const RawAddress& bd_addr,
122 btav_audio_state_t state) {
123 std::string device_address = BtAddrString(&bd_addr);
124 std::lock_guard<std::mutex> lock(delegate_mutex_);
125
126 if (delegate_)
127 delegate_->OnAudioState(device_address, static_cast<int>(state));
128 }
129
AudioConfigCallback(BluetoothAvInterface * iface,const RawAddress & bd_addr,uint32_t sample_rate,uint8_t channel_count)130 void A2dpSink::AudioConfigCallback(BluetoothAvInterface* iface,
131 const RawAddress& bd_addr,
132 uint32_t sample_rate,
133 uint8_t channel_count) {
134 std::string device_address = BtAddrString(&bd_addr);
135 std::lock_guard<std::mutex> lock(delegate_mutex_);
136 if (delegate_)
137 delegate_->OnAudioConfig(device_address, sample_rate, channel_count);
138 }
139
140 // A2dpSinkFactory implementation
141 // ========================================================
142 A2dpSinkFactory::A2dpSinkFactory() = default;
143 A2dpSinkFactory::~A2dpSinkFactory() = default;
144
RegisterInstance(const Uuid & uuid,const RegisterCallback & callback)145 bool A2dpSinkFactory::RegisterInstance(const Uuid& uuid,
146 const RegisterCallback& callback) {
147 VLOG(1) << __func__ << " - Uuid: " << uuid.ToString();
148
149 auto a2dp_sink = base::WrapUnique(new A2dpSink(uuid));
150 callback(BLE_STATUS_SUCCESS, uuid, std::move(a2dp_sink));
151 return true;
152 }
153
154 } // namespace bluetooth
155