Implement A2DP source and AVRCP target binder servers
Bug: 64231556
Test: On device.
Change-Id: I57136d5550e8e52626a1e7eb26b7d8c02cd94eb5
diff --git a/service/Android.bp b/service/Android.bp
index 42be835..6d136aa 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -15,8 +15,10 @@
// ========================================================
btserviceDaemonSrc = [
"a2dp_sink.cc",
+ "a2dp_source.cc",
"adapter.cc",
"avrcp_control.cc",
+ "avrcp_target.cc",
"daemon.cc",
"gatt_client.cc",
"gatt_server.cc",
@@ -41,7 +43,9 @@
btserviceBinderDaemonSrc = [
"ipc/binder/bluetooth_a2dp_sink_binder_server.cc",
+ "ipc/binder/bluetooth_a2dp_source_binder_server.cc",
"ipc/binder/bluetooth_avrcp_control_binder_server.cc",
+ "ipc/binder/bluetooth_avrcp_target_binder_server.cc",
"ipc/binder/bluetooth_binder_server.cc",
"ipc/binder/bluetooth_gatt_client_binder_server.cc",
"ipc/binder/bluetooth_gatt_server_binder_server.cc",
diff --git a/service/a2dp_source.cc b/service/a2dp_source.cc
new file mode 100644
index 0000000..9e77007
--- /dev/null
+++ b/service/a2dp_source.cc
@@ -0,0 +1,216 @@
+//
+// 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.
+//
+
+#include "service/a2dp_source.h"
+
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "service/logging_helpers.h"
+
+#define PARSE_ADDR(str) \
+ ({ \
+ RawAddress tmp; \
+ if (!RawAddress::FromString((str), tmp)) { \
+ LOG(ERROR) << "Invalid device address given: " << (str); \
+ return false; \
+ } \
+ tmp; \
+ })
+
+#define TRY_RET(expr, err_msg) \
+ do { \
+ if (!(expr)) { \
+ LOG(ERROR) << err_msg; \
+ return false; \
+ } \
+ return true; \
+ } while (0)
+
+#define TRY_RET_FUNC(expr) TRY_RET(expr, __func__ << " failed")
+
+using bluetooth::hal::BluetoothAvInterface;
+using LockGuard = std::lock_guard<std::mutex>;
+
+namespace bluetooth {
+
+namespace {
+
+btav_a2dp_codec_config_t CodecConfigToFluoride(const A2dpCodecConfig& config) {
+ btav_a2dp_codec_config_t ret = {
+ .codec_type = static_cast<btav_a2dp_codec_index_t>(config.codec_type()),
+ .codec_priority =
+ static_cast<btav_a2dp_codec_priority_t>(config.codec_priority()),
+ .sample_rate =
+ static_cast<btav_a2dp_codec_sample_rate_t>(config.sample_rate()),
+ .bits_per_sample = static_cast<btav_a2dp_codec_bits_per_sample_t>(
+ config.bits_per_sample()),
+ .channel_mode =
+ static_cast<btav_a2dp_codec_channel_mode_t>(config.channel_mode()),
+ .codec_specific_1 = config.codec_specific_1(),
+ .codec_specific_2 = config.codec_specific_2(),
+ .codec_specific_3 = config.codec_specific_3(),
+ .codec_specific_4 = config.codec_specific_4(),
+ };
+
+ return ret;
+}
+
+std::vector<btav_a2dp_codec_config_t> CodecConfigsToFluoride(
+ const std::vector<A2dpCodecConfig>& configs) {
+ std::vector<btav_a2dp_codec_config_t> ret;
+ ret.reserve(configs.size());
+ for (const auto& config : configs) {
+ ret.push_back(CodecConfigToFluoride(config));
+ }
+
+ return ret;
+}
+A2dpCodecConfig FluorideCodecToCodec(const btav_a2dp_codec_config_t& config) {
+ A2dpCodecConfig ret(config.codec_type, config.codec_priority,
+ config.sample_rate, config.bits_per_sample,
+ config.channel_mode, config.codec_specific_1,
+ config.codec_specific_2, config.codec_specific_3,
+ config.codec_specific_4);
+
+ return ret;
+}
+
+std::vector<A2dpCodecConfig> FluorideCodecsToCodec(
+ const std::vector<btav_a2dp_codec_config_t>& configs) {
+ std::vector<A2dpCodecConfig> ret;
+ ret.reserve(configs.size());
+ for (const auto& config : configs) {
+ ret.push_back(FluorideCodecToCodec(config));
+ }
+
+ return ret;
+}
+
+} // namespace
+
+// static
+const int A2dpSource::kSingletonInstanceId = 0;
+
+A2dpSource::A2dpSource(const Uuid& uuid) : app_identifier_(uuid) {
+ hal::BluetoothAvInterface::Get()->AddA2dpSourceObserver(this);
+}
+
+A2dpSource::~A2dpSource() {
+ hal::BluetoothAvInterface::Get()->RemoveA2dpSourceObserver(this);
+}
+
+const Uuid& A2dpSource::GetAppIdentifier() const { return app_identifier_; }
+
+int A2dpSource::GetInstanceId() const { return kSingletonInstanceId; }
+
+void A2dpSource::SetDelegate(Delegate* delegate) {
+ LockGuard lock(delegate_mutex_);
+ delegate_ = delegate;
+}
+
+bool A2dpSource::Enable(const std::vector<A2dpCodecConfig>& codec_priorities) {
+ auto fluoride_priorities = CodecConfigsToFluoride(codec_priorities);
+ LockGuard lock(mutex_);
+ return hal::BluetoothAvInterface::Get()->A2dpSourceEnable(
+ fluoride_priorities);
+}
+
+void A2dpSource::Disable() {
+ LockGuard lock(mutex_);
+ hal::BluetoothAvInterface::Get()->A2dpSourceDisable();
+}
+
+bool A2dpSource::Connect(const std::string& device_address) {
+ RawAddress addr = PARSE_ADDR(device_address);
+ LockGuard lock(mutex_);
+ TRY_RET_FUNC(
+ hal::BluetoothAvInterface::Get()->GetA2dpSourceHALInterface()->connect(
+ addr) == BT_STATUS_SUCCESS);
+}
+
+bool A2dpSource::Disconnect(const std::string& device_address) {
+ RawAddress addr = PARSE_ADDR(device_address);
+ LockGuard lock(mutex_);
+ TRY_RET_FUNC(
+ hal::BluetoothAvInterface::Get()->GetA2dpSourceHALInterface()->disconnect(
+ addr) == BT_STATUS_SUCCESS);
+}
+
+bool A2dpSource::ConfigCodec(
+ const std::string& device_address,
+ const std::vector<A2dpCodecConfig>& codec_preferences) {
+ RawAddress addr = PARSE_ADDR(device_address);
+ auto fluoride_preferences = CodecConfigsToFluoride(codec_preferences);
+ LockGuard lock(mutex_);
+ TRY_RET_FUNC(hal::BluetoothAvInterface::Get()
+ ->GetA2dpSourceHALInterface()
+ ->config_codec(addr, fluoride_preferences) ==
+ BT_STATUS_SUCCESS);
+}
+
+void A2dpSource::ConnectionStateCallback(BluetoothAvInterface* iface,
+ const RawAddress& bd_addr,
+ btav_connection_state_t state) {
+ auto device_address = BtAddrString(&bd_addr);
+ LockGuard lock(delegate_mutex_);
+ if (delegate_)
+ delegate_->OnConnectionState(device_address, static_cast<int>(state));
+}
+
+void A2dpSource::AudioStateCallback(BluetoothAvInterface* iface,
+ const RawAddress& bd_addr,
+ btav_audio_state_t state) {
+ auto device_address = BtAddrString(&bd_addr);
+ LockGuard lock(delegate_mutex_);
+ if (delegate_)
+ delegate_->OnAudioState(device_address, static_cast<int>(state));
+}
+
+void A2dpSource::AudioConfigCallback(
+ BluetoothAvInterface* iface, const RawAddress& bd_addr,
+ const btav_a2dp_codec_config_t& codec_config_fluoride,
+ const std::vector<btav_a2dp_codec_config_t>
+ codecs_local_capabilities_fluoride,
+ const std::vector<btav_a2dp_codec_config_t>
+ codecs_selectable_capabilities_fluoride) {
+ auto device_address = BtAddrString(&bd_addr);
+ auto codec_config = FluorideCodecToCodec(codec_config_fluoride);
+ auto codecs_local_capabilities =
+ FluorideCodecsToCodec(codecs_local_capabilities_fluoride);
+ auto codecs_selectable_capabilities =
+ FluorideCodecsToCodec(codecs_selectable_capabilities_fluoride);
+ LockGuard lock(delegate_mutex_);
+ if (delegate_)
+ delegate_->OnAudioConfig(device_address, codec_config,
+ codecs_local_capabilities,
+ codecs_selectable_capabilities);
+}
+
+// A2dpSourceFactory implementation
+// ========================================================
+A2dpSourceFactory::A2dpSourceFactory() = default;
+A2dpSourceFactory::~A2dpSourceFactory() = default;
+
+bool A2dpSourceFactory::RegisterInstance(const Uuid& uuid,
+ const RegisterCallback& callback) {
+ VLOG(1) << __func__ << " - UUID: " << uuid.ToString();
+
+ auto a2dp_source = base::WrapUnique(new A2dpSource(uuid));
+ callback(BLE_STATUS_SUCCESS, uuid, std::move(a2dp_source));
+ return true;
+}
+
+} // namespace bluetooth
diff --git a/service/a2dp_source.h b/service/a2dp_source.h
new file mode 100644
index 0000000..f4e3ab3
--- /dev/null
+++ b/service/a2dp_source.h
@@ -0,0 +1,116 @@
+//
+// 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 <base/macros.h>
+
+#include "service/bluetooth_instance.h"
+#include "service/common/bluetooth/a2dp_codec_config.h"
+#include "service/hal/bluetooth_av_interface.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() 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;
+
+ // 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;
+
+ DISALLOW_COPY_AND_ASSIGN(A2dpSource);
+};
+
+class A2dpSourceFactory : public BluetoothInstanceFactory {
+ public:
+ A2dpSourceFactory();
+ ~A2dpSourceFactory() override;
+
+ // BluetoothInstanceFactory override:
+ bool RegisterInstance(const Uuid& uuid,
+ const RegisterCallback& callback) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(A2dpSourceFactory);
+};
+
+} // namespace bluetooth
diff --git a/service/adapter.cc b/service/adapter.cc
index 2363127..b721ef8 100644
--- a/service/adapter.cc
+++ b/service/adapter.cc
@@ -25,7 +25,9 @@
#include <base/observer_list.h>
#include "service/a2dp_sink.h"
+#include "service/a2dp_source.h"
#include "service/avrcp_control.h"
+#include "service/avrcp_target.h"
#include "service/common/bluetooth/util/atomic_string.h"
#include "service/gatt_client.h"
#include "service/gatt_server.h"
@@ -202,7 +204,9 @@
memset(&local_le_features_, 0, sizeof(local_le_features_));
hal::BluetoothInterface::Get()->AddObserver(this);
a2dp_sink_factory_.reset(new A2dpSinkFactory);
+ a2dp_source_factory_.reset(new A2dpSourceFactory);
avrcp_control_factory_.reset(new AvrcpControlFactory);
+ avrcp_target_factory_.reset(new AvrcpTargetFactory);
ble_client_factory_.reset(new LowEnergyClientFactory(*this));
ble_advertiser_factory_.reset(new LowEnergyAdvertiserFactory());
ble_scanner_factory_.reset(new LowEnergyScannerFactory(*this));
@@ -466,10 +470,18 @@
return a2dp_sink_factory_.get();
}
+ A2dpSourceFactory* GetA2dpSourceFactory() const override {
+ return a2dp_source_factory_.get();
+ }
+
AvrcpControlFactory* GetAvrcpControlFactory() const override {
return avrcp_control_factory_.get();
}
+ AvrcpTargetFactory* GetAvrcpTargetFactory() const override {
+ return avrcp_target_factory_.get();
+ }
+
LowEnergyClientFactory* GetLowEnergyClientFactory() const override {
return ble_client_factory_.get();
}
@@ -764,9 +776,15 @@
// Factory used to create per-app A2dpSink instances.
std::unique_ptr<A2dpSinkFactory> a2dp_sink_factory_;
+ // Factory used to create per-app A2dpSource instances.
+ std::unique_ptr<A2dpSourceFactory> a2dp_source_factory_;
+
// Factory used to create per-app AvrcpControl instances.
std::unique_ptr<AvrcpControlFactory> avrcp_control_factory_;
+ // Factory used to create per-app AvrcpTarget instances.
+ std::unique_ptr<AvrcpTargetFactory> avrcp_target_factory_;
+
// Factory used to create per-app LowEnergyClient instances.
std::unique_ptr<LowEnergyClientFactory> ble_client_factory_;
diff --git a/service/adapter.h b/service/adapter.h
index 032f1d9..edb8afe 100644
--- a/service/adapter.h
+++ b/service/adapter.h
@@ -28,7 +28,9 @@
namespace bluetooth {
class A2dpSinkFactory;
+class A2dpSourceFactory;
class AvrcpControlFactory;
+class AvrcpTargetFactory;
class GattClientFactory;
class GattServerFactory;
class LowEnergyAdvertiserFactory;
@@ -183,11 +185,21 @@
// operations.
virtual A2dpSinkFactory* GetA2dpSinkFactory() const = 0;
+ // Returns a pointer to the A2dpSourceFactory. This can be used to
+ // register per-application A2dpSourceClient instances to perform A2DP source
+ // operations.
+ virtual A2dpSourceFactory* GetA2dpSourceFactory() const = 0;
+
// Returns a pointer to the AvrcpControlFactory. This can be used to register
// per-application AvrcpControlClient instances to perform AVRCP control
// operations.
virtual AvrcpControlFactory* GetAvrcpControlFactory() const = 0;
+ // Returns a pointer to the AvrcpTargetFactory. This can be used to register
+ // per-application AvrcpTargetClient instances to perform AVRCP target
+ // operations.
+ virtual AvrcpTargetFactory* GetAvrcpTargetFactory() const = 0;
+
// Returns a pointer to the LowEnergyClientFactory. This can be used to
// register per-application LowEnergyClient instances to perform BLE GAP
// operations.
diff --git a/service/avrcp_target.cc b/service/avrcp_target.cc
new file mode 100644
index 0000000..f502774
--- /dev/null
+++ b/service/avrcp_target.cc
@@ -0,0 +1,382 @@
+//
+// 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.
+//
+
+#include "service/avrcp_target.h"
+
+#include <algorithm>
+#include <cerrno>
+#include <climits>
+#include <string>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "service/logging_helpers.h"
+
+#include "stack/include/avrc_defs.h"
+
+#define PARSE_ADDR(str) \
+ ({ \
+ RawAddress tmp; \
+ if (!RawAddress::FromString((str), tmp)) { \
+ LOG(ERROR) << "Invalid device address given: " << (str); \
+ return false; \
+ } \
+ tmp; \
+ })
+
+#define TRY_RET(expr, err_msg) \
+ do { \
+ if (!(expr)) { \
+ LOG(ERROR) << err_msg; \
+ return false; \
+ } \
+ return true; \
+ } while (0)
+
+#define TRY_RET_FUNC(expr) TRY_RET(expr, __func__ << " failed")
+
+using android::String8;
+using LockGuard = std::lock_guard<std::mutex>;
+
+namespace bluetooth {
+
+namespace {
+
+std::vector<btrc_player_setting_text_t> StringValueToPlayerSettingsText(
+ const std::vector<AvrcpStringValue>& attrs) {
+ std::vector<btrc_player_setting_text_t> btrc_attrs(attrs.size());
+ for (size_t i = 0; i < attrs.size(); ++i) {
+ btrc_attrs[i].id = attrs[i].id();
+ String8 str(attrs[i].value());
+ size_t to_copy = std::min(sizeof(btrc_attrs[i].text) - 1, str.bytes());
+ if (to_copy < str.bytes()) {
+ LOG(WARNING) << "Value truncated";
+ }
+
+ memcpy(btrc_attrs[i].text, str.string(), to_copy);
+ btrc_attrs[i].text[to_copy] = '\0';
+ }
+
+ return btrc_attrs;
+}
+
+std::vector<btrc_element_attr_val_t> StringValueToElementAttrVal(
+ const std::vector<AvrcpStringValue>& attrs) {
+ std::vector<btrc_element_attr_val_t> btrc_attrs(attrs.size());
+ for (size_t i = 0; i < attrs.size(); ++i) {
+ btrc_attrs[i].attr_id = attrs[i].id();
+ String8 str(attrs[i].value());
+ size_t to_copy = std::min(sizeof(btrc_attrs[i].text) - 1, str.bytes());
+ if (to_copy < str.bytes()) {
+ LOG(WARNING) << "Value truncated";
+ }
+
+ memcpy(btrc_attrs[i].text, str.string(), to_copy);
+ btrc_attrs[i].text[to_copy] = '\0';
+ }
+
+ return btrc_attrs;
+}
+
+} // namespace
+
+// static
+const int AvrcpTarget::kSingletonInstanceId = 0;
+
+AvrcpTarget::AvrcpTarget(const Uuid& uuid) : app_identifier_(uuid) {
+ hal::BluetoothAvrcpInterface::Get()->AddTargetObserver(this);
+}
+
+AvrcpTarget::~AvrcpTarget() {
+ hal::BluetoothAvrcpInterface::Get()->RemoveTargetObserver(this);
+}
+
+const Uuid& AvrcpTarget::GetAppIdentifier() const { return app_identifier_; }
+
+int AvrcpTarget::GetInstanceId() const { return kSingletonInstanceId; }
+
+void AvrcpTarget::SetDelegate(Delegate* delegate) {
+ LockGuard lock(delegate_mutex_);
+ delegate_ = delegate;
+}
+
+bool AvrcpTarget::Enable() {
+ LockGuard lock(mutex_);
+ return hal::BluetoothAvrcpInterface::Get()->AvrcpTargetEnable();
+}
+
+void AvrcpTarget::Disable() {
+ LockGuard lock(mutex_);
+ hal::BluetoothAvrcpInterface::Get()->AvrcpTargetDisable();
+}
+
+bool AvrcpTarget::GetPlayStatusResponse(const std::string& str_addr,
+ int32_t play_status, uint32_t song_len,
+ uint32_t song_pos) {
+ RawAddress addr = PARSE_ADDR(str_addr);
+ LockGuard lock(mutex_);
+ TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
+ ->GetTargetHALInterface()
+ ->get_play_status_rsp(
+ addr, static_cast<btrc_play_status_t>(play_status),
+ song_len, song_pos) == BT_STATUS_SUCCESS);
+}
+
+bool AvrcpTarget::ListPlayerAppAttrResponse(const std::string& str_addr,
+ const std::vector<int32_t>& attrs) {
+ RawAddress addr = PARSE_ADDR(str_addr);
+
+ std::vector<btrc_player_attr_t> btrc_attrs;
+ btrc_attrs.reserve(attrs.size());
+ for (auto attr : attrs) {
+ btrc_attrs.push_back(static_cast<btrc_player_attr_t>(attr));
+ }
+
+ LockGuard lock(mutex_);
+ TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
+ ->GetTargetHALInterface()
+ ->list_player_app_attr_rsp(addr, btrc_attrs.size(),
+ btrc_attrs.data()) ==
+ BT_STATUS_SUCCESS);
+}
+
+bool AvrcpTarget::GetPlayerAppValueResponse(
+ const std::string& str_addr, const std::vector<AvrcpIntValue>& values) {
+ RawAddress addr = PARSE_ADDR(str_addr);
+ btrc_player_settings_t btrc_values;
+ if (values.size() >= arraysize(btrc_values.attr_ids)) {
+ LOG(ERROR) << "Too many attribute values";
+ return false;
+ }
+
+ btrc_values.num_attr = values.size();
+ for (size_t i = 0; i < values.size(); ++i) {
+ btrc_values.attr_ids[i] = values[i].id();
+ btrc_values.attr_values[i] = values[i].value();
+ }
+
+ LockGuard lock(mutex_);
+ TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
+ ->GetTargetHALInterface()
+ ->get_player_app_value_rsp(addr, &btrc_values) ==
+ BT_STATUS_SUCCESS);
+}
+
+bool AvrcpTarget::GetPlayerAppAttrTextResponse(
+ const std::string& str_addr, const std::vector<AvrcpStringValue>& attrs) {
+ RawAddress addr = PARSE_ADDR(str_addr);
+ auto btrc_attrs = StringValueToPlayerSettingsText(attrs);
+ LockGuard lock(mutex_);
+ TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
+ ->GetTargetHALInterface()
+ ->get_player_app_attr_text_rsp(addr, btrc_attrs.size(),
+ btrc_attrs.data()) ==
+ BT_STATUS_SUCCESS);
+}
+
+bool AvrcpTarget::GetPlayerAppValueTextResponse(
+ const std::string& str_addr, const std::vector<AvrcpStringValue>& values) {
+ RawAddress addr = PARSE_ADDR(str_addr);
+ auto btrc_values = StringValueToPlayerSettingsText(values);
+ LockGuard lock(mutex_);
+ TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
+ ->GetTargetHALInterface()
+ ->get_player_app_value_text_rsp(addr, btrc_values.size(),
+ btrc_values.data()) ==
+ BT_STATUS_SUCCESS);
+}
+
+bool AvrcpTarget::GetElementAttrResponse(
+ const std::string& str_addr, const std::vector<AvrcpStringValue>& attrs) {
+ RawAddress addr = PARSE_ADDR(str_addr);
+ auto btrc_attrs = StringValueToElementAttrVal(attrs);
+ LockGuard lock(mutex_);
+ TRY_RET_FUNC(
+ hal::BluetoothAvrcpInterface::Get()
+ ->GetTargetHALInterface()
+ ->get_element_attr_rsp(addr, btrc_attrs.size(), btrc_attrs.data()) ==
+ BT_STATUS_SUCCESS);
+}
+
+bool AvrcpTarget::SetPlayerAppValueResponse(const std::string& str_addr,
+ int32_t rsp_status) {
+ RawAddress addr = PARSE_ADDR(str_addr);
+ LockGuard lock(mutex_);
+ TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
+ ->GetTargetHALInterface()
+ ->set_player_app_value_rsp(
+ addr, static_cast<btrc_status_t>(rsp_status)) ==
+ BT_STATUS_SUCCESS);
+}
+
+bool AvrcpTarget::RegisterNotificationResponse(
+ int32_t event_id, int32_t type,
+ const AvrcpRegisterNotificationResponse& param) {
+ auto param_copy = param.data();
+ LockGuard lock(mutex_);
+ TRY_RET_FUNC(hal::BluetoothAvrcpInterface::Get()
+ ->GetTargetHALInterface()
+ ->register_notification_rsp(
+ static_cast<btrc_event_id_t>(event_id),
+ static_cast<btrc_notification_type_t>(type),
+ ¶m_copy) == BT_STATUS_SUCCESS);
+}
+
+bool AvrcpTarget::SetVolume(int volume) {
+ LockGuard lock(mutex_);
+ TRY_RET_FUNC(
+ hal::BluetoothAvrcpInterface::Get()->GetTargetHALInterface()->set_volume(
+ volume) == BT_STATUS_SUCCESS);
+}
+
+void AvrcpTarget::RemoteFeaturesCallback(const RawAddress& bd_addr,
+ btrc_remote_features_t features) {
+ auto str_addr = BtAddrString(&bd_addr);
+ LockGuard lock(delegate_mutex_);
+ if (delegate_)
+ delegate_->OnGetRemoteFeatures(str_addr, static_cast<int32_t>(features));
+}
+
+void AvrcpTarget::GetPlayStatusCallback(const RawAddress& bd_addr) {
+ auto str_addr = BtAddrString(&bd_addr);
+ LockGuard lock(delegate_mutex_);
+ if (delegate_) delegate_->OnGetPlayStatus(str_addr);
+}
+
+void AvrcpTarget::ListPlayerAppAttrCallback(const RawAddress& bd_addr) {
+ auto str_addr = BtAddrString(&bd_addr);
+ LockGuard lock(delegate_mutex_);
+ if (delegate_) delegate_->OnListPlayerAppAttr(str_addr);
+}
+
+void AvrcpTarget::ListPlayerAppValuesCallback(btrc_player_attr_t attr_id,
+ const RawAddress& bd_addr) {
+ auto str_addr = BtAddrString(&bd_addr);
+ LockGuard lock(delegate_mutex_);
+ if (delegate_)
+ delegate_->OnListPlayerAppValues(str_addr, static_cast<int32_t>(attr_id));
+}
+
+void AvrcpTarget::GetPlayerAppValueCallback(uint8_t num_attr,
+ btrc_player_attr_t* p_attrs,
+ const RawAddress& bd_addr) {
+ auto str_addr = BtAddrString(&bd_addr);
+ std::vector<int32_t> attr_vec;
+ attr_vec.reserve(num_attr);
+ for (auto* it = p_attrs; it != p_attrs + num_attr; ++it) {
+ attr_vec.push_back(*it);
+ }
+
+ LockGuard lock(delegate_mutex_);
+ if (delegate_) delegate_->OnGetPlayerAppValue(str_addr, attr_vec);
+}
+
+void AvrcpTarget::GetPlayerAppAttrsTextCallback(uint8_t num_attr,
+ btrc_player_attr_t* p_attrs,
+ const RawAddress& bd_addr) {
+ auto str_addr = BtAddrString(&bd_addr);
+ std::vector<int32_t> attr_vec;
+ attr_vec.reserve(num_attr);
+ for (auto* it = p_attrs; it != p_attrs + num_attr; ++it) {
+ attr_vec.push_back(*it);
+ }
+
+ LockGuard lock(delegate_mutex_);
+ if (delegate_) delegate_->OnGetPlayerAppAttrsText(str_addr, attr_vec);
+}
+
+void AvrcpTarget::GetPlayerAppValuesTextCallback(uint8_t attr_id,
+ uint8_t num_val,
+ uint8_t* p_vals,
+ const RawAddress& bd_addr) {
+ auto str_addr = BtAddrString(&bd_addr);
+ std::vector<int32_t> val_vec;
+ val_vec.reserve(num_val);
+ for (auto* it = p_vals; it != p_vals + num_val; ++it) {
+ val_vec.push_back(*it);
+ }
+ LockGuard lock(delegate_mutex_);
+ if (delegate_)
+ delegate_->OnGetPlayerAppValuesText(str_addr, attr_id, val_vec);
+}
+
+void AvrcpTarget::SetPlayerAppValueCallback(btrc_player_settings_t* p_vals,
+ const RawAddress& bd_addr) {
+ auto str_addr = BtAddrString(&bd_addr);
+ std::vector<AvrcpIntValue> values;
+ values.reserve(p_vals->num_attr);
+ for (size_t i = 0; i < p_vals->num_attr; ++i) {
+ values.emplace_back(p_vals->attr_ids[i], p_vals->attr_values[i]);
+ }
+
+ LockGuard lock(delegate_mutex_);
+ if (delegate_) delegate_->OnSetPlayerAppValue(str_addr, values);
+}
+
+void AvrcpTarget::GetElementAttrCallback(uint8_t num_attr,
+ btrc_media_attr_t* p_attrs,
+ const RawAddress& bd_addr) {
+ auto str_addr = BtAddrString(&bd_addr);
+ std::vector<int32_t> attr_vec;
+ attr_vec.reserve(num_attr);
+ for (auto* it = p_attrs; it != p_attrs + num_attr; ++it) {
+ attr_vec.push_back(*it);
+ }
+ LockGuard lock(delegate_mutex_);
+ if (delegate_) delegate_->OnGetElementAttrs(str_addr, attr_vec);
+}
+
+void AvrcpTarget::RegisterNotificationCallback(btrc_event_id_t event_id,
+ uint32_t param,
+ const RawAddress& bd_addr) {
+ auto str_addr = BtAddrString(&bd_addr);
+ LockGuard lock(delegate_mutex_);
+ if (delegate_)
+ delegate_->OnRegisterNotification(str_addr, static_cast<int32_t>(event_id),
+ param);
+}
+
+void AvrcpTarget::VolumeChangeCallback(uint8_t volume, uint8_t ctype,
+ const RawAddress& bd_addr) {
+ auto str_addr = BtAddrString(&bd_addr);
+ LockGuard lock(delegate_mutex_);
+ if (delegate_) delegate_->OnVolumeChange(str_addr, volume, ctype);
+}
+
+void AvrcpTarget::PassthroughCmdCallback(int id, int key_state,
+ const RawAddress& bd_addr) {
+ auto str_addr = BtAddrString(&bd_addr);
+ LockGuard lock(delegate_mutex_);
+ if (delegate_) delegate_->OnPassThroughCommand(str_addr, id, key_state);
+}
+
+// AvrcpTargetFactory implementation
+// ========================================================
+
+AvrcpTargetFactory::AvrcpTargetFactory() = default;
+AvrcpTargetFactory::~AvrcpTargetFactory() = default;
+
+bool AvrcpTargetFactory::RegisterInstance(const Uuid& uuid,
+ const RegisterCallback& callback) {
+ VLOG(1) << __func__ << " - UUID: " << uuid.ToString();
+
+ auto avrcp_target = base::WrapUnique(new AvrcpTarget(uuid));
+ callback(BLE_STATUS_SUCCESS, uuid, std::move(avrcp_target));
+ return true;
+}
+
+} // namespace bluetooth
diff --git a/service/avrcp_target.h b/service/avrcp_target.h
new file mode 100644
index 0000000..8c2bcce
--- /dev/null
+++ b/service/avrcp_target.h
@@ -0,0 +1,179 @@
+//
+// 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 <mutex>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+
+#include "service/common/bluetooth/avrcp_int_value.h"
+#include "service/common/bluetooth/avrcp_register_notification_response.h"
+#include "service/common/bluetooth/avrcp_string_value.h"
+
+#include "service/bluetooth_instance.h"
+#include "service/hal/bluetooth_avrcp_interface.h"
+
+namespace bluetooth {
+
+// Note: presently this only supports
+// (BTRC_FEAT_METADATA | BTRC_FEAT_ABSOLUTE_VOLUME)
+class AvrcpTarget : public BluetoothInstance,
+ private hal::BluetoothAvrcpInterface::TargetObserver {
+ public:
+ // We only allow one instance of this object at a time.
+ static const int kSingletonInstanceId;
+
+ class Delegate {
+ public:
+ virtual void OnGetRemoteFeatures(const std::string& addr,
+ int32_t features) = 0;
+ virtual void OnGetPlayStatus(const std::string& addr) = 0;
+ virtual void OnListPlayerAppAttr(const std::string& addr) = 0;
+ virtual void OnListPlayerAppValues(const std::string& addr,
+ int32_t attr_id) = 0;
+ virtual void OnGetPlayerAppValue(const std::string& addr,
+ const std::vector<int32_t>& attrs) = 0;
+ virtual void OnGetPlayerAppAttrsText(const std::string& addr,
+ const std::vector<int32_t>& attrs) = 0;
+ virtual void OnGetPlayerAppValuesText(
+ const std::string& addr, int32_t attr_id,
+ const std::vector<int32_t>& values) = 0;
+ virtual void OnSetPlayerAppValue(
+ const std::string& addr, const std::vector<AvrcpIntValue>& values) = 0;
+ virtual void OnGetElementAttrs(const std::string& addr,
+ const std::vector<int32_t>& attrs) = 0;
+ virtual void OnRegisterNotification(const std::string& addr,
+ int32_t event_id, uint32_t param) = 0;
+ virtual void OnVolumeChange(const std::string& addr, int32_t volume,
+ int32_t ctype) = 0;
+ virtual void OnPassThroughCommand(const std::string& addr, int32_t id,
+ int32_t key_state) = 0;
+
+ protected:
+ virtual ~Delegate() = default;
+ };
+
+ // The destructor automatically unregisters this instance from the stack.
+ ~AvrcpTarget() override;
+
+ // Assigns a delegate to this instance. |delegate| must out-live this
+ // AvrcpTarget instance.
+ void SetDelegate(Delegate* delegate);
+
+ // BluetoothClientInstace overrides:
+ const Uuid& GetAppIdentifier() const override;
+ int GetInstanceId() const override;
+
+ bool Enable();
+ void Disable();
+
+ bool GetPlayStatusResponse(const std::string& addr, int32_t play_status,
+ uint32_t song_len, uint32_t song_pos);
+
+ bool ListPlayerAppAttrResponse(const std::string& addr,
+ const std::vector<int32_t>& attrs);
+
+ bool GetPlayerAppValueResponse(const std::string& addr,
+ const std::vector<AvrcpIntValue>& values);
+
+ bool GetPlayerAppAttrTextResponse(const std::string& addr,
+ const std::vector<AvrcpStringValue>& attrs);
+
+ bool GetPlayerAppValueTextResponse(
+ const std::string& addr, const std::vector<AvrcpStringValue>& attrs);
+
+ bool GetElementAttrResponse(const std::string& addr,
+ const std::vector<AvrcpStringValue>& attrs);
+
+ bool SetPlayerAppValueResponse(const std::string& addr, int32_t rsp_status);
+
+ bool RegisterNotificationResponse(
+ int32_t event_id, int32_t type,
+ const AvrcpRegisterNotificationResponse& param);
+
+ bool SetVolume(int volume);
+
+ private:
+ friend class AvrcpTargetFactory;
+
+ // Constructor shouldn't be called directly as instances are meant to be
+ // obtained from the factory.
+ AvrcpTarget(const Uuid& uuid);
+
+ // hal::BluetoothAvrcpInterface::TargetObserver implementation:
+ void RemoteFeaturesCallback(const RawAddress& bd_addr,
+ btrc_remote_features_t features) override;
+ void GetPlayStatusCallback(const RawAddress& bd_addr) override;
+ void ListPlayerAppAttrCallback(const RawAddress& bd_addr) override;
+ void ListPlayerAppValuesCallback(btrc_player_attr_t attr_id,
+ const RawAddress& bd_addr) override;
+ void GetPlayerAppValueCallback(uint8_t num_attr, btrc_player_attr_t* p_attrs,
+ const RawAddress& bd_addr) override;
+ void GetPlayerAppAttrsTextCallback(uint8_t num_attr,
+ btrc_player_attr_t* p_attrs,
+ const RawAddress& bd_addr) override;
+ void GetPlayerAppValuesTextCallback(uint8_t attr_id, uint8_t num_val,
+ uint8_t* p_vals,
+ const RawAddress& bd_addr) override;
+ void SetPlayerAppValueCallback(btrc_player_settings_t* p_vals,
+ const RawAddress& bd_addr) override;
+ void GetElementAttrCallback(uint8_t num_attr, btrc_media_attr_t* p_attrs,
+ const RawAddress& bd_addr) override;
+ void RegisterNotificationCallback(btrc_event_id_t event_id, uint32_t param,
+ const RawAddress& bd_addr) override;
+ void VolumeChangeCallback(uint8_t volume, uint8_t ctype,
+ const RawAddress& bd_addr) override;
+ void PassthroughCmdCallback(int id, int key_state,
+ const RawAddress& bd_addr) override;
+
+ // See getters for documentation.
+ const Uuid app_identifier_;
+
+ // Mutex that synchronizes access to the entries below.
+ std::mutex mutex_;
+
+ // Raw handle to the Delegate, which must outlive this AvrcpTarget instance.
+ std::mutex delegate_mutex_;
+ Delegate* delegate_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(AvrcpTarget);
+};
+
+// AvrcpTargetFactory is used to register and obtain a per-application
+// AvrcpTarget
+// instance. Users should call RegisterClient to obtain their own unique
+// AvrcpTarget instance that has been registered with the Bluetooth stack.
+class AvrcpTargetFactory
+ : public BluetoothInstanceFactory,
+ private hal::BluetoothAvrcpInterface::TargetObserver {
+ public:
+ // Don't construct/destruct directly except in tests. Instead, obtain a handle
+ // from an Adapter instance.
+ AvrcpTargetFactory();
+ ~AvrcpTargetFactory() override;
+
+ // BluetoothInstanceFactory override:
+ bool RegisterInstance(const Uuid& uuid,
+ const RegisterCallback& callback) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AvrcpTargetFactory);
+};
+
+} // namespace bluetooth
diff --git a/service/common/Android.bp b/service/common/Android.bp
index b481d19..ef08b21 100644
--- a/service/common/Android.bp
+++ b/service/common/Android.bp
@@ -9,10 +9,14 @@
host_supported: true,
header_libs: [ "libbluetooth_headers" ],
srcs: [
+ "bluetooth/a2dp_codec_config.cc",
"bluetooth/adapter_state.cc",
"bluetooth/advertise_data.cc",
"bluetooth/advertise_settings.cc",
+ "bluetooth/avrcp_int_value.cc",
"bluetooth/avrcp_media_attr.cc",
+ "bluetooth/avrcp_register_notification_response.cc",
+ "bluetooth/avrcp_string_value.cc",
"bluetooth/characteristic.cc",
"bluetooth/descriptor.cc",
"bluetooth/remote_device_props.cc",
@@ -42,8 +46,12 @@
"android/bluetooth/IBluetooth.aidl",
"android/bluetooth/IBluetoothA2dpSink.aidl",
"android/bluetooth/IBluetoothA2dpSinkCallback.aidl",
+ "android/bluetooth/IBluetoothA2dpSource.aidl",
+ "android/bluetooth/IBluetoothA2dpSourceCallback.aidl",
"android/bluetooth/IBluetoothAvrcpControl.aidl",
"android/bluetooth/IBluetoothAvrcpControlCallback.aidl",
+ "android/bluetooth/IBluetoothAvrcpTarget.aidl",
+ "android/bluetooth/IBluetoothAvrcpTargetCallback.aidl",
"android/bluetooth/IBluetoothCallback.aidl",
"android/bluetooth/IBluetoothGattClient.aidl",
"android/bluetooth/IBluetoothGattClientCallback.aidl",
@@ -57,7 +65,11 @@
"android/bluetooth/IBluetoothLowEnergyCallback.aidl",
"android/bluetooth/advertise_data.cc",
"android/bluetooth/advertise_settings.cc",
+ "android/bluetooth/bluetooth_a2dp_codec_config.cc",
+ "android/bluetooth/bluetooth_avrcp_int_value.cc",
"android/bluetooth/bluetooth_avrcp_media_attr.cc",
+ "android/bluetooth/bluetooth_avrcp_register_notification_response.cc",
+ "android/bluetooth/bluetooth_avrcp_string_value.cc",
"android/bluetooth/bluetooth_gatt_characteristic.cc",
"android/bluetooth/bluetooth_gatt_descriptor.cc",
"android/bluetooth/bluetooth_gatt_included_service.cc",
diff --git a/service/common/android/bluetooth/BluetoothA2dpCodecConfig.aidl b/service/common/android/bluetooth/BluetoothA2dpCodecConfig.aidl
new file mode 100644
index 0000000..083cd75
--- /dev/null
+++ b/service/common/android/bluetooth/BluetoothA2dpCodecConfig.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.bluetooth;
+
+parcelable BluetoothA2dpCodecConfig cpp_header "android/bluetooth/bluetooth_a2dp_codec_config.h";
diff --git a/service/common/android/bluetooth/BluetoothAvrcpIntValue.aidl b/service/common/android/bluetooth/BluetoothAvrcpIntValue.aidl
new file mode 100644
index 0000000..e126393
--- /dev/null
+++ b/service/common/android/bluetooth/BluetoothAvrcpIntValue.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.bluetooth;
+
+parcelable BluetoothAvrcpIntValue cpp_header "android/bluetooth/bluetooth_avrcp_int_value.h";
diff --git a/service/common/android/bluetooth/BluetoothAvrcpRegisterNotificationResponse.aidl b/service/common/android/bluetooth/BluetoothAvrcpRegisterNotificationResponse.aidl
new file mode 100644
index 0000000..147a187
--- /dev/null
+++ b/service/common/android/bluetooth/BluetoothAvrcpRegisterNotificationResponse.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.bluetooth;
+
+parcelable BluetoothAvrcpRegisterNotificationResponse cpp_header "android/bluetooth/bluetooth_avrcp_register_notification_response.h";
diff --git a/service/common/android/bluetooth/BluetoothAvrcpStringValue.aidl b/service/common/android/bluetooth/BluetoothAvrcpStringValue.aidl
new file mode 100644
index 0000000..5bbfbd4
--- /dev/null
+++ b/service/common/android/bluetooth/BluetoothAvrcpStringValue.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.bluetooth;
+
+parcelable BluetoothAvrcpStringValue cpp_header "android/bluetooth/bluetooth_avrcp_string_value.h";
diff --git a/service/common/android/bluetooth/IBluetooth.aidl b/service/common/android/bluetooth/IBluetooth.aidl
index 9223afb..3986ad7 100644
--- a/service/common/android/bluetooth/IBluetooth.aidl
+++ b/service/common/android/bluetooth/IBluetooth.aidl
@@ -23,7 +23,9 @@
import android.bluetooth.IBluetoothGattClient;
import android.bluetooth.IBluetoothGattServer;
import android.bluetooth.IBluetoothA2dpSink;
+import android.bluetooth.IBluetoothA2dpSource;
import android.bluetooth.IBluetoothAvrcpControl;
+import android.bluetooth.IBluetoothAvrcpTarget;
import android.bluetooth.UUID;
@@ -61,5 +63,7 @@
IBluetoothGattClient GetGattClientInterface();
IBluetoothGattServer GetGattServerInterface();
IBluetoothA2dpSink GetA2dpSinkInterface();
+ IBluetoothA2dpSource GetA2dpSourceInterface();
IBluetoothAvrcpControl GetAvrcpControlInterface();
+ IBluetoothAvrcpTarget GetAvrcpTargetInterface();
}
diff --git a/service/common/android/bluetooth/IBluetoothA2dpSource.aidl b/service/common/android/bluetooth/IBluetoothA2dpSource.aidl
new file mode 100644
index 0000000..344292c
--- /dev/null
+++ b/service/common/android/bluetooth/IBluetoothA2dpSource.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.IBluetoothA2dpSourceCallback;
+import android.bluetooth.BluetoothA2dpCodecConfig;
+
+interface IBluetoothA2dpSource {
+ boolean Register(in IBluetoothA2dpSourceCallback callback);
+ void Unregister();
+
+ boolean Enable(in BluetoothA2dpCodecConfig[] codec_priorities);
+ boolean Disable();
+ boolean Connect(String device_address);
+ boolean Disconnect(String device_address);
+ boolean ConfigCodec(String device_address,
+ in BluetoothA2dpCodecConfig[] codec_preferences);
+
+}
diff --git a/service/common/android/bluetooth/IBluetoothA2dpSourceCallback.aidl b/service/common/android/bluetooth/IBluetoothA2dpSourceCallback.aidl
new file mode 100644
index 0000000..4d4a82d
--- /dev/null
+++ b/service/common/android/bluetooth/IBluetoothA2dpSourceCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.BluetoothA2dpCodecConfig;
+
+oneway interface IBluetoothA2dpSourceCallback {
+ void OnRegistered(int status);
+ void OnConnectionState(String device_address, int state);
+ void OnAudioState(String device_address, int state);
+ void OnAudioConfig(
+ String device_address,
+ in BluetoothA2dpCodecConfig codec_config,
+ in BluetoothA2dpCodecConfig[] codecs_local_capabilities,
+ in BluetoothA2dpCodecConfig[] codecs_selectable_capabilities);
+}
diff --git a/service/common/android/bluetooth/IBluetoothAvrcpTarget.aidl b/service/common/android/bluetooth/IBluetoothAvrcpTarget.aidl
new file mode 100644
index 0000000..6654f86
--- /dev/null
+++ b/service/common/android/bluetooth/IBluetoothAvrcpTarget.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.IBluetoothAvrcpTargetCallback;
+
+import android.bluetooth.BluetoothAvrcpIntValue;
+import android.bluetooth.BluetoothAvrcpStringValue;
+import android.bluetooth.BluetoothAvrcpRegisterNotificationResponse;
+
+interface IBluetoothAvrcpTarget {
+ boolean Register(in IBluetoothAvrcpTargetCallback callback);
+ void Unregister(int id);
+ void UnregisterAll();
+
+ boolean Enable();
+ boolean Disable();
+
+ boolean GetPlayStatusResponse(String addr,
+ int play_status, int song_len, int song_pos);
+
+ boolean ListPlayerAppAttrResponse(String addr, in int[] attrs);
+
+ boolean GetPlayerAppValueResponse(String addr,
+ in BluetoothAvrcpIntValue[] values);
+
+ boolean GetPlayerAppAttrTextResponse(String addr,
+ in BluetoothAvrcpStringValue[] attrs);
+
+ boolean GetPlayerAppValueTextResponse(String addr,
+ in BluetoothAvrcpStringValue[] values);
+
+ boolean GetElementAttrResponse(String addr,
+ in BluetoothAvrcpStringValue[] attrs);
+
+ boolean SetPlayerAppValueResponse(String addr, int rsp_status);
+
+ boolean RegisterNotificationResponse(
+ int event_id,
+ int type,
+ in BluetoothAvrcpRegisterNotificationResponse param);
+
+ boolean SetVolume(int volume);
+}
diff --git a/service/common/android/bluetooth/IBluetoothAvrcpTargetCallback.aidl b/service/common/android/bluetooth/IBluetoothAvrcpTargetCallback.aidl
new file mode 100644
index 0000000..15d45f3
--- /dev/null
+++ b/service/common/android/bluetooth/IBluetoothAvrcpTargetCallback.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.BluetoothAvrcpIntValue;
+
+oneway interface IBluetoothAvrcpTargetCallback {
+ void OnRegistered(int status);
+ void OnGetRemoteFeatures(String addr, int features);
+ void OnGetPlayStatus(String addr);
+ void OnListPlayerAppAttr(String addr);
+ void OnListPlayerAppValues(String addr, int attr_id);
+ void OnGetPlayerAppValue(String addr, in int[] attrs);
+ void OnGetPlayerAppAttrsText(String addr, in int[] attrs);
+ void OnGetPlayerAppValuesText(String addr, int attr_id, in int[] values);
+ void OnSetPlayerAppValue(String addr, in BluetoothAvrcpIntValue[] values);
+ void OnGetElementAttrs(String addr, in int[] attrs);
+ void OnRegisterNotification(String addr, int event_id, int param);
+ void OnVolumeChange(String addr, int volume, int ctype);
+ void OnPassThroughCommand(String addr, int id, int key_state);
+}
diff --git a/service/common/android/bluetooth/bluetooth_a2dp_codec_config.cc b/service/common/android/bluetooth/bluetooth_a2dp_codec_config.cc
new file mode 100644
index 0000000..8e7b709
--- /dev/null
+++ b/service/common/android/bluetooth/bluetooth_a2dp_codec_config.cc
@@ -0,0 +1,103 @@
+//
+// 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.
+//
+
+#include "android/bluetooth/bluetooth_a2dp_codec_config.h"
+
+#include <utils/String16.h>
+#include <utils/String8.h>
+
+using android::OK;
+using android::String16;
+using android::String8;
+
+namespace android {
+namespace bluetooth {
+
+status_t BluetoothA2dpCodecConfig::writeToParcel(Parcel* parcel) const {
+ status_t status = parcel->writeInt32(codec_type_);
+ if (status != OK) return status;
+
+ status = parcel->writeInt32(codec_priority_);
+ if (status != OK) return status;
+
+ status = parcel->writeInt32(sample_rate_);
+ if (status != OK) return status;
+
+ status = parcel->writeInt32(bits_per_sample_);
+ if (status != OK) return status;
+
+ status = parcel->writeInt32(channel_mode_);
+ if (status != OK) return status;
+
+ status = parcel->writeInt64(codec_specific_1_);
+ if (status != OK) return status;
+
+ status = parcel->writeInt64(codec_specific_2_);
+ if (status != OK) return status;
+
+ status = parcel->writeInt64(codec_specific_3_);
+ if (status != OK) return status;
+
+ status = parcel->writeInt64(codec_specific_4_);
+ if (status != OK) return status;
+
+ return status;
+}
+
+status_t BluetoothA2dpCodecConfig::readFromParcel(const Parcel* parcel) {
+ int32_t tmp;
+ status_t status = parcel->readInt32(&tmp);
+ if (status != OK) return status;
+ codec_type_ = tmp;
+
+ status = parcel->readInt32(&tmp);
+ if (status != OK) return status;
+ codec_priority_ = tmp;
+
+ status = parcel->readInt32(&tmp);
+ if (status != OK) return status;
+ sample_rate_ = tmp;
+
+ status = parcel->readInt32(&tmp);
+ if (status != OK) return status;
+ bits_per_sample_ = tmp;
+
+ status = parcel->readInt32(&tmp);
+ if (status != OK) return status;
+ channel_mode_ = tmp;
+
+ int64_t tmp64;
+ status = parcel->readInt64(&tmp64);
+ if (status != OK) return status;
+ codec_specific_1_ = tmp64;
+
+ status = parcel->readInt64(&tmp64);
+ if (status != OK) return status;
+ codec_specific_2_ = tmp64;
+
+ status = parcel->readInt64(&tmp64);
+ if (status != OK) return status;
+ codec_specific_3_ = tmp64;
+
+ status = parcel->readInt64(&tmp64);
+ if (status != OK) return status;
+ codec_specific_4_ = tmp64;
+
+ return status;
+}
+
+} // namespace bluetooth
+} // namespace android
diff --git a/service/common/android/bluetooth/bluetooth_a2dp_codec_config.h b/service/common/android/bluetooth/bluetooth_a2dp_codec_config.h
new file mode 100644
index 0000000..0071d67
--- /dev/null
+++ b/service/common/android/bluetooth/bluetooth_a2dp_codec_config.h
@@ -0,0 +1,57 @@
+//
+// 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 <binder/Parcel.h>
+#include <binder/Parcelable.h>
+
+#include "bluetooth/a2dp_codec_config.h"
+
+using android::Parcel;
+using android::Parcelable;
+using android::status_t;
+
+namespace android {
+namespace bluetooth {
+
+class BluetoothA2dpCodecConfig : public Parcelable,
+ public ::bluetooth::A2dpCodecConfig {
+ public:
+ BluetoothA2dpCodecConfig() = default;
+ BluetoothA2dpCodecConfig(const ::bluetooth::A2dpCodecConfig& other)
+ : ::bluetooth::A2dpCodecConfig(other) {} // NOLINT(implicit)
+ BluetoothA2dpCodecConfig(const BluetoothA2dpCodecConfig& other)
+ : ::bluetooth::A2dpCodecConfig(other) {} // NOLINT(implicit)
+ ~BluetoothA2dpCodecConfig() = default;
+
+ // Write |this| parcelable to the given |parcel|. Keep in mind that
+ // implementations of writeToParcel must be manually kept in sync
+ // with readFromParcel and the Java equivalent versions of these methods.
+ //
+ // Returns android::OK on success and an appropriate error otherwise.
+ status_t writeToParcel(Parcel* parcel) const override;
+
+ // Read data from the given |parcel| into |this|. After readFromParcel
+ // completes, |this| should have equivalent state to the object that
+ // wrote itself to the parcel.
+ //
+ // Returns android::OK on success and an appropriate error otherwise.
+ status_t readFromParcel(const Parcel* parcel) override;
+};
+
+} // namespace bluetooth
+} // namespace android
diff --git a/service/common/android/bluetooth/bluetooth_avrcp_int_value.cc b/service/common/android/bluetooth/bluetooth_avrcp_int_value.cc
new file mode 100644
index 0000000..c2a895c
--- /dev/null
+++ b/service/common/android/bluetooth/bluetooth_avrcp_int_value.cc
@@ -0,0 +1,53 @@
+//
+// 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.
+//
+
+#include "android/bluetooth/bluetooth_avrcp_int_value.h"
+
+#include <utils/String16.h>
+#include <utils/String8.h>
+
+using android::OK;
+using android::String16;
+using android::String8;
+
+namespace android {
+namespace bluetooth {
+
+status_t BluetoothAvrcpIntValue::writeToParcel(Parcel* parcel) const {
+ status_t status = parcel->writeInt32(id_);
+ if (status != OK) return status;
+
+ status = parcel->writeInt32(value_);
+ if (status != OK) return status;
+
+ return status;
+}
+
+status_t BluetoothAvrcpIntValue::readFromParcel(const Parcel* parcel) {
+ int32_t tmp;
+ status_t status = parcel->readInt32(&tmp);
+ if (status != OK) return status;
+ id_ = tmp;
+
+ status = parcel->readInt32(&tmp);
+ if (status != OK) return status;
+ value_ = tmp;
+
+ return status;
+}
+
+} // namespace bluetooth
+} // namespace android
diff --git a/service/common/android/bluetooth/bluetooth_avrcp_int_value.h b/service/common/android/bluetooth/bluetooth_avrcp_int_value.h
new file mode 100644
index 0000000..80eed7c
--- /dev/null
+++ b/service/common/android/bluetooth/bluetooth_avrcp_int_value.h
@@ -0,0 +1,57 @@
+//
+// 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 <binder/Parcel.h>
+#include <binder/Parcelable.h>
+
+#include "bluetooth/avrcp_int_value.h"
+
+using android::Parcel;
+using android::Parcelable;
+using android::status_t;
+
+namespace android {
+namespace bluetooth {
+
+class BluetoothAvrcpIntValue : public Parcelable,
+ public ::bluetooth::AvrcpIntValue {
+ public:
+ BluetoothAvrcpIntValue() = default;
+ BluetoothAvrcpIntValue(const ::bluetooth::AvrcpIntValue& other)
+ : ::bluetooth::AvrcpIntValue(other) {} // NOLINT(implicit)
+ BluetoothAvrcpIntValue(const BluetoothAvrcpIntValue& other)
+ : ::bluetooth::AvrcpIntValue(other) {} // NOLINT(implicit)
+ ~BluetoothAvrcpIntValue() = default;
+
+ // Write |this| parcelable to the given |parcel|. Keep in mind that
+ // implementations of writeToParcel must be manually kept in sync
+ // with readFromParcel and the Java equivalent versions of these methods.
+ //
+ // Returns android::OK on success and an appropriate error otherwise.
+ status_t writeToParcel(Parcel* parcel) const override;
+
+ // Read data from the given |parcel| into |this|. After readFromParcel
+ // completes, |this| should have equivalent state to the object that
+ // wrote itself to the parcel.
+ //
+ // Returns android::OK on success and an appropriate error otherwise.
+ status_t readFromParcel(const Parcel* parcel) override;
+};
+
+} // namespace bluetooth
+} // namespace android
diff --git a/service/common/android/bluetooth/bluetooth_avrcp_register_notification_response.cc b/service/common/android/bluetooth/bluetooth_avrcp_register_notification_response.cc
new file mode 100644
index 0000000..2ff5a17
--- /dev/null
+++ b/service/common/android/bluetooth/bluetooth_avrcp_register_notification_response.cc
@@ -0,0 +1,46 @@
+//
+// 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.
+//
+
+#include "android/bluetooth/bluetooth_avrcp_register_notification_response.h"
+
+#include <utils/String16.h>
+#include <utils/String8.h>
+
+using android::OK;
+using android::String16;
+using android::String8;
+
+namespace android {
+namespace bluetooth {
+
+status_t BluetoothAvrcpRegisterNotificationResponse::writeToParcel(
+ Parcel* parcel) const {
+ status_t status = parcel->write(&data_, sizeof(data_));
+ if (status != OK) return status;
+
+ return status;
+}
+
+status_t BluetoothAvrcpRegisterNotificationResponse::readFromParcel(
+ const Parcel* parcel) {
+ status_t status = parcel->read(&data_, sizeof(data_));
+ if (status != OK) return status;
+
+ return status;
+}
+
+} // namespace bluetooth
+} // namespace android
diff --git a/service/common/android/bluetooth/bluetooth_avrcp_register_notification_response.h b/service/common/android/bluetooth/bluetooth_avrcp_register_notification_response.h
new file mode 100644
index 0000000..0a34d1e
--- /dev/null
+++ b/service/common/android/bluetooth/bluetooth_avrcp_register_notification_response.h
@@ -0,0 +1,60 @@
+//
+// 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 <binder/Parcel.h>
+#include <binder/Parcelable.h>
+
+#include "bluetooth/avrcp_register_notification_response.h"
+
+using android::Parcel;
+using android::Parcelable;
+using android::status_t;
+
+namespace android {
+namespace bluetooth {
+
+class BluetoothAvrcpRegisterNotificationResponse
+ : public Parcelable,
+ public ::bluetooth::AvrcpRegisterNotificationResponse {
+ public:
+ BluetoothAvrcpRegisterNotificationResponse() = default;
+ BluetoothAvrcpRegisterNotificationResponse(
+ const AvrcpRegisterNotificationResponse& other)
+ : ::bluetooth::AvrcpRegisterNotificationResponse(other) {}
+ BluetoothAvrcpRegisterNotificationResponse(
+ const BluetoothAvrcpRegisterNotificationResponse& other)
+ : ::bluetooth::AvrcpRegisterNotificationResponse(other) {}
+ ~BluetoothAvrcpRegisterNotificationResponse() = default;
+
+ // Write |this| parcelable to the given |parcel|. Keep in mind that
+ // implementations of writeToParcel must be manually kept in sync
+ // with readFromParcel and the Java equivalent versions of these methods.
+ //
+ // Returns android::OK on success and an appropriate error otherwise.
+ status_t writeToParcel(Parcel* parcel) const override;
+
+ // Read data from the given |parcel| into |this|. After readFromParcel
+ // completes, |this| should have equivalent state to the object that
+ // wrote itself to the parcel.
+ //
+ // Returns android::OK on success and an appropriate error otherwise.
+ status_t readFromParcel(const Parcel* parcel) override;
+};
+
+} // namespace bluetooth
+} // namespace android
diff --git a/service/common/android/bluetooth/bluetooth_avrcp_string_value.cc b/service/common/android/bluetooth/bluetooth_avrcp_string_value.cc
new file mode 100644
index 0000000..72ed179
--- /dev/null
+++ b/service/common/android/bluetooth/bluetooth_avrcp_string_value.cc
@@ -0,0 +1,52 @@
+//
+// 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.
+//
+
+#include "android/bluetooth/bluetooth_avrcp_string_value.h"
+
+#include <utils/String16.h>
+#include <utils/String8.h>
+
+using android::OK;
+using android::String16;
+using android::String8;
+
+namespace android {
+namespace bluetooth {
+
+status_t BluetoothAvrcpStringValue::writeToParcel(Parcel* parcel) const {
+ status_t status = parcel->writeInt32(id_);
+ if (status != OK) return status;
+
+ status = parcel->writeString16(value_);
+ if (status != OK) return status;
+
+ return status;
+}
+
+status_t BluetoothAvrcpStringValue::readFromParcel(const Parcel* parcel) {
+ int32_t tmp;
+ status_t status = parcel->readInt32(&tmp);
+ if (status != OK) return status;
+ id_ = tmp;
+
+ status = parcel->readString16(&value_);
+ if (status != OK) return status;
+
+ return status;
+}
+
+} // namespace bluetooth
+} // namespace android
diff --git a/service/common/android/bluetooth/bluetooth_avrcp_string_value.h b/service/common/android/bluetooth/bluetooth_avrcp_string_value.h
new file mode 100644
index 0000000..8f7e952
--- /dev/null
+++ b/service/common/android/bluetooth/bluetooth_avrcp_string_value.h
@@ -0,0 +1,57 @@
+//
+// 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 <binder/Parcel.h>
+#include <binder/Parcelable.h>
+
+#include "bluetooth/avrcp_string_value.h"
+
+using android::Parcel;
+using android::Parcelable;
+using android::status_t;
+
+namespace android {
+namespace bluetooth {
+
+class BluetoothAvrcpStringValue : public Parcelable,
+ public ::bluetooth::AvrcpStringValue {
+ public:
+ BluetoothAvrcpStringValue() = default;
+ BluetoothAvrcpStringValue(const ::bluetooth::AvrcpStringValue& other)
+ : ::bluetooth::AvrcpStringValue(other) {} // NOLINT(implicit)
+ BluetoothAvrcpStringValue(const BluetoothAvrcpStringValue& other)
+ : ::bluetooth::AvrcpStringValue(other) {} // NOLINT(implicit)
+ ~BluetoothAvrcpStringValue() = default;
+
+ // Write |this| parcelable to the given |parcel|. Keep in mind that
+ // implementations of writeToParcel must be manually kept in sync
+ // with readFromParcel and the Java equivalent versions of these methods.
+ //
+ // Returns android::OK on success and an appropriate error otherwise.
+ status_t writeToParcel(Parcel* parcel) const override;
+
+ // Read data from the given |parcel| into |this|. After readFromParcel
+ // completes, |this| should have equivalent state to the object that
+ // wrote itself to the parcel.
+ //
+ // Returns android::OK on success and an appropriate error otherwise.
+ status_t readFromParcel(const Parcel* parcel) override;
+};
+
+} // namespace bluetooth
+} // namespace android
diff --git a/service/common/bluetooth/a2dp_codec_config.cc b/service/common/bluetooth/a2dp_codec_config.cc
new file mode 100644
index 0000000..2b5e5ba
--- /dev/null
+++ b/service/common/bluetooth/a2dp_codec_config.cc
@@ -0,0 +1,41 @@
+//
+// 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.
+//
+
+#include "bluetooth/a2dp_codec_config.h"
+
+namespace bluetooth {
+
+A2dpCodecConfig::A2dpCodecConfig() = default;
+A2dpCodecConfig::A2dpCodecConfig(const A2dpCodecConfig& other) = default;
+A2dpCodecConfig::A2dpCodecConfig(int codec_type, int codec_priority,
+ int sample_rate, int bits_per_sample,
+ int channel_mode, int64_t codec_specific_1,
+ int64_t codec_specific_2,
+ int64_t codec_specific_3,
+ int64_t codec_specific_4)
+ : codec_type_(codec_type),
+ codec_priority_(codec_priority),
+ sample_rate_(sample_rate),
+ bits_per_sample_(bits_per_sample),
+ channel_mode_(channel_mode),
+ codec_specific_1_(codec_specific_1),
+ codec_specific_2_(codec_specific_2),
+ codec_specific_3_(codec_specific_3),
+ codec_specific_4_(codec_specific_4) {}
+
+A2dpCodecConfig::~A2dpCodecConfig() = default;
+
+} // namespace bluetooth
diff --git a/service/common/bluetooth/a2dp_codec_config.h b/service/common/bluetooth/a2dp_codec_config.h
new file mode 100644
index 0000000..10dbfcb
--- /dev/null
+++ b/service/common/bluetooth/a2dp_codec_config.h
@@ -0,0 +1,56 @@
+//
+// 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 <cstdint>
+
+namespace bluetooth {
+
+// Should match btav_a2dp_codec_config_t in bt_av.h
+class A2dpCodecConfig {
+ public:
+ A2dpCodecConfig();
+ A2dpCodecConfig(const A2dpCodecConfig& other);
+ A2dpCodecConfig(int codec_type, int codec_priority, int sample_rate,
+ int bits_per_sample, int channel_mode,
+ int64_t codec_specific_1, int64_t codec_specific_2,
+ int64_t codec_specific_3, int64_t codec_specific_4);
+ ~A2dpCodecConfig();
+
+ int codec_type() const { return codec_type_; }
+ int codec_priority() const { return codec_priority_; }
+ int sample_rate() const { return sample_rate_; }
+ int bits_per_sample() const { return bits_per_sample_; }
+ int channel_mode() const { return channel_mode_; }
+ int64_t codec_specific_1() const { return codec_specific_1_; }
+ int64_t codec_specific_2() const { return codec_specific_2_; }
+ int64_t codec_specific_3() const { return codec_specific_3_; }
+ int64_t codec_specific_4() const { return codec_specific_4_; }
+
+ protected:
+ int codec_type_ = 0;
+ int codec_priority_ = 0;
+ int sample_rate_ = 0;
+ int bits_per_sample_ = 0;
+ int channel_mode_ = 0;
+ int64_t codec_specific_1_ = 0;
+ int64_t codec_specific_2_ = 0;
+ int64_t codec_specific_3_ = 0;
+ int64_t codec_specific_4_ = 0;
+};
+
+} // namespace bluetooth
diff --git a/service/common/bluetooth/avrcp_int_value.cc b/service/common/bluetooth/avrcp_int_value.cc
new file mode 100644
index 0000000..5ea07d4
--- /dev/null
+++ b/service/common/bluetooth/avrcp_int_value.cc
@@ -0,0 +1,26 @@
+//
+// 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.
+//
+
+#include "bluetooth/avrcp_int_value.h"
+
+namespace bluetooth {
+
+AvrcpIntValue::AvrcpIntValue() = default;
+AvrcpIntValue::AvrcpIntValue(const AvrcpIntValue& other) = default;
+AvrcpIntValue::AvrcpIntValue(int id, int value) : id_(id), value_(value) {}
+AvrcpIntValue::~AvrcpIntValue() = default;
+
+} // namespace bluetooth
diff --git a/service/common/bluetooth/avrcp_int_value.h b/service/common/bluetooth/avrcp_int_value.h
new file mode 100644
index 0000000..d9cf510
--- /dev/null
+++ b/service/common/bluetooth/avrcp_int_value.h
@@ -0,0 +1,36 @@
+//
+// 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
+
+namespace bluetooth {
+
+class AvrcpIntValue {
+ public:
+ AvrcpIntValue();
+ AvrcpIntValue(const AvrcpIntValue& other);
+ AvrcpIntValue(int id, int value);
+ ~AvrcpIntValue();
+
+ int id() const { return id_; }
+ int value() const { return value_; }
+
+ protected:
+ int id_ = 0;
+ int value_ = 0;
+};
+
+} // namespace bluetooth
diff --git a/service/common/bluetooth/avrcp_register_notification_response.cc b/service/common/bluetooth/avrcp_register_notification_response.cc
new file mode 100644
index 0000000..6200f77
--- /dev/null
+++ b/service/common/bluetooth/avrcp_register_notification_response.cc
@@ -0,0 +1,31 @@
+//
+// 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.
+//
+
+#include "bluetooth/avrcp_register_notification_response.h"
+
+namespace bluetooth {
+
+AvrcpRegisterNotificationResponse::AvrcpRegisterNotificationResponse() =
+ default;
+AvrcpRegisterNotificationResponse::AvrcpRegisterNotificationResponse(
+ const AvrcpRegisterNotificationResponse& other) = default;
+AvrcpRegisterNotificationResponse::AvrcpRegisterNotificationResponse(
+ const btrc_register_notification_t& data)
+ : data_(data) {}
+AvrcpRegisterNotificationResponse::~AvrcpRegisterNotificationResponse() =
+ default;
+
+} // namespace bluetooth
diff --git a/service/common/bluetooth/avrcp_register_notification_response.h b/service/common/bluetooth/avrcp_register_notification_response.h
new file mode 100644
index 0000000..3c78da2
--- /dev/null
+++ b/service/common/bluetooth/avrcp_register_notification_response.h
@@ -0,0 +1,38 @@
+//
+// 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 <hardware/bt_common_types.h>
+#include <hardware/bt_rc.h>
+
+namespace bluetooth {
+
+class AvrcpRegisterNotificationResponse {
+ public:
+ AvrcpRegisterNotificationResponse();
+ AvrcpRegisterNotificationResponse(
+ const AvrcpRegisterNotificationResponse& other);
+ AvrcpRegisterNotificationResponse(const btrc_register_notification_t& data);
+ ~AvrcpRegisterNotificationResponse();
+
+ const btrc_register_notification_t& data() const { return data_; }
+
+ protected:
+ btrc_register_notification_t data_;
+};
+
+} // namespace bluetooth
diff --git a/service/common/bluetooth/avrcp_string_value.cc b/service/common/bluetooth/avrcp_string_value.cc
new file mode 100644
index 0000000..65f7ffa
--- /dev/null
+++ b/service/common/bluetooth/avrcp_string_value.cc
@@ -0,0 +1,29 @@
+//
+// 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.
+//
+
+#include "bluetooth/avrcp_string_value.h"
+
+using android::String16;
+
+namespace bluetooth {
+
+AvrcpStringValue::AvrcpStringValue() = default;
+AvrcpStringValue::AvrcpStringValue(const AvrcpStringValue& other) = default;
+AvrcpStringValue::AvrcpStringValue(int id, const String16& value)
+ : id_(id), value_(value) {}
+AvrcpStringValue::~AvrcpStringValue() = default;
+
+} // namespace bluetooth
diff --git a/service/common/bluetooth/avrcp_string_value.h b/service/common/bluetooth/avrcp_string_value.h
new file mode 100644
index 0000000..8ba6cb4
--- /dev/null
+++ b/service/common/bluetooth/avrcp_string_value.h
@@ -0,0 +1,38 @@
+//
+// 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 <utils/String16.h>
+
+namespace bluetooth {
+
+class AvrcpStringValue {
+ public:
+ AvrcpStringValue();
+ AvrcpStringValue(const AvrcpStringValue& other);
+ AvrcpStringValue(int id, const android::String16& value);
+ ~AvrcpStringValue();
+
+ int id() const { return id_; }
+ const android::String16& value() const { return value_; }
+
+ protected:
+ int id_ = 0;
+ android::String16 value_;
+};
+
+} // namespace bluetooth
diff --git a/service/ipc/binder/bluetooth_a2dp_source_binder_server.cc b/service/ipc/binder/bluetooth_a2dp_source_binder_server.cc
new file mode 100644
index 0000000..51e6dff
--- /dev/null
+++ b/service/ipc/binder/bluetooth_a2dp_source_binder_server.cc
@@ -0,0 +1,226 @@
+//
+// 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.
+//
+#include "service/ipc/binder/bluetooth_a2dp_source_binder_server.h"
+
+#include <base/logging.h>
+
+#include "service/adapter.h"
+
+#define AIDL_RET(value) \
+ do { \
+ *_aidl_return = (value); \
+ return Status::ok(); \
+ } while (0)
+
+#define TRY_GET_SOURCE() \
+ ({ \
+ auto source = GetA2dpSource(); \
+ if (!source) { \
+ LOG(ERROR) << __func__ << ": " \
+ << "Failed to get A2DP source interface"; \
+ AIDL_RET(false); \
+ } \
+ source; \
+ })
+
+#define TRY_GET_CB() \
+ ({ \
+ auto cb = GetA2dpSourceCallback(); \
+ if (!cb.get()) { \
+ LOG(WARNING) << "Callback for A2DP SOURCE was deleted"; \
+ return; \
+ } \
+ cb; \
+ })
+
+#define TRY_RET(expr, msg) \
+ do { \
+ if (!(expr)) { \
+ LOG(ERROR) << msg; \
+ AIDL_RET(false); \
+ } \
+ AIDL_RET(true); \
+ } while (0)
+
+#define TRY_RET_FUNC(expr) TRY_RET(expr, __func__ << " failed")
+
+using android::String16;
+using android::String8;
+using android::binder::Status;
+using android::bluetooth::BluetoothA2dpCodecConfig;
+using android::bluetooth::IBluetoothA2dpSourceCallback;
+
+using LockGuard = std::lock_guard<std::mutex>;
+
+namespace ipc {
+namespace binder {
+
+namespace {
+
+std::vector<bluetooth::A2dpCodecConfig> A2dpCodecsFromBinder(
+ const std::vector<BluetoothA2dpCodecConfig>& codecs) {
+ std::vector<bluetooth::A2dpCodecConfig> ret;
+ ret.reserve(codecs.size());
+ for (const auto& config : codecs) {
+ ret.push_back(config);
+ }
+
+ return ret;
+}
+
+std::vector<BluetoothA2dpCodecConfig> A2dpCodecsToBinder(
+ const std::vector<bluetooth::A2dpCodecConfig>& codecs) {
+ std::vector<BluetoothA2dpCodecConfig> ret;
+ ret.reserve(codecs.size());
+ for (const auto& config : codecs) {
+ ret.push_back(config);
+ }
+
+ return ret;
+}
+
+} // namespace
+
+BluetoothA2dpSourceBinderServer::BluetoothA2dpSourceBinderServer(
+ bluetooth::Adapter* adapter)
+ : adapter_(adapter) {
+ CHECK(adapter);
+}
+
+BluetoothA2dpSourceBinderServer::~BluetoothA2dpSourceBinderServer() = default;
+
+bool BluetoothA2dpSourceBinderServer::HasInstance() {
+ return GetA2dpSource() != nullptr;
+}
+
+Status BluetoothA2dpSourceBinderServer::Register(
+ const android::sp<IBluetoothA2dpSourceCallback>& callback,
+ bool* _aidl_return) {
+ auto factory = adapter_->GetA2dpSourceFactory();
+ *_aidl_return = RegisterInstanceBase(callback, factory);
+ return Status::ok();
+}
+
+Status BluetoothA2dpSourceBinderServer::Unregister() {
+ UnregisterAllBase();
+ return Status::ok();
+}
+
+Status BluetoothA2dpSourceBinderServer::Enable(
+ const std::vector<android::bluetooth::BluetoothA2dpCodecConfig>&
+ codec_priorities,
+ bool* _aidl_return) {
+ auto codec_priorities_non_binder = A2dpCodecsFromBinder(codec_priorities);
+
+ LockGuard lock(*maps_lock());
+ auto a2dp_source = TRY_GET_SOURCE();
+ TRY_RET_FUNC(a2dp_source->Enable(codec_priorities_non_binder));
+}
+
+Status BluetoothA2dpSourceBinderServer::Disable(bool* _aidl_return) {
+ LockGuard lock(*maps_lock());
+ auto a2dp_source = TRY_GET_SOURCE();
+ a2dp_source->Disable();
+ AIDL_RET(true);
+}
+
+Status BluetoothA2dpSourceBinderServer::Connect(const String16& device_address,
+ bool* _aidl_return) {
+ LockGuard lock(*maps_lock());
+ auto a2dp_source = TRY_GET_SOURCE();
+ TRY_RET_FUNC(a2dp_source->Connect(String8(device_address).string()));
+}
+
+Status BluetoothA2dpSourceBinderServer::Disconnect(
+ const String16& device_address, bool* _aidl_return) {
+ LockGuard lock(*maps_lock());
+ auto a2dp_source = TRY_GET_SOURCE();
+ TRY_RET_FUNC(a2dp_source->Disconnect(String8(device_address).string()));
+}
+
+Status BluetoothA2dpSourceBinderServer::ConfigCodec(
+ const android::String16& device_address,
+ const std::vector<android::bluetooth::BluetoothA2dpCodecConfig>&
+ codec_preferences,
+ bool* _aidl_return) {
+ auto codec_preferences_non_binder = A2dpCodecsFromBinder(codec_preferences);
+
+ LockGuard lock(*maps_lock());
+ auto a2dp_source = TRY_GET_SOURCE();
+ TRY_RET_FUNC(a2dp_source->ConfigCodec(String8(device_address).string(),
+ codec_preferences_non_binder));
+}
+
+void BluetoothA2dpSourceBinderServer::OnConnectionState(
+ const std::string& device_address, int state) {
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnConnectionState(String16(device_address.c_str()), state);
+}
+
+void BluetoothA2dpSourceBinderServer::OnAudioState(
+ const std::string& device_address, int state) {
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnAudioState(String16(device_address.c_str()), state);
+}
+
+void BluetoothA2dpSourceBinderServer::OnAudioConfig(
+ const std::string& device_address, bluetooth::A2dpCodecConfig codec_config,
+ const std::vector<bluetooth::A2dpCodecConfig>& codecs_local_capabilities,
+ const std::vector<bluetooth::A2dpCodecConfig>&
+ codecs_selectable_capabilities) {
+ auto binder_codecs_local_capabilities =
+ A2dpCodecsToBinder(codecs_local_capabilities);
+ auto binder_codecs_selectable_capabilities =
+ A2dpCodecsToBinder(codecs_selectable_capabilities);
+
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnAudioConfig(String16(device_address.c_str()), codec_config,
+ binder_codecs_local_capabilities,
+ binder_codecs_selectable_capabilities);
+}
+
+android::sp<IBluetoothA2dpSourceCallback>
+BluetoothA2dpSourceBinderServer::GetA2dpSourceCallback() {
+ auto cb = GetCallback(bluetooth::A2dpSource::kSingletonInstanceId);
+ return android::sp<IBluetoothA2dpSourceCallback>(
+ static_cast<IBluetoothA2dpSourceCallback*>(cb.get()));
+}
+
+std::shared_ptr<bluetooth::A2dpSource>
+BluetoothA2dpSourceBinderServer::GetA2dpSource() {
+ return std::static_pointer_cast<bluetooth::A2dpSource>(
+ GetInstance(bluetooth::A2dpSource::kSingletonInstanceId));
+}
+
+void BluetoothA2dpSourceBinderServer::OnRegisterInstanceImpl(
+ bluetooth::BLEStatus status, android::sp<IInterface> callback,
+ bluetooth::BluetoothInstance* instance) {
+ VLOG(1) << __func__ << " instance ID: " << instance->GetInstanceId()
+ << " status: " << status;
+ bluetooth::A2dpSource* a2dp_source =
+ static_cast<bluetooth::A2dpSource*>(instance);
+ a2dp_source->SetDelegate(this);
+
+ android::sp<IBluetoothA2dpSourceCallback> cb(
+ static_cast<IBluetoothA2dpSourceCallback*>(callback.get()));
+ cb->OnRegistered(status);
+}
+
+} // namespace binder
+} // namespace ipc
diff --git a/service/ipc/binder/bluetooth_a2dp_source_binder_server.h b/service/ipc/binder/bluetooth_a2dp_source_binder_server.h
new file mode 100644
index 0000000..160a38a
--- /dev/null
+++ b/service/ipc/binder/bluetooth_a2dp_source_binder_server.h
@@ -0,0 +1,95 @@
+//
+// 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 <map>
+#include <string>
+#include <vector>
+
+#include <base/macros.h>
+
+#include <android/bluetooth/BnBluetoothA2dpSource.h>
+#include <android/bluetooth/IBluetoothA2dpSourceCallback.h>
+
+#include "service/a2dp_source.h"
+#include "service/ipc/binder/interface_with_instances_base.h"
+
+namespace bluetooth {
+class Adapter;
+} // namespace bluetooth
+
+namespace ipc {
+namespace binder {
+
+class BluetoothA2dpSourceBinderServer
+ : public InterfaceWithInstancesBase,
+ public android::bluetooth::BnBluetoothA2dpSource,
+ public bluetooth::A2dpSource::Delegate {
+ public:
+ explicit BluetoothA2dpSourceBinderServer(bluetooth::Adapter* adapter);
+ ~BluetoothA2dpSourceBinderServer() override;
+
+ bool HasInstance();
+
+ // IBluetoothA2dpSource implementation:
+ android::binder::Status Register(
+ const android::sp<android::bluetooth::IBluetoothA2dpSourceCallback>&
+ callback,
+ bool* _aidl_return) override;
+ android::binder::Status Unregister() override;
+ android::binder::Status Enable(
+ const std::vector<android::bluetooth::BluetoothA2dpCodecConfig>&
+ codec_priorities,
+ bool* _aidl_return) override;
+ android::binder::Status Disable(bool* _aidl_return) override;
+ android::binder::Status Connect(const android::String16& device_address,
+ bool* _aidl_return) override;
+ android::binder::Status Disconnect(const android::String16& device_address,
+ bool* _aidl_return) override;
+ android::binder::Status ConfigCodec(
+ const android::String16& device_address,
+ const std::vector<android::bluetooth::BluetoothA2dpCodecConfig>&
+ codec_preferences,
+ bool* _aidl_return) override;
+
+ private:
+ // bluetooth::bluetooth::A2dpSource::Delegate implementation:
+ void OnConnectionState(const std::string& device_address, int state) override;
+ void OnAudioState(const std::string& device_address, int state) override;
+ void OnAudioConfig(
+ const std::string& device_address,
+ bluetooth::A2dpCodecConfig codec_config,
+ const std::vector<bluetooth::A2dpCodecConfig>& codecs_local_capabilities,
+ const std::vector<bluetooth::A2dpCodecConfig>&
+ codecs_selectable_capabilities) override;
+
+ android::sp<android::bluetooth::IBluetoothA2dpSourceCallback>
+ GetA2dpSourceCallback();
+ std::shared_ptr<bluetooth::A2dpSource> GetA2dpSource();
+
+ // InterfaceWithInstancesBase override:
+ void OnRegisterInstanceImpl(bluetooth::BLEStatus status,
+ android::sp<IInterface> callback,
+ bluetooth::BluetoothInstance* instance) override;
+
+ bluetooth::Adapter* const adapter_; // weak
+
+ DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSourceBinderServer);
+};
+
+} // namespace binder
+} // namespace ipc
diff --git a/service/ipc/binder/bluetooth_avrcp_target_binder_server.cc b/service/ipc/binder/bluetooth_avrcp_target_binder_server.cc
new file mode 100644
index 0000000..1652b10
--- /dev/null
+++ b/service/ipc/binder/bluetooth_avrcp_target_binder_server.cc
@@ -0,0 +1,339 @@
+//
+// 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.
+//
+#include "service/ipc/binder/bluetooth_avrcp_target_binder_server.h"
+
+#include <string>
+
+#include "base/logging.h"
+
+#include "service/adapter.h"
+
+#define AIDL_RET(value) \
+ do { \
+ *_aidl_return = (value); \
+ return Status::ok(); \
+ } while (0)
+
+#define TRY_GET_TARGET() \
+ ({ \
+ auto target = GetAvrcpTarget(); \
+ if (!target) { \
+ LOG(ERROR) << __func__ << ": " \
+ << "Failed to get AVRCP target interface"; \
+ AIDL_RET(false); \
+ } \
+ target; \
+ })
+
+#define TRY_GET_CB() \
+ ({ \
+ auto cb = GetAvrcpTargetCallback(); \
+ if (!cb.get()) { \
+ LOG(WARNING) << "Callback for AVRCP target was deleted"; \
+ return; \
+ } \
+ cb; \
+ })
+
+#define TRY_RET(expr, msg) \
+ do { \
+ if (!(expr)) { \
+ LOG(ERROR) << msg; \
+ AIDL_RET(false); \
+ } \
+ AIDL_RET(true); \
+ } while (0)
+
+#define TRY_RET_FUNC(expr) TRY_RET(expr, __func__ << " failed")
+
+using android::String16;
+using android::String8;
+using android::binder::Status;
+using android::bluetooth::BluetoothAvrcpIntValue;
+using android::bluetooth::IBluetoothAvrcpTargetCallback;
+
+using LockGuard = std::lock_guard<std::mutex>;
+
+namespace ipc {
+namespace binder {
+
+BluetoothAvrcpTargetBinderServer::BluetoothAvrcpTargetBinderServer(
+ bluetooth::Adapter* adapter)
+ : adapter_(adapter) {
+ CHECK(adapter_);
+}
+
+BluetoothAvrcpTargetBinderServer::~BluetoothAvrcpTargetBinderServer() = default;
+
+bool BluetoothAvrcpTargetBinderServer::HasInstance() {
+ return GetAvrcpTarget() != nullptr;
+}
+
+Status BluetoothAvrcpTargetBinderServer::Register(
+ const android::sp<IBluetoothAvrcpTargetCallback>& callback,
+ bool* _aidl_return) {
+ VLOG(2) << __func__;
+
+ bluetooth::AvrcpTargetFactory* gatt_client_factory =
+ adapter_->GetAvrcpTargetFactory();
+
+ *_aidl_return = RegisterInstanceBase(callback, gatt_client_factory);
+ return Status::ok();
+}
+
+Status BluetoothAvrcpTargetBinderServer::Unregister(int32_t id) {
+ VLOG(2) << __func__;
+ UnregisterInstanceBase(id);
+ return Status::ok();
+}
+
+Status BluetoothAvrcpTargetBinderServer::UnregisterAll() {
+ VLOG(2) << __func__;
+ UnregisterAllBase();
+ return Status::ok();
+}
+
+Status BluetoothAvrcpTargetBinderServer::Enable(bool* _aidl_return) {
+ auto avrcp_target = TRY_GET_TARGET();
+ TRY_RET_FUNC(avrcp_target->Enable());
+}
+
+Status BluetoothAvrcpTargetBinderServer::Disable(bool* _aidl_return) {
+ auto avrcp_target = TRY_GET_TARGET();
+ avrcp_target->Disable();
+ AIDL_RET(true);
+}
+
+Status BluetoothAvrcpTargetBinderServer::GetPlayStatusResponse(
+ const android::String16& addr, int32_t play_status, int32_t song_len,
+ int32_t song_pos, bool* _aidl_return) {
+ auto avrcp_target = TRY_GET_TARGET();
+ TRY_RET_FUNC(avrcp_target->GetPlayStatusResponse(
+ String8(addr).string(), play_status, song_len, song_pos));
+}
+
+Status BluetoothAvrcpTargetBinderServer::ListPlayerAppAttrResponse(
+ const android::String16& addr, const std::vector<int32_t>& attrs,
+ bool* _aidl_return) {
+ auto avrcp_target = TRY_GET_TARGET();
+ TRY_RET_FUNC(
+ avrcp_target->ListPlayerAppAttrResponse(String8(addr).string(), attrs));
+}
+
+Status BluetoothAvrcpTargetBinderServer::GetPlayerAppValueResponse(
+ const android::String16& addr,
+ const std::vector<::android::bluetooth::BluetoothAvrcpIntValue>& values,
+ bool* _aidl_return) {
+ auto avrcp_target = TRY_GET_TARGET();
+ std::vector<bluetooth::AvrcpIntValue> non_binder;
+ non_binder.reserve(values.size());
+ for (const auto& val : values) {
+ non_binder.push_back(val);
+ }
+ TRY_RET_FUNC(avrcp_target->GetPlayerAppValueResponse(String8(addr).string(),
+ non_binder));
+}
+
+Status BluetoothAvrcpTargetBinderServer::GetPlayerAppAttrTextResponse(
+ const android::String16& addr,
+ const std::vector<::android::bluetooth::BluetoothAvrcpStringValue>& attrs,
+ bool* _aidl_return) {
+ auto avrcp_target = TRY_GET_TARGET();
+ std::vector<bluetooth::AvrcpStringValue> non_binder;
+ non_binder.reserve(attrs.size());
+ for (const auto& val : attrs) {
+ non_binder.push_back(val);
+ }
+ TRY_RET_FUNC(avrcp_target->GetPlayerAppAttrTextResponse(
+ String8(addr).string(), non_binder));
+}
+
+Status BluetoothAvrcpTargetBinderServer::GetPlayerAppValueTextResponse(
+ const android::String16& addr,
+ const std::vector<::android::bluetooth::BluetoothAvrcpStringValue>& values,
+ bool* _aidl_return) {
+ auto avrcp_target = TRY_GET_TARGET();
+ std::vector<bluetooth::AvrcpStringValue> non_binder;
+ non_binder.reserve(values.size());
+ for (const auto& val : values) {
+ non_binder.push_back(val);
+ }
+ TRY_RET_FUNC(avrcp_target->GetPlayerAppValueTextResponse(
+ String8(addr).string(), non_binder));
+}
+
+Status BluetoothAvrcpTargetBinderServer::GetElementAttrResponse(
+ const android::String16& addr,
+ const std::vector<::android::bluetooth::BluetoothAvrcpStringValue>& attrs,
+ bool* _aidl_return) {
+ auto avrcp_target = TRY_GET_TARGET();
+ std::vector<bluetooth::AvrcpStringValue> non_binder;
+ non_binder.reserve(attrs.size());
+ for (const auto& val : attrs) {
+ non_binder.push_back(val);
+ }
+ TRY_RET_FUNC(
+ avrcp_target->GetElementAttrResponse(String8(addr).string(), non_binder));
+}
+
+Status BluetoothAvrcpTargetBinderServer::SetPlayerAppValueResponse(
+ const android::String16& addr, int32_t rsp_status, bool* _aidl_return) {
+ auto avrcp_target = TRY_GET_TARGET();
+ TRY_RET_FUNC(avrcp_target->SetPlayerAppValueResponse(String8(addr).string(),
+ rsp_status));
+}
+
+Status BluetoothAvrcpTargetBinderServer::RegisterNotificationResponse(
+ int32_t event_id, int32_t type,
+ const ::android::bluetooth::BluetoothAvrcpRegisterNotificationResponse&
+ param,
+ bool* _aidl_return) {
+ auto avrcp_target = TRY_GET_TARGET();
+ TRY_RET_FUNC(
+ avrcp_target->RegisterNotificationResponse(event_id, type, param));
+}
+
+Status BluetoothAvrcpTargetBinderServer::SetVolume(int32_t volume,
+ bool* _aidl_return) {
+ auto avrcp_target = TRY_GET_TARGET();
+ TRY_RET_FUNC(avrcp_target->SetVolume(volume));
+}
+
+void BluetoothAvrcpTargetBinderServer::OnGetRemoteFeatures(
+ const std::string& addr, int32_t features) {
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnGetRemoteFeatures(String16(addr.data(), addr.size()), features);
+}
+
+void BluetoothAvrcpTargetBinderServer::OnGetPlayStatus(
+ const std::string& addr) {
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnGetPlayStatus(String16(addr.data(), addr.size()));
+}
+
+void BluetoothAvrcpTargetBinderServer::OnListPlayerAppAttr(
+ const std::string& addr) {
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnListPlayerAppAttr(String16(addr.data(), addr.size()));
+}
+
+void BluetoothAvrcpTargetBinderServer::OnListPlayerAppValues(
+ const std::string& addr, int32_t attr_id) {
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnListPlayerAppValues(String16(addr.data(), addr.size()), attr_id);
+}
+
+void BluetoothAvrcpTargetBinderServer::OnGetPlayerAppValue(
+ const std::string& addr, const std::vector<int32_t>& attrs) {
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnGetPlayerAppValue(String16(addr.data(), addr.size()), attrs);
+}
+
+void BluetoothAvrcpTargetBinderServer::OnGetPlayerAppAttrsText(
+ const std::string& addr, const std::vector<int32_t>& attrs) {
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnGetPlayerAppAttrsText(String16(addr.data(), addr.size()), attrs);
+}
+
+void BluetoothAvrcpTargetBinderServer::OnGetPlayerAppValuesText(
+ const std::string& addr, int32_t attr_id,
+ const std::vector<int32_t>& values) {
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnGetPlayerAppValuesText(String16(addr.data(), addr.size()), attr_id,
+ values);
+}
+
+void BluetoothAvrcpTargetBinderServer::OnSetPlayerAppValue(
+ const std::string& addr,
+ const std::vector<bluetooth::AvrcpIntValue>& values) {
+ std::vector<BluetoothAvrcpIntValue> binder_values;
+ binder_values.reserve(values.size());
+ for (const auto& val : values) {
+ binder_values.push_back(val);
+ }
+
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnSetPlayerAppValue(String16(addr.data(), addr.size()), binder_values);
+}
+
+void BluetoothAvrcpTargetBinderServer::OnGetElementAttrs(
+ const std::string& addr, const std::vector<int32_t>& attrs) {
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnGetElementAttrs(String16(addr.data(), addr.size()), attrs);
+}
+
+void BluetoothAvrcpTargetBinderServer::OnRegisterNotification(
+ const std::string& addr, int32_t event_id, uint32_t param) {
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnRegisterNotification(String16(addr.data(), addr.size()), event_id,
+ param);
+}
+
+void BluetoothAvrcpTargetBinderServer::OnVolumeChange(const std::string& addr,
+ int32_t volume,
+ int32_t ctype) {
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnVolumeChange(String16(addr.data(), addr.size()), volume, ctype);
+}
+
+void BluetoothAvrcpTargetBinderServer::OnPassThroughCommand(
+ const std::string& addr, int32_t id, int32_t key_state) {
+ LockGuard lock(*maps_lock());
+ auto cb = TRY_GET_CB();
+ cb->OnPassThroughCommand(String16(addr.data(), addr.size()), id, key_state);
+}
+
+android::sp<IBluetoothAvrcpTargetCallback>
+BluetoothAvrcpTargetBinderServer::GetAvrcpTargetCallback() {
+ auto cb = GetCallback(bluetooth::AvrcpTarget::kSingletonInstanceId);
+ return android::sp<IBluetoothAvrcpTargetCallback>(
+ static_cast<IBluetoothAvrcpTargetCallback*>(cb.get()));
+}
+
+std::shared_ptr<bluetooth::AvrcpTarget>
+BluetoothAvrcpTargetBinderServer::GetAvrcpTarget() {
+ return std::static_pointer_cast<bluetooth::AvrcpTarget>(
+ GetInstance(bluetooth::AvrcpTarget::kSingletonInstanceId));
+}
+
+void BluetoothAvrcpTargetBinderServer::OnRegisterInstanceImpl(
+ bluetooth::BLEStatus status, android::sp<IInterface> callback,
+ bluetooth::BluetoothInstance* instance) {
+ VLOG(1) << __func__ << " client ID: " << instance->GetInstanceId()
+ << " status: " << status;
+
+ bluetooth::AvrcpTarget* avrcp_target =
+ static_cast<bluetooth::AvrcpTarget*>(instance);
+ avrcp_target->SetDelegate(this);
+
+ android::sp<IBluetoothAvrcpTargetCallback> cb(
+ static_cast<IBluetoothAvrcpTargetCallback*>(callback.get()));
+ cb->OnRegistered(status);
+}
+
+} // namespace binder
+} // namespace ipc
diff --git a/service/ipc/binder/bluetooth_avrcp_target_binder_server.h b/service/ipc/binder/bluetooth_avrcp_target_binder_server.h
new file mode 100644
index 0000000..9d2bba0
--- /dev/null
+++ b/service/ipc/binder/bluetooth_avrcp_target_binder_server.h
@@ -0,0 +1,131 @@
+//
+// 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 <map>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+
+#include "android/bluetooth/BnBluetoothAvrcpTarget.h"
+#include "android/bluetooth/IBluetoothAvrcpTargetCallback.h"
+
+#include "service/avrcp_target.h"
+#include "service/ipc/binder/interface_with_instances_base.h"
+
+namespace bluetooth {
+class Adapter;
+} // namespace bluetooth
+
+namespace ipc {
+namespace binder {
+
+class BluetoothAvrcpTargetBinderServer
+ : public InterfaceWithInstancesBase,
+ public android::bluetooth::BnBluetoothAvrcpTarget,
+ public bluetooth::AvrcpTarget::Delegate {
+ public:
+ explicit BluetoothAvrcpTargetBinderServer(bluetooth::Adapter* adapter);
+ ~BluetoothAvrcpTargetBinderServer() override;
+
+ bool HasInstance();
+
+ // IBluetoothAvrcpTarget implementation:
+ android::binder::Status Register(
+ const android::sp<android::bluetooth::IBluetoothAvrcpTargetCallback>&
+ callback,
+ bool* _aidl_return) override;
+ android::binder::Status Unregister(int32_t id) override;
+ android::binder::Status UnregisterAll() override;
+ android::binder::Status Enable(bool* _aidl_return) override;
+ android::binder::Status Disable(bool* _aidl_return) override;
+ android::binder::Status GetPlayStatusResponse(const android::String16& addr,
+ int32_t play_status,
+ int32_t song_len,
+ int32_t song_pos,
+ bool* _aidl_return) override;
+ android::binder::Status ListPlayerAppAttrResponse(
+ const android::String16& addr, const std::vector<int32_t>& attrs,
+ bool* _aidl_return) override;
+ android::binder::Status GetPlayerAppValueResponse(
+ const android::String16& addr,
+ const std::vector<android::bluetooth::BluetoothAvrcpIntValue>& values,
+ bool* _aidl_return) override;
+ android::binder::Status GetPlayerAppAttrTextResponse(
+ const android::String16& addr,
+ const std::vector<android::bluetooth::BluetoothAvrcpStringValue>& attrs,
+ bool* _aidl_return) override;
+ android::binder::Status GetPlayerAppValueTextResponse(
+ const android::String16& addr,
+ const std::vector<android::bluetooth::BluetoothAvrcpStringValue>& values,
+ bool* _aidl_return) override;
+ android::binder::Status GetElementAttrResponse(
+ const android::String16& addr,
+ const std::vector<android::bluetooth::BluetoothAvrcpStringValue>& attrs,
+ bool* _aidl_return) override;
+ android::binder::Status SetPlayerAppValueResponse(
+ const android::String16& addr, int32_t rsp_status,
+ bool* _aidl_return) override;
+ android::binder::Status RegisterNotificationResponse(
+ int32_t event_id, int32_t type,
+ const android::bluetooth::BluetoothAvrcpRegisterNotificationResponse&
+ param,
+ bool* _aidl_return) override;
+ android::binder::Status SetVolume(int32_t volume,
+ bool* _aidl_return) override;
+
+ private:
+ // bluetooth::bluetooth::AvrcpTarget::Delegate implementation:
+ void OnGetRemoteFeatures(const std::string& addr, int32_t features) override;
+ void OnGetPlayStatus(const std::string& addr) override;
+ void OnListPlayerAppAttr(const std::string& addr) override;
+ void OnListPlayerAppValues(const std::string& addr, int32_t attr_id) override;
+ void OnGetPlayerAppValue(const std::string& addr,
+ const std::vector<int32_t>& attrs) override;
+ void OnGetPlayerAppAttrsText(const std::string& addr,
+ const std::vector<int32_t>& attrs) override;
+ void OnGetPlayerAppValuesText(const std::string& addr, int32_t attr_id,
+ const std::vector<int32_t>& values) override;
+ void OnSetPlayerAppValue(
+ const std::string& addr,
+ const std::vector<bluetooth::AvrcpIntValue>& values) override;
+ void OnGetElementAttrs(const std::string& addr,
+ const std::vector<int32_t>& attrs) override;
+ void OnRegisterNotification(const std::string& addr, int32_t event_id,
+ uint32_t param) override;
+ void OnVolumeChange(const std::string& addr, int32_t volume,
+ int32_t ctype) override;
+ void OnPassThroughCommand(const std::string& addr, int32_t id,
+ int32_t key_state) override;
+
+ // InterfaceWithInstancesBase override:
+ void OnRegisterInstanceImpl(bluetooth::BLEStatus status,
+ android::sp<IInterface> callback,
+ bluetooth::BluetoothInstance* instance) override;
+
+ android::sp<android::bluetooth::IBluetoothAvrcpTargetCallback>
+ GetAvrcpTargetCallback();
+ std::shared_ptr<bluetooth::AvrcpTarget> GetAvrcpTarget();
+
+ bluetooth::Adapter* const adapter_; // weak
+
+ DISALLOW_COPY_AND_ASSIGN(BluetoothAvrcpTargetBinderServer);
+};
+
+} // namespace binder
+} // namespace ipc
diff --git a/service/ipc/binder/bluetooth_binder_server.cc b/service/ipc/binder/bluetooth_binder_server.cc
index 30090ee..ca36019 100644
--- a/service/ipc/binder/bluetooth_binder_server.cc
+++ b/service/ipc/binder/bluetooth_binder_server.cc
@@ -19,7 +19,9 @@
#include <base/logging.h>
#include "service/ipc/binder/bluetooth_a2dp_sink_binder_server.h"
+#include "service/ipc/binder/bluetooth_a2dp_source_binder_server.h"
#include "service/ipc/binder/bluetooth_avrcp_control_binder_server.h"
+#include "service/ipc/binder/bluetooth_avrcp_target_binder_server.h"
#include "service/ipc/binder/bluetooth_gatt_client_binder_server.h"
#include "service/ipc/binder/bluetooth_gatt_server_binder_server.h"
#include "service/ipc/binder/bluetooth_le_advertiser_binder_server.h"
@@ -214,6 +216,29 @@
return Status::ok();
}
+Status BluetoothBinderServer::GetA2dpSourceInterface(
+ ::android::sp<IBluetoothA2dpSource>* _aidl_return) {
+ VLOG(2) << __func__;
+
+ if (!adapter_->IsEnabled()) {
+ LOG(ERROR) << "Cannot obtain IBluetoothA2dpSource interface while disabled";
+ *_aidl_return = nullptr;
+ return Status::ok();
+ }
+
+ if (!a2dp_source_interface_.get())
+ a2dp_source_interface_ = new BluetoothA2dpSourceBinderServer(adapter_);
+
+ if (a2dp_source_interface_->HasInstance()) {
+ LOG(ERROR) << "Only one A2dpSource interface allowed at a time";
+ *_aidl_return = nullptr;
+ return Status::ok();
+ }
+
+ *_aidl_return = a2dp_source_interface_;
+ return Status::ok();
+}
+
Status BluetoothBinderServer::GetLowEnergyInterface(
::android::sp<IBluetoothLowEnergy>* _aidl_return) {
VLOG(2) << __func__;
@@ -318,6 +343,30 @@
return Status::ok();
}
+Status BluetoothBinderServer::GetAvrcpTargetInterface(
+ ::android::sp<IBluetoothAvrcpTarget>* _aidl_return) {
+ VLOG(2) << __func__;
+
+ if (!adapter_->IsEnabled()) {
+ LOG(ERROR)
+ << "Cannot obtain IBluetoothAvrcpTarget interface while disabled";
+ *_aidl_return = NULL;
+ return Status::ok();
+ }
+
+ if (!avrcp_target_interface_.get())
+ avrcp_target_interface_ = new BluetoothAvrcpTargetBinderServer(adapter_);
+
+ if (avrcp_target_interface_->HasInstance()) {
+ LOG(ERROR) << "Only one AVRCP target interface allowed at a time";
+ *_aidl_return = nullptr;
+ return Status::ok();
+ }
+
+ *_aidl_return = avrcp_target_interface_;
+ return Status::ok();
+}
+
android::status_t BluetoothBinderServer::dump(
int fd, const android::Vector<android::String16>& args) {
VLOG(2) << __func__ << " called with fd " << fd;
diff --git a/service/ipc/binder/bluetooth_binder_server.h b/service/ipc/binder/bluetooth_binder_server.h
index 1388626..bfeb589 100644
--- a/service/ipc/binder/bluetooth_binder_server.h
+++ b/service/ipc/binder/bluetooth_binder_server.h
@@ -25,7 +25,9 @@
#include <android/bluetooth/BnBluetooth.h>
#include <android/bluetooth/IBluetoothA2dpSink.h>
+#include <android/bluetooth/IBluetoothA2dpSource.h>
#include <android/bluetooth/IBluetoothAvrcpControl.h>
+#include <android/bluetooth/IBluetoothAvrcpTarget.h>
#include <android/bluetooth/IBluetoothCallback.h>
#include <android/bluetooth/IBluetoothGattClient.h>
#include <android/bluetooth/IBluetoothGattServer.h>
@@ -42,7 +44,9 @@
using android::bluetooth::BnBluetooth;
using android::bluetooth::IBluetoothA2dpSink;
+using android::bluetooth::IBluetoothA2dpSource;
using android::bluetooth::IBluetoothAvrcpControl;
+using android::bluetooth::IBluetoothAvrcpTarget;
using android::bluetooth::IBluetoothCallback;
using android::bluetooth::IBluetoothGattClient;
using android::bluetooth::IBluetoothGattServer;
@@ -54,6 +58,8 @@
namespace binder {
class BluetoothA2dpSinkBinderServer;
+class BluetoothA2dpSourceBinderServer;
+class BluetoothAvrcpTargetBinderServer;
// Implements the server side of the IBluetooth Binder interface.
class BluetoothBinderServer : public BnBluetooth,
@@ -93,6 +99,8 @@
Status IsMultiAdvertisementSupported(bool* _aidl_return) override;
Status GetA2dpSinkInterface(
::android::sp<IBluetoothA2dpSink>* _aidl_return) override;
+ Status GetA2dpSourceInterface(
+ ::android::sp<IBluetoothA2dpSource>* _aidl_return) override;
Status GetLowEnergyInterface(
::android::sp<IBluetoothLowEnergy>* _aidl_return) override;
Status GetLeAdvertiserInterface(
@@ -105,6 +113,8 @@
::android::sp<IBluetoothGattServer>* _aidl_return) override;
Status GetAvrcpControlInterface(
::android::sp<IBluetoothAvrcpControl>* _aidl_return) override;
+ Status GetAvrcpTargetInterface(
+ ::android::sp<IBluetoothAvrcpTarget>* _aidl_return) override;
android::status_t dump(
int fd, const android::Vector<android::String16>& args) override;
@@ -147,6 +157,10 @@
// first call to GetA2dpSinkInterface().
android::sp<BluetoothA2dpSinkBinderServer> a2dp_sink_interface_;
+ // The IBluetoothA2dpSource interface handle. This is lazily initialized on
+ // the first call to GetA2dpSourceInterface().
+ android::sp<BluetoothA2dpSourceBinderServer> a2dp_source_interface_;
+
// The IBluetoothLowEnergy interface handle. This is lazily initialized on the
// first call to GetLowEnergyInterface().
android::sp<IBluetoothLowEnergy> low_energy_interface_;
@@ -171,6 +185,10 @@
// the first call to GetAvrcpControlInterface().
android::sp<IBluetoothAvrcpControl> avrcp_control_interface_;
+ // The IBluetoothAvrcpTarget interface handle. This is lazily initialized on
+ // the first call to GetAvrcpTargetInterface().
+ android::sp<BluetoothAvrcpTargetBinderServer> avrcp_target_interface_;
+
DISALLOW_COPY_AND_ASSIGN(BluetoothBinderServer);
};
diff --git a/service/test/mock_adapter.h b/service/test/mock_adapter.h
index ff64ab1..2c496b1 100644
--- a/service/test/mock_adapter.h
+++ b/service/test/mock_adapter.h
@@ -52,7 +52,9 @@
MOCK_METHOD1(GetRemoteDeviceProperties,
bool(const std::string& device_address));
MOCK_CONST_METHOD0(GetA2dpSinkFactory, A2dpSinkFactory*());
+ MOCK_CONST_METHOD0(GetA2dpSourceFactory, A2dpSourceFactory*());
MOCK_CONST_METHOD0(GetAvrcpControlFactory, AvrcpControlFactory*());
+ MOCK_CONST_METHOD0(GetAvrcpTargetFactory, AvrcpTargetFactory*());
MOCK_CONST_METHOD0(GetLowEnergyClientFactory, LowEnergyClientFactory*());
MOCK_CONST_METHOD0(GetLeAdvertiserFactory, LowEnergyAdvertiserFactory*());
MOCK_CONST_METHOD0(GetLeScannerFactory, LowEnergyScannerFactory*());