mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:23:37 +00:00
Merge "audio: Add IBluetooth core interface" am: 7d183a48c8
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2239861 Change-Id: Ib83232899075b03f32767f7cc8f4b74c22e78f9a Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -112,6 +112,7 @@ aidl_interface {
|
||||
"android/hardware/audio/core/AudioMode.aidl",
|
||||
"android/hardware/audio/core/AudioPatch.aidl",
|
||||
"android/hardware/audio/core/AudioRoute.aidl",
|
||||
"android/hardware/audio/core/IBluetooth.aidl",
|
||||
"android/hardware/audio/core/IConfig.aidl",
|
||||
"android/hardware/audio/core/IModule.aidl",
|
||||
"android/hardware/audio/core/IStreamCallback.aidl",
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 IBluetooth {
|
||||
android.hardware.audio.core.IBluetooth.ScoConfig setScoConfig(in android.hardware.audio.core.IBluetooth.ScoConfig config);
|
||||
android.hardware.audio.core.IBluetooth.HfpConfig setHfpConfig(in android.hardware.audio.core.IBluetooth.HfpConfig config);
|
||||
@JavaDerive(equals=true, toString=true) @VintfStability
|
||||
parcelable ScoConfig {
|
||||
@nullable android.media.audio.common.Boolean isEnabled;
|
||||
@nullable android.media.audio.common.Boolean isNrecEnabled;
|
||||
android.hardware.audio.core.IBluetooth.ScoConfig.Mode mode = android.hardware.audio.core.IBluetooth.ScoConfig.Mode.UNSPECIFIED;
|
||||
@nullable @utf8InCpp String debugName;
|
||||
@VintfStability
|
||||
enum Mode {
|
||||
UNSPECIFIED = 0,
|
||||
SCO = 1,
|
||||
SCO_WB = 2,
|
||||
SCO_SWB = 3,
|
||||
}
|
||||
}
|
||||
@JavaDerive(equals=true, toString=true) @VintfStability
|
||||
parcelable HfpConfig {
|
||||
@nullable android.media.audio.common.Boolean isEnabled;
|
||||
@nullable android.media.audio.common.Int sampleRate;
|
||||
@nullable android.media.audio.common.Float volume;
|
||||
const int VOLUME_MIN = 0;
|
||||
const int VOLUME_MAX = 1;
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ package android.hardware.audio.core;
|
||||
interface IModule {
|
||||
void setModuleDebug(in android.hardware.audio.core.ModuleDebug debug);
|
||||
@nullable android.hardware.audio.core.ITelephony getTelephony();
|
||||
@nullable android.hardware.audio.core.IBluetooth getBluetooth();
|
||||
android.media.audio.common.AudioPort connectExternalDevice(in android.media.audio.common.AudioPort templateIdAndAdditionalData);
|
||||
void disconnectExternalDevice(int portId);
|
||||
android.hardware.audio.core.AudioPatch[] getAudioPatches();
|
||||
|
||||
127
audio/aidl/android/hardware/audio/core/IBluetooth.aidl
Normal file
127
audio/aidl/android/hardware/audio/core/IBluetooth.aidl
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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;
|
||||
|
||||
import android.media.audio.common.Boolean;
|
||||
import android.media.audio.common.Float;
|
||||
import android.media.audio.common.Int;
|
||||
|
||||
/**
|
||||
* An instance of IBluetooth manages settings for the Hands-Free Profile (HFP)
|
||||
* 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.
|
||||
*/
|
||||
@VintfStability
|
||||
interface IBluetooth {
|
||||
@JavaDerive(equals=true, toString=true)
|
||||
@VintfStability
|
||||
parcelable ScoConfig {
|
||||
/**
|
||||
* Whether BT SCO is enabled. The client might need to disable it
|
||||
* when another profile (for example, A2DP) is activated.
|
||||
*/
|
||||
@nullable Boolean isEnabled;
|
||||
/**
|
||||
* Whether BT SCO Noise Reduction and Echo Cancellation are enabled.
|
||||
*/
|
||||
@nullable Boolean isNrecEnabled;
|
||||
@VintfStability enum Mode { UNSPECIFIED, SCO, SCO_WB, SCO_SWB }
|
||||
/**
|
||||
* If set, specifies the SCO mode to use:
|
||||
* regular, wide band (WB), or super wide band (SWB).
|
||||
*/
|
||||
Mode mode = Mode.UNSPECIFIED;
|
||||
/**
|
||||
* The name of the BT SCO headset used for debugging purposes. Can be empty.
|
||||
*/
|
||||
@nullable @utf8InCpp String debugName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configuration of Bluetooth SCO.
|
||||
*
|
||||
* In the provided parcelable, the client sets zero, one or more parameters
|
||||
* which have to be updated on the HAL side. The parameters that are left
|
||||
* unset must retain their current values. It is allowed to change
|
||||
* parameters while the SCO profile is disabled (isEnabled.value == false).
|
||||
*
|
||||
* In the returned parcelable, all parameter fields known to the HAL module
|
||||
* must be populated to their current values. If the SCO profile is
|
||||
* currently disabled (isEnabled.value == false), the parameters must
|
||||
* reflect the last values that were in use.
|
||||
*
|
||||
* The client can pass an uninitialized parcelable in order to retrieve the
|
||||
* current configuration.
|
||||
*
|
||||
* @return The current configuration (after update). All fields known to
|
||||
* the HAL must be populated.
|
||||
* @param config The configuration to set. Any number of fields may be left
|
||||
* uninitialized.
|
||||
* @throws EX_UNSUPPORTED_OPERATION If BT SCO is not supported.
|
||||
* @throws EX_ILLEGAL_ARGUMENT If the requested combination of parameter
|
||||
* values is invalid.
|
||||
*/
|
||||
ScoConfig setScoConfig(in ScoConfig config);
|
||||
|
||||
@JavaDerive(equals=true, toString=true)
|
||||
@VintfStability
|
||||
parcelable HfpConfig {
|
||||
/**
|
||||
* Whether BT HFP is enabled.
|
||||
*/
|
||||
@nullable Boolean isEnabled;
|
||||
/**
|
||||
* The sample rate of BT HFP, in Hertz. Must be a positive number.
|
||||
*/
|
||||
@nullable Int sampleRate;
|
||||
|
||||
const int VOLUME_MIN = 0;
|
||||
const int VOLUME_MAX = 1;
|
||||
/**
|
||||
* The output volume of BT HFP. 1.0f means unity gain, 0.0f is muted,
|
||||
* see VOLUME_* constants;
|
||||
*/
|
||||
@nullable Float volume;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configuration of Bluetooth HFP.
|
||||
*
|
||||
* In the provided parcelable, the client sets zero, one or more parameters
|
||||
* which have to be updated on the HAL side. The parameters that are left
|
||||
* unset must retain their current values. It is allowed to change
|
||||
* parameters while the HFP profile is disabled (isEnabled.value == false).
|
||||
*
|
||||
* In the returned parcelable, all parameter fields known to the HAL module
|
||||
* must be populated to their current values. If the HFP profile is
|
||||
* currently disabled (isEnabled.value == false), the parameters must
|
||||
* reflect the last values that were in use.
|
||||
*
|
||||
* The client can pass an uninitialized parcelable in order to retrieve the
|
||||
* current configuration.
|
||||
*
|
||||
* @return The current configuration (after update). All fields known to
|
||||
* the HAL must be populated.
|
||||
* @param config The configuration to set. Any number of fields may be left
|
||||
* uninitialized.
|
||||
* @throws EX_UNSUPPORTED_OPERATION If BT HFP is not supported.
|
||||
* @throws EX_ILLEGAL_ARGUMENT If the requested combination of parameter
|
||||
* values is invalid.
|
||||
*/
|
||||
HfpConfig setHfpConfig(in HfpConfig config);
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import android.hardware.audio.common.SourceMetadata;
|
||||
import android.hardware.audio.core.AudioMode;
|
||||
import android.hardware.audio.core.AudioPatch;
|
||||
import android.hardware.audio.core.AudioRoute;
|
||||
import android.hardware.audio.core.IBluetooth;
|
||||
import android.hardware.audio.core.IStreamCallback;
|
||||
import android.hardware.audio.core.IStreamIn;
|
||||
import android.hardware.audio.core.IStreamOut;
|
||||
@@ -85,6 +86,20 @@ interface IModule {
|
||||
*/
|
||||
@nullable ITelephony getTelephony();
|
||||
|
||||
/**
|
||||
* Retrieve the interface to control Bluetooth SCO and HFP.
|
||||
*
|
||||
* If the HAL module supports either the SCO Link or Hands-Free Profile
|
||||
* functionality (or both) for Bluetooth, it must return an instance of the
|
||||
* IBluetooth interface. The same instance must be returned during the
|
||||
* lifetime of the HAL module. If the HAL module does not support BT SCO and
|
||||
* HFP, a null must be returned, without throwing any errors.
|
||||
*
|
||||
* @return An instance of the IBluetooth interface implementation.
|
||||
* @throws EX_ILLEGAL_STATE If there was an error creating an instance.
|
||||
*/
|
||||
@nullable IBluetooth getBluetooth();
|
||||
|
||||
/**
|
||||
* Set a device port of an external device into connected state.
|
||||
*
|
||||
|
||||
@@ -62,6 +62,7 @@ cc_library_static {
|
||||
export_include_dirs: ["include"],
|
||||
srcs: [
|
||||
"AudioPolicyConfigXmlConverter.cpp",
|
||||
"Bluetooth.cpp",
|
||||
"Config.cpp",
|
||||
"Configuration.cpp",
|
||||
"EngineConfigXmlConverter.cpp",
|
||||
|
||||
82
audio/aidl/default/Bluetooth.cpp
Normal file
82
audio/aidl/default/Bluetooth.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "AHAL_Bluetooth"
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "core-impl/Bluetooth.h"
|
||||
|
||||
using aidl::android::media::audio::common::Boolean;
|
||||
using aidl::android::media::audio::common::Float;
|
||||
using aidl::android::media::audio::common::Int;
|
||||
|
||||
namespace aidl::android::hardware::audio::core {
|
||||
|
||||
Bluetooth::Bluetooth() {
|
||||
mScoConfig.isEnabled = Boolean{false};
|
||||
mScoConfig.isNrecEnabled = Boolean{false};
|
||||
mScoConfig.mode = ScoConfig::Mode::SCO;
|
||||
mHfpConfig.isEnabled = Boolean{false};
|
||||
mHfpConfig.sampleRate = Int{8000};
|
||||
mHfpConfig.volume = Float{HfpConfig::VOLUME_MAX};
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Bluetooth::setScoConfig(const ScoConfig& in_config, ScoConfig* _aidl_return) {
|
||||
if (in_config.isEnabled.has_value()) {
|
||||
mScoConfig.isEnabled = in_config.isEnabled;
|
||||
}
|
||||
if (in_config.isNrecEnabled.has_value()) {
|
||||
mScoConfig.isNrecEnabled = in_config.isNrecEnabled;
|
||||
}
|
||||
if (in_config.mode != ScoConfig::Mode::UNSPECIFIED) {
|
||||
mScoConfig.mode = in_config.mode;
|
||||
}
|
||||
if (in_config.debugName.has_value()) {
|
||||
mScoConfig.debugName = in_config.debugName;
|
||||
}
|
||||
*_aidl_return = mScoConfig;
|
||||
LOG(DEBUG) << __func__ << ": received " << in_config.toString() << ", returning "
|
||||
<< _aidl_return->toString();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Bluetooth::setHfpConfig(const HfpConfig& in_config, HfpConfig* _aidl_return) {
|
||||
if (in_config.sampleRate.has_value() && in_config.sampleRate.value().value <= 0) {
|
||||
LOG(ERROR) << __func__ << ": invalid sample rate: " << in_config.sampleRate.value().value;
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
}
|
||||
if (in_config.volume.has_value() && (in_config.volume.value().value < HfpConfig::VOLUME_MIN ||
|
||||
in_config.volume.value().value > HfpConfig::VOLUME_MAX)) {
|
||||
LOG(ERROR) << __func__ << ": invalid volume: " << in_config.volume.value().value;
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
}
|
||||
|
||||
if (in_config.isEnabled.has_value()) {
|
||||
mHfpConfig.isEnabled = in_config.isEnabled;
|
||||
}
|
||||
if (in_config.sampleRate.has_value()) {
|
||||
mHfpConfig.sampleRate = in_config.sampleRate;
|
||||
}
|
||||
if (in_config.volume.has_value()) {
|
||||
mHfpConfig.volume = in_config.volume;
|
||||
}
|
||||
*_aidl_return = mHfpConfig;
|
||||
LOG(DEBUG) << __func__ << ": received " << in_config.toString() << ", returning "
|
||||
<< _aidl_return->toString();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::audio::core
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <aidl/android/media/audio/common/AudioInputFlags.h>
|
||||
#include <aidl/android/media/audio/common/AudioOutputFlags.h>
|
||||
|
||||
#include "core-impl/Bluetooth.h"
|
||||
#include "core-impl/Module.h"
|
||||
#include "core-impl/SoundDose.h"
|
||||
#include "core-impl/Telephony.h"
|
||||
@@ -326,6 +327,18 @@ ndk::ScopedAStatus Module::getTelephony(std::shared_ptr<ITelephony>* _aidl_retur
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) {
|
||||
if (mBluetooth == nullptr) {
|
||||
mBluetooth = ndk::SharedRefBase::make<Bluetooth>();
|
||||
mBluetoothBinder = mBluetooth->asBinder();
|
||||
AIBinder_setMinSchedulerPolicy(mBluetoothBinder.get(), SCHED_NORMAL,
|
||||
ANDROID_PRIORITY_AUDIO);
|
||||
}
|
||||
*_aidl_return = mBluetooth;
|
||||
LOG(DEBUG) << __func__ << ": returning instance of IBluetooth: " << _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;
|
||||
|
||||
35
audio/aidl/default/include/core-impl/Bluetooth.h
Normal file
35
audio/aidl/default/include/core-impl/Bluetooth.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <aidl/android/hardware/audio/core/BnBluetooth.h>
|
||||
|
||||
namespace aidl::android::hardware::audio::core {
|
||||
|
||||
class Bluetooth : public BnBluetooth {
|
||||
public:
|
||||
Bluetooth();
|
||||
|
||||
private:
|
||||
ndk::ScopedAStatus setScoConfig(const ScoConfig& in_config, ScoConfig* _aidl_return) override;
|
||||
ndk::ScopedAStatus setHfpConfig(const HfpConfig& in_config, HfpConfig* _aidl_return) override;
|
||||
|
||||
ScoConfig mScoConfig;
|
||||
HfpConfig mHfpConfig;
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::audio::core
|
||||
@@ -39,6 +39,7 @@ class Module : public BnModule {
|
||||
ndk::ScopedAStatus setModuleDebug(
|
||||
const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) override;
|
||||
ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
|
||||
ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override;
|
||||
ndk::ScopedAStatus connectExternalDevice(
|
||||
const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData,
|
||||
::aidl::android::media::audio::common::AudioPort* _aidl_return) override;
|
||||
@@ -127,10 +128,12 @@ class Module : public BnModule {
|
||||
const Type mType;
|
||||
std::unique_ptr<internal::Configuration> mConfig;
|
||||
ModuleDebug mDebug;
|
||||
// Since it is required to return the same instance of the ITelephony, even
|
||||
// if the client has released it on its side, we need to hold it via a strong pointer.
|
||||
// For the interfaces requiring to return the same instance, we need to hold them
|
||||
// via a strong pointer. The binder token is retained for a call to 'setMinSchedulerPolicy'.
|
||||
std::shared_ptr<ITelephony> mTelephony;
|
||||
ndk::SpAIBinder mTelephonyBinder;
|
||||
std::shared_ptr<IBluetooth> mBluetooth;
|
||||
ndk::SpAIBinder mBluetoothBinder;
|
||||
// ids of ports created at runtime via 'connectExternalDevice'.
|
||||
std::set<int32_t> mConnectedDevicePorts;
|
||||
Streams mStreams;
|
||||
|
||||
@@ -56,6 +56,7 @@ using aidl::android::hardware::audio::common::SourceMetadata;
|
||||
using aidl::android::hardware::audio::core::AudioMode;
|
||||
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::IModule;
|
||||
using aidl::android::hardware::audio::core::IStreamCommon;
|
||||
using aidl::android::hardware::audio::core::IStreamIn;
|
||||
@@ -85,6 +86,7 @@ using aidl::android::media::audio::common::AudioPortExt;
|
||||
using aidl::android::media::audio::common::AudioSource;
|
||||
using aidl::android::media::audio::common::AudioUsage;
|
||||
using aidl::android::media::audio::common::Float;
|
||||
using aidl::android::media::audio::common::Int;
|
||||
using aidl::android::media::audio::common::Void;
|
||||
using android::hardware::audio::common::getChannelCount;
|
||||
using android::hardware::audio::common::isBitPositionFlagSet;
|
||||
@@ -1776,6 +1778,89 @@ TEST_P(AudioCoreModule, AddRemoveEffectInvalidArguments) {
|
||||
}
|
||||
}
|
||||
|
||||
class AudioCoreBluetooth : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam()));
|
||||
ASSERT_IS_OK(module->getBluetooth(&bluetooth));
|
||||
}
|
||||
|
||||
void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
|
||||
|
||||
std::shared_ptr<IBluetooth> bluetooth;
|
||||
};
|
||||
|
||||
TEST_P(AudioCoreBluetooth, SameInstance) {
|
||||
if (bluetooth == nullptr) {
|
||||
GTEST_SKIP() << "Bluetooth is not supported";
|
||||
}
|
||||
std::shared_ptr<IBluetooth> bluetooth2;
|
||||
EXPECT_IS_OK(module->getBluetooth(&bluetooth2));
|
||||
ASSERT_NE(nullptr, bluetooth2.get());
|
||||
EXPECT_EQ(bluetooth->asBinder(), bluetooth2->asBinder())
|
||||
<< "getBluetooth must return the same interface instance across invocations";
|
||||
}
|
||||
|
||||
TEST_P(AudioCoreBluetooth, ScoConfig) {
|
||||
static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
|
||||
if (bluetooth == nullptr) {
|
||||
GTEST_SKIP() << "Bluetooth is not supported";
|
||||
}
|
||||
ndk::ScopedAStatus status;
|
||||
IBluetooth::ScoConfig scoConfig;
|
||||
ASSERT_STATUS(kStatuses, status = bluetooth->setScoConfig({}, &scoConfig));
|
||||
if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
|
||||
GTEST_SKIP() << "BT SCO is not supported";
|
||||
}
|
||||
EXPECT_TRUE(scoConfig.isEnabled.has_value());
|
||||
EXPECT_TRUE(scoConfig.isNrecEnabled.has_value());
|
||||
EXPECT_NE(IBluetooth::ScoConfig::Mode::UNSPECIFIED, scoConfig.mode);
|
||||
IBluetooth::ScoConfig scoConfig2;
|
||||
ASSERT_IS_OK(bluetooth->setScoConfig(scoConfig, &scoConfig2));
|
||||
EXPECT_EQ(scoConfig, scoConfig2);
|
||||
}
|
||||
|
||||
TEST_P(AudioCoreBluetooth, HfpConfig) {
|
||||
static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
|
||||
if (bluetooth == nullptr) {
|
||||
GTEST_SKIP() << "Bluetooth is not supported";
|
||||
}
|
||||
ndk::ScopedAStatus status;
|
||||
IBluetooth::HfpConfig hfpConfig;
|
||||
ASSERT_STATUS(kStatuses, status = bluetooth->setHfpConfig({}, &hfpConfig));
|
||||
if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
|
||||
GTEST_SKIP() << "BT HFP is not supported";
|
||||
}
|
||||
EXPECT_TRUE(hfpConfig.isEnabled.has_value());
|
||||
EXPECT_TRUE(hfpConfig.sampleRate.has_value());
|
||||
EXPECT_TRUE(hfpConfig.volume.has_value());
|
||||
IBluetooth::HfpConfig hfpConfig2;
|
||||
ASSERT_IS_OK(bluetooth->setHfpConfig(hfpConfig, &hfpConfig2));
|
||||
EXPECT_EQ(hfpConfig, hfpConfig2);
|
||||
}
|
||||
|
||||
TEST_P(AudioCoreBluetooth, HfpConfigInvalid) {
|
||||
static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
|
||||
if (bluetooth == nullptr) {
|
||||
GTEST_SKIP() << "Bluetooth is not supported";
|
||||
}
|
||||
ndk::ScopedAStatus status;
|
||||
IBluetooth::HfpConfig hfpConfig;
|
||||
ASSERT_STATUS(kStatuses, status = bluetooth->setHfpConfig({}, &hfpConfig));
|
||||
if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
|
||||
GTEST_SKIP() << "BT HFP is not supported";
|
||||
}
|
||||
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
|
||||
bluetooth->setHfpConfig({.sampleRate = Int{-1}}, &hfpConfig));
|
||||
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, bluetooth->setHfpConfig({.sampleRate = Int{0}}, &hfpConfig));
|
||||
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
|
||||
bluetooth->setHfpConfig({.volume = Float{IBluetooth::HfpConfig::VOLUME_MIN - 1}},
|
||||
&hfpConfig));
|
||||
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
|
||||
bluetooth->setHfpConfig({.volume = Float{IBluetooth::HfpConfig::VOLUME_MAX + 1}},
|
||||
&hfpConfig));
|
||||
}
|
||||
|
||||
class AudioCoreTelephony : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
@@ -1788,6 +1873,17 @@ class AudioCoreTelephony : public AudioCoreModuleBase, public testing::TestWithP
|
||||
std::shared_ptr<ITelephony> telephony;
|
||||
};
|
||||
|
||||
TEST_P(AudioCoreTelephony, SameInstance) {
|
||||
if (telephony == nullptr) {
|
||||
GTEST_SKIP() << "Telephony is not supported";
|
||||
}
|
||||
std::shared_ptr<ITelephony> telephony2;
|
||||
EXPECT_IS_OK(module->getTelephony(&telephony2));
|
||||
ASSERT_NE(nullptr, telephony2.get());
|
||||
EXPECT_EQ(telephony->asBinder(), telephony2->asBinder())
|
||||
<< "getTelephony must return the same interface instance across invocations";
|
||||
}
|
||||
|
||||
TEST_P(AudioCoreTelephony, GetSupportedAudioModes) {
|
||||
if (telephony == nullptr) {
|
||||
GTEST_SKIP() << "Telephony is not supported";
|
||||
@@ -3039,6 +3135,17 @@ ndk::ScopedAStatus AudioCoreSoundDose::NoOpHalSoundDoseCallback::onNewMelValues(
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
TEST_P(AudioCoreSoundDose, SameInstance) {
|
||||
if (soundDose == nullptr) {
|
||||
GTEST_SKIP() << "SoundDose is not supported";
|
||||
}
|
||||
std::shared_ptr<ISoundDose> soundDose2;
|
||||
EXPECT_IS_OK(module->getSoundDose(&soundDose2));
|
||||
ASSERT_NE(nullptr, soundDose2.get());
|
||||
EXPECT_EQ(soundDose->asBinder(), soundDose2->asBinder())
|
||||
<< "getSoundDose must return the same interface instance across invocations";
|
||||
}
|
||||
|
||||
TEST_P(AudioCoreSoundDose, GetSetOutputRs2) {
|
||||
if (soundDose == nullptr) {
|
||||
GTEST_SKIP() << "SoundDose is not supported";
|
||||
@@ -3085,6 +3192,10 @@ INSTANTIATE_TEST_SUITE_P(AudioCoreModuleTest, AudioCoreModule,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreModule);
|
||||
INSTANTIATE_TEST_SUITE_P(AudioCoreBluetoothTest, AudioCoreBluetooth,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreBluetooth);
|
||||
INSTANTIATE_TEST_SUITE_P(AudioCoreTelephonyTest, AudioCoreTelephony,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
||||
|
||||
Reference in New Issue
Block a user