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