Implement A2DP sink and AVRCP controller binder server
Also added bonded device management because this is needed for A2DP to
work with most devices.
Bug: 32657860
Test: Run on device, modified tests pass.
Change-Id: I862e41b6594b7cec9f61094d300577574cc8bbc6
diff --git a/service/a2dp_sink.cc b/service/a2dp_sink.cc
new file mode 100644
index 0000000..4d59c7c
--- /dev/null
+++ b/service/a2dp_sink.cc
@@ -0,0 +1,154 @@
+//
+// Copyright 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.
+//
+
+#include "service/a2dp_sink.h"
+
+#include <base/logging.h>
+#include <base/memory/ptr_util.h>
+
+#include "service/logging_helpers.h"
+
+using bluetooth::hal::BluetoothAvInterface;
+
+namespace bluetooth {
+
+// static
+const int A2dpSink::kSingletonInstanceId = 0;
+
+A2dpSink::A2dpSink(const Uuid& uuid) : app_identifier_(uuid) {
+ hal::BluetoothAvInterface::Get()->AddA2dpSinkObserver(this);
+}
+
+A2dpSink::~A2dpSink() {
+ hal::BluetoothAvInterface::Get()->RemoveA2dpSinkObserver(this);
+}
+
+const Uuid& A2dpSink::GetAppIdentifier() const { return app_identifier_; }
+
+int A2dpSink::GetInstanceId() const { return kSingletonInstanceId; }
+
+void A2dpSink::SetDelegate(Delegate* delegate) {
+ std::lock_guard<std::mutex> lock(delegate_mutex_);
+ delegate_ = delegate;
+}
+
+bool A2dpSink::Enable() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return hal::BluetoothAvInterface::Get()->A2dpSinkEnable();
+}
+
+void A2dpSink::Disable() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ hal::BluetoothAvInterface::Get()->A2dpSinkDisable();
+}
+
+bool A2dpSink::Connect(const std::string& device_address) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ RawAddress addr;
+ if (!RawAddress::FromString(device_address, addr)) {
+ LOG(ERROR) << "Invalid device address given: " << device_address;
+ return false;
+ }
+
+ bt_status_t status =
+ hal::BluetoothAvInterface::Get()->GetA2dpSinkHALInterface()->connect(
+ addr);
+ if (status != BT_STATUS_SUCCESS) {
+ LOG(ERROR) << "Failed to connect";
+ return false;
+ }
+
+ return true;
+}
+
+bool A2dpSink::Disconnect(const std::string& device_address) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ RawAddress addr;
+ if (!RawAddress::FromString(device_address, addr)) {
+ LOG(ERROR) << "Invalid device address given: " << device_address;
+ return false;
+ }
+
+ bt_status_t status =
+ hal::BluetoothAvInterface::Get()->GetA2dpSinkHALInterface()->disconnect(
+ addr);
+ if (status != BT_STATUS_SUCCESS) {
+ LOG(ERROR) << "Failed to disconnect";
+ return false;
+ }
+
+ return true;
+}
+
+void A2dpSink::SetAudioFocusState(int focus_state) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ hal::BluetoothAvInterface::Get()
+ ->GetA2dpSinkHALInterface()
+ ->set_audio_focus_state(focus_state);
+}
+
+void A2dpSink::SetAudioTrackGain(float gain) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ hal::BluetoothAvInterface::Get()
+ ->GetA2dpSinkHALInterface()
+ ->set_audio_track_gain(gain);
+}
+
+void A2dpSink::ConnectionStateCallback(BluetoothAvInterface* iface,
+ const RawAddress& bd_addr,
+ btav_connection_state_t state) {
+ std::string device_address = BtAddrString(&bd_addr);
+ std::lock_guard<std::mutex> lock(delegate_mutex_);
+
+ if (delegate_)
+ delegate_->OnConnectionState(device_address, static_cast<int>(state));
+}
+
+void A2dpSink::AudioStateCallback(BluetoothAvInterface* iface,
+ const RawAddress& bd_addr,
+ btav_audio_state_t state) {
+ std::string device_address = BtAddrString(&bd_addr);
+ std::lock_guard<std::mutex> lock(delegate_mutex_);
+
+ if (delegate_)
+ delegate_->OnAudioState(device_address, static_cast<int>(state));
+}
+
+void A2dpSink::AudioConfigCallback(BluetoothAvInterface* iface,
+ const RawAddress& bd_addr,
+ uint32_t sample_rate,
+ uint8_t channel_count) {
+ std::string device_address = BtAddrString(&bd_addr);
+ std::lock_guard<std::mutex> lock(delegate_mutex_);
+ if (delegate_)
+ delegate_->OnAudioConfig(device_address, sample_rate, channel_count);
+}
+
+// A2dpSinkFactory implementation
+// ========================================================
+A2dpSinkFactory::A2dpSinkFactory() = default;
+A2dpSinkFactory::~A2dpSinkFactory() = default;
+
+bool A2dpSinkFactory::RegisterInstance(const Uuid& uuid,
+ const RegisterCallback& callback) {
+ VLOG(1) << __func__ << " - Uuid: " << uuid.ToString();
+
+ auto a2dp_sink = base::WrapUnique(new A2dpSink(uuid));
+ callback(BLE_STATUS_SUCCESS, uuid, std::move(a2dp_sink));
+ return true;
+}
+
+} // namespace bluetooth