audio: Add IBluetoothLe am: b5647da1ad

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2477536

Change-Id: I00c7d4d4114acd560ce77f302142aabf9e9ed426
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Mikhail Naganov 2023-03-08 19:09:25 +00:00 committed by Automerger Merge Worker
commit 1202d57e63
12 changed files with 189 additions and 3 deletions

View file

@ -114,6 +114,7 @@ aidl_interface {
"android/hardware/audio/core/AudioRoute.aidl",
"android/hardware/audio/core/IBluetooth.aidl",
"android/hardware/audio/core/IBluetoothA2dp.aidl",
"android/hardware/audio/core/IBluetoothLe.aidl",
"android/hardware/audio/core/IConfig.aidl",
"android/hardware/audio/core/IModule.aidl",
"android/hardware/audio/core/IStreamCallback.aidl",

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2023 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.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.audio.core;
@VintfStability
interface IBluetoothLe {
boolean isEnabled();
void setEnabled(boolean enabled);
}

View file

@ -38,6 +38,7 @@ interface IModule {
@nullable android.hardware.audio.core.ITelephony getTelephony();
@nullable android.hardware.audio.core.IBluetooth getBluetooth();
@nullable android.hardware.audio.core.IBluetoothA2dp getBluetoothA2dp();
@nullable android.hardware.audio.core.IBluetoothLe getBluetoothLe();
android.media.audio.common.AudioPort connectExternalDevice(in android.media.audio.common.AudioPort templateIdAndAdditionalData);
void disconnectExternalDevice(int portId);
android.hardware.audio.core.AudioPatch[] getAudioPatches();

View file

@ -25,6 +25,9 @@ import android.media.audio.common.Int;
* and the SCO Link. This interface is optional to implement and provide by the
* vendor. It needs to be provided only if the device actually supports BT SCO
* or HFP.
*
* Each of IBluetooth* interfaces is independent of each other. The HAL module
* can provide any combination of them.
*/
@VintfStability
interface IBluetooth {

View file

@ -24,8 +24,8 @@ import android.hardware.audio.core.VendorParameter;
* the vendor. It needs to be provided only if the device actually supports BT
* A2DP.
*
* This interface is separate from IBluetooth interface which manages SCO & HFP.
* The HAL module can handle both SCO and A2DP profiles or only one of them.
* Each of IBluetooth* interfaces is independent of each other. The HAL module
* can provide any combination of them.
*/
@VintfStability
interface IBluetoothA2dp {

View file

@ -0,0 +1,51 @@
/*
* Copyright (C) 2023 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.hardware.audio.core;
/**
* An instance of IBluetoothLe manages settings for the LE (Low Energy)
* profiles. This interface is optional to implement by the vendor. It needs to
* be provided only if the device actually supports BT LE.
*
* Each of IBluetooth* interfaces is independent of each other. The HAL module
* can provide any combination of them.
*/
@VintfStability
interface IBluetoothLe {
/**
* Whether BT LE is enabled.
*
* Returns the current state of LE support. The client might need to
* disable (suspend) LE when another profile (for example, SCO) is
* activated.
*
* @return Whether BT LE is enabled.
*/
boolean isEnabled();
/**
* Enable or disable LE.
*
* Sets the current state of LE support. The client might need to
* disable (suspend) LE when another Bluetooth profile (for example, SCO) is
* activated.
*
* @param enabled Whether BT LE must be enabled or suspended.
* @throws EX_ILLEGAL_STATE If there was an error performing the operation.
*/
void setEnabled(boolean enabled);
}

View file

@ -22,6 +22,7 @@ import android.hardware.audio.core.AudioPatch;
import android.hardware.audio.core.AudioRoute;
import android.hardware.audio.core.IBluetooth;
import android.hardware.audio.core.IBluetoothA2dp;
import android.hardware.audio.core.IBluetoothLe;
import android.hardware.audio.core.IStreamCallback;
import android.hardware.audio.core.IStreamIn;
import android.hardware.audio.core.IStreamOut;
@ -117,6 +118,20 @@ interface IModule {
*/
@nullable IBluetoothA2dp getBluetoothA2dp();
/**
* Retrieve the interface to control Bluetooth LE.
*
* If the HAL module supports LE Profile functionality for Bluetooth, it
* must return an instance of the IBluetoothLe interface. The same
* instance must be returned during the lifetime of the HAL module. If the
* HAL module does not support BT LE, a null must be returned, without
* throwing any errors.
*
* @return An instance of the IBluetoothLe interface implementation.
* @throws EX_ILLEGAL_STATE If there was an error creating an instance.
*/
@nullable IBluetoothLe getBluetoothLe();
/**
* Set a device port of an external device into connected state.
*
@ -842,7 +857,7 @@ interface IModule {
AudioMMapPolicyInfo[] getMmapPolicyInfos(AudioMMapPolicyType mmapPolicyType);
/**
* Indicates if this module supports variable latency control for instance
* Indicates if this module supports variable latency control, for instance,
* over Bluetooth A2DP or LE Audio links.
*
* If supported, all instances of IStreamOut interface returned by this module must

View file

@ -105,4 +105,16 @@ ndk::ScopedAStatus BluetoothA2dp::reconfigureOffload(
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus BluetoothLe::isEnabled(bool* _aidl_return) {
*_aidl_return = mEnabled;
LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus BluetoothLe::setEnabled(bool in_enabled) {
mEnabled = in_enabled;
LOG(DEBUG) << __func__ << ": " << mEnabled;
return ndk::ScopedAStatus::ok();
}
} // namespace aidl::android::hardware::audio::core

View file

@ -396,6 +396,15 @@ ndk::ScopedAStatus Module::getBluetoothA2dp(std::shared_ptr<IBluetoothA2dp>* _ai
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Module::getBluetoothLe(std::shared_ptr<IBluetoothLe>* _aidl_return) {
if (!mBluetoothLe) {
mBluetoothLe = ndk::SharedRefBase::make<BluetoothLe>();
}
*_aidl_return = mBluetoothLe.getPtr();
LOG(DEBUG) << __func__ << ": returning instance of IBluetoothLe: " << _aidl_return->get();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdAndAdditionalData,
AudioPort* _aidl_return) {
const int32_t templateId = in_templateIdAndAdditionalData.id;

View file

@ -18,6 +18,7 @@
#include <aidl/android/hardware/audio/core/BnBluetooth.h>
#include <aidl/android/hardware/audio/core/BnBluetoothA2dp.h>
#include <aidl/android/hardware/audio/core/BnBluetoothLe.h>
namespace aidl::android::hardware::audio::core {
@ -48,4 +49,15 @@ class BluetoothA2dp : public BnBluetoothA2dp {
bool mEnabled = false;
};
class BluetoothLe : public BnBluetoothLe {
public:
BluetoothLe() = default;
private:
ndk::ScopedAStatus isEnabled(bool* _aidl_return) override;
ndk::ScopedAStatus setEnabled(bool in_enabled) override;
bool mEnabled = false;
};
} // namespace aidl::android::hardware::audio::core

View file

@ -72,6 +72,7 @@ class Module : public BnModule {
ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override;
ndk::ScopedAStatus getBluetoothA2dp(std::shared_ptr<IBluetoothA2dp>* _aidl_return) override;
ndk::ScopedAStatus getBluetoothLe(std::shared_ptr<IBluetoothLe>* _aidl_return) override;
ndk::ScopedAStatus connectExternalDevice(
const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData,
::aidl::android::media::audio::common::AudioPort* _aidl_return) override;
@ -175,6 +176,7 @@ class Module : public BnModule {
ChildInterface<ITelephony> mTelephony;
ChildInterface<IBluetooth> mBluetooth;
ChildInterface<IBluetoothA2dp> mBluetoothA2dp;
ChildInterface<IBluetoothLe> mBluetoothLe;
// ids of ports created at runtime via 'connectExternalDevice'.
std::set<int32_t> mConnectedDevicePorts;
Streams mStreams;

View file

@ -62,6 +62,7 @@ using aidl::android::hardware::audio::core::AudioPatch;
using aidl::android::hardware::audio::core::AudioRoute;
using aidl::android::hardware::audio::core::IBluetooth;
using aidl::android::hardware::audio::core::IBluetoothA2dp;
using aidl::android::hardware::audio::core::IBluetoothLe;
using aidl::android::hardware::audio::core::IModule;
using aidl::android::hardware::audio::core::IStreamCommon;
using aidl::android::hardware::audio::core::IStreamIn;
@ -2111,6 +2112,42 @@ TEST_P(AudioCoreBluetoothA2dp, OffloadReconfiguration) {
}
}
class AudioCoreBluetoothLe : public AudioCoreModuleBase,
public testing::TestWithParam<std::string> {
public:
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam()));
ASSERT_IS_OK(module->getBluetoothLe(&bluetooth));
}
void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
std::shared_ptr<IBluetoothLe> bluetooth;
};
TEST_P(AudioCoreBluetoothLe, SameInstance) {
if (bluetooth == nullptr) {
GTEST_SKIP() << "BluetoothLe is not supported";
}
std::shared_ptr<IBluetoothLe> bluetooth2;
EXPECT_IS_OK(module->getBluetoothLe(&bluetooth2));
ASSERT_NE(nullptr, bluetooth2.get());
EXPECT_EQ(bluetooth->asBinder(), bluetooth2->asBinder())
<< "getBluetoothLe must return the same interface instance across invocations";
}
TEST_P(AudioCoreBluetoothLe, Enabled) {
if (bluetooth == nullptr) {
GTEST_SKIP() << "BluetoothLe is not supported";
}
// Since enabling LE may require having an actual device connection,
// limit testing to setting back the current value.
bool enabled;
ASSERT_IS_OK(bluetooth->isEnabled(&enabled));
EXPECT_IS_OK(bluetooth->setEnabled(enabled))
<< "setEnabled without actual state change must not fail";
}
class AudioCoreTelephony : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
public:
void SetUp() override {
@ -3543,6 +3580,10 @@ INSTANTIATE_TEST_SUITE_P(AudioCoreBluetoothA2dpTest, AudioCoreBluetoothA2dp,
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
android::PrintInstanceNameToString);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreBluetoothA2dp);
INSTANTIATE_TEST_SUITE_P(AudioCoreBluetoothLeTest, AudioCoreBluetoothLe,
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
android::PrintInstanceNameToString);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreBluetoothLe);
INSTANTIATE_TEST_SUITE_P(AudioCoreTelephonyTest, AudioCoreTelephony,
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
android::PrintInstanceNameToString);