Merge "Create secretkeeper HAL APEX" into main
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
index bcbf870..046c220 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
@@ -43,6 +43,8 @@
boolean audioModeIndication;
boolean audioSourceIndication;
boolean bypass;
+ boolean sinkMetadataIndication;
+ boolean sourceMetadataIndication;
@Backing(type="byte") @VintfStability
enum Type {
INSERT = 0,
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
index 7313b57..ff33c42 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
@@ -41,6 +41,8 @@
boolean offload;
android.hardware.audio.effect.Parameter.VolumeStereo volumeStereo;
android.hardware.audio.effect.Parameter.Specific specific;
+ android.hardware.audio.common.SinkMetadata sinkMetadata;
+ android.hardware.audio.common.SourceMetadata sourceMetadata;
@VintfStability
union Id {
android.hardware.audio.effect.VendorExtension vendorEffectTag;
diff --git a/audio/aidl/android/hardware/audio/effect/Flags.aidl b/audio/aidl/android/hardware/audio/effect/Flags.aidl
index 28685c3..70668a3 100644
--- a/audio/aidl/android/hardware/audio/effect/Flags.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Flags.aidl
@@ -144,4 +144,18 @@
* Set to true if the effect instance bypass audio data (no processing).
*/
boolean bypass;
+
+ /**
+ * Effect instance sets this flag to true if it requires record AudioTrack metadata update. In
+ * this case the framework must call IEffect.setParameter to notify effect instance when there
+ * is a change in sinkMetadata.
+ */
+ boolean sinkMetadataIndication;
+
+ /**
+ * Effect instance sets this flag to true if it requires playback AudioTrack metadata update. In
+ * this case the framework must call IEffect.setParameter to notify effect instance when there
+ * is a change in sourceMetadata.
+ */
+ boolean sourceMetadataIndication;
}
diff --git a/audio/aidl/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
index 6ec7226..6fd9161 100644
--- a/audio/aidl/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
@@ -16,6 +16,8 @@
package android.hardware.audio.effect;
+import android.hardware.audio.common.SinkMetadata;
+import android.hardware.audio.common.SourceMetadata;
import android.hardware.audio.effect.AcousticEchoCanceler;
import android.hardware.audio.effect.AutomaticGainControlV1;
import android.hardware.audio.effect.AutomaticGainControlV2;
@@ -198,4 +200,20 @@
Spatializer spatializer;
}
Specific specific;
+
+ /**
+ * SinkMetadata defines the metadata of record AudioTracks which the effect instance associate
+ * with.
+ * The effect engine is required to set Flags.sinkMetadataIndication to true if it wants to
+ * receive sinkMetadata update from the audio framework.
+ */
+ SinkMetadata sinkMetadata;
+
+ /**
+ * SourceMetadata defines the metadata of playback AudioTracks which the effect instance
+ * associate with.
+ * The effect engine is required to set Flags.sourceMetadataIndication to true if it wants to
+ * receive sourceMetadata update from the audio framework.
+ */
+ SourceMetadata sourceMetadata;
}
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 7b96293..949b654 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -94,6 +94,7 @@
"audio_policy_engine_configuration_aidl_default",
],
shared_libs: [
+ "android.hardware.bluetooth.audio-impl",
"libaudio_aidl_conversion_common_ndk",
"libbluetooth_audio_session_aidl",
"libmedia_helper",
@@ -127,6 +128,7 @@
"libaudioserviceexampleimpl",
],
shared_libs: [
+ "android.hardware.bluetooth.audio-impl",
"libaudio_aidl_conversion_common_ndk",
"libbluetooth_audio_session_aidl",
"libmedia_helper",
diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp
index 254eb46..d63e353 100644
--- a/audio/aidl/default/Configuration.cpp
+++ b/audio/aidl/default/Configuration.cpp
@@ -320,9 +320,9 @@
// - no profiles specified
//
// Mix ports:
-// * "r_submix output", maximum 20 opened streams, maximum 10 active streams
+// * "r_submix output", maximum 10 opened streams, maximum 10 active streams
// - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
-// * "r_submix input", maximum 20 opened streams, maximum 10 active streams
+// * "r_submix input", maximum 10 opened streams, maximum 10 active streams
// - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
//
// Routes:
@@ -355,12 +355,12 @@
// Mix ports
AudioPort rsubmixOutMix =
- createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(20, 10));
+ createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(10, 10));
rsubmixOutMix.profiles = remoteSubmixPcmAudioProfiles;
c.ports.push_back(rsubmixOutMix);
AudioPort rsubmixInMix =
- createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(20, 10));
+ createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(10, 10));
rsubmixInMix.profiles = remoteSubmixPcmAudioProfiles;
c.ports.push_back(rsubmixInMix);
diff --git a/audio/aidl/default/XsdcConversion.cpp b/audio/aidl/default/XsdcConversion.cpp
index 9e30347..1720949 100644
--- a/audio/aidl/default/XsdcConversion.cpp
+++ b/audio/aidl/default/XsdcConversion.cpp
@@ -205,24 +205,28 @@
ConversionResult<AudioIoFlags> convertIoFlagsToAidl(
const std::vector<ap_xsd::AudioInOutFlag>& flags, const ap_xsd::Role role,
bool flagsForMixPort) {
- int flagMask = 0;
+ int legacyFlagMask = 0;
if ((role == ap_xsd::Role::sink && flagsForMixPort) ||
(role == ap_xsd::Role::source && !flagsForMixPort)) {
for (const ap_xsd::AudioInOutFlag& flag : flags) {
audio_input_flags_t legacyFlag;
if (::android::InputFlagConverter::fromString(ap_xsd::toString(flag), legacyFlag)) {
- flagMask |= static_cast<int>(legacyFlag);
+ legacyFlagMask |= static_cast<int>(legacyFlag);
}
}
- return AudioIoFlags::make<AudioIoFlags::Tag::input>(flagMask);
+ return AudioIoFlags::make<AudioIoFlags::Tag::input>(
+ VALUE_OR_FATAL(legacy2aidl_audio_input_flags_t_int32_t_mask(
+ static_cast<audio_input_flags_t>(legacyFlagMask))));
} else {
for (const ap_xsd::AudioInOutFlag& flag : flags) {
audio_output_flags_t legacyFlag;
if (::android::OutputFlagConverter::fromString(ap_xsd::toString(flag), legacyFlag)) {
- flagMask |= static_cast<int>(legacyFlag);
+ legacyFlagMask |= static_cast<int>(legacyFlag);
}
}
- return AudioIoFlags::make<AudioIoFlags::Tag::output>(flagMask);
+ return AudioIoFlags::make<AudioIoFlags::Tag::output>(
+ VALUE_OR_FATAL(legacy2aidl_audio_output_flags_t_int32_t_mask(
+ static_cast<audio_output_flags_t>(legacyFlagMask))));
}
}
diff --git a/audio/aidl/default/bluetooth/ModuleBluetooth.cpp b/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
index 502b153..8a1cbbf 100644
--- a/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
+++ b/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
@@ -33,8 +33,23 @@
using android::bluetooth::audio::aidl::BluetoothAudioPortAidl;
using android::bluetooth::audio::aidl::BluetoothAudioPortAidlOut;
+// TODO(b/312265159) bluetooth audio should be in its own process
+// Remove this and the shared_libs when that happens
+extern "C" binder_status_t createIBluetoothAudioProviderFactory();
+
namespace aidl::android::hardware::audio::core {
+ModuleBluetooth::ModuleBluetooth(std::unique_ptr<Module::Configuration>&& config)
+ : Module(Type::BLUETOOTH, std::move(config)) {
+ // TODO(b/312265159) bluetooth audio should be in its own process
+ // Remove this and the shared_libs when that happens
+ binder_status_t status = createIBluetoothAudioProviderFactory();
+ if (status != STATUS_OK) {
+ LOG(ERROR) << "Failed to create bluetooth audio provider factory. Status: "
+ << ::android::statusToString(status);
+ }
+}
+
ndk::ScopedAStatus ModuleBluetooth::getBluetoothA2dp(
std::shared_ptr<IBluetoothA2dp>* _aidl_return) {
*_aidl_return = getBtA2dp().getInstance();
diff --git a/audio/aidl/default/include/core-impl/ModuleBluetooth.h b/audio/aidl/default/include/core-impl/ModuleBluetooth.h
index a58798b..631b088 100644
--- a/audio/aidl/default/include/core-impl/ModuleBluetooth.h
+++ b/audio/aidl/default/include/core-impl/ModuleBluetooth.h
@@ -28,8 +28,7 @@
std::weak_ptr<IBluetoothLe>>
BtProfileHandles;
- ModuleBluetooth(std::unique_ptr<Configuration>&& config)
- : Module(Type::BLUETOOTH, std::move(config)) {}
+ ModuleBluetooth(std::unique_ptr<Configuration>&& config);
private:
ChildInterface<BluetoothA2dp>& getBtA2dp();
diff --git a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
index 21592b3..ee10abf 100644
--- a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
@@ -71,6 +71,10 @@
static constexpr int kMaxReadFailureAttempts = 3;
// 5ms between two read attempts when pipe is empty
static constexpr int kReadAttemptSleepUs = 5000;
+
+ long mStartTimeNs = 0;
+ long mFramesSinceStart = 0;
+ int mReadErrorCount = 0;
};
class StreamInRemoteSubmix final : public StreamIn, public StreamSwitcher {
diff --git a/audio/aidl/default/primary/StreamPrimary.cpp b/audio/aidl/default/primary/StreamPrimary.cpp
index b22ef32..7325a91 100644
--- a/audio/aidl/default/primary/StreamPrimary.cpp
+++ b/audio/aidl/default/primary/StreamPrimary.cpp
@@ -116,8 +116,8 @@
GetBoolProperty("ro.boot.audio.tinyalsa.simulate_input", false);
return kSimulateInput || device.type.type == AudioDeviceType::IN_TELEPHONY_RX ||
device.type.type == AudioDeviceType::IN_FM_TUNER ||
- device.type.connection == AudioDeviceDescription::CONNECTION_BUS ||
- (device.type.type == AudioDeviceType::IN_DEVICE && device.type.connection.empty());
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated */ ||
+ (device.type.type == AudioDeviceType::IN_BUS && device.type.connection.empty());
}
StreamSwitcher::DeviceSwitchBehavior StreamInPrimary::switchCurrentStream(
@@ -188,8 +188,8 @@
static const bool kSimulateOutput =
GetBoolProperty("ro.boot.audio.tinyalsa.ignore_output", false);
return kSimulateOutput || device.type.type == AudioDeviceType::OUT_TELEPHONY_TX ||
- device.type.connection == AudioDeviceDescription::CONNECTION_BUS ||
- (device.type.type == AudioDeviceType::OUT_DEVICE && device.type.connection.empty());
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated*/ ||
+ (device.type.type == AudioDeviceType::OUT_BUS && device.type.connection.empty());
}
StreamSwitcher::DeviceSwitchBehavior StreamOutPrimary::switchCurrentStream(
diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
index fc61dcb..6258c93 100644
--- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
@@ -16,6 +16,9 @@
#define LOG_TAG "AHAL_StreamRemoteSubmix"
#include <android-base/logging.h>
+#include <audio_utils/clock.h>
+#include <error/Result.h>
+#include <error/expected_utils.h>
#include "core-impl/StreamRemoteSubmix.h"
@@ -50,37 +53,33 @@
if (routeItr != sSubmixRoutes.end()) {
mCurrentRoute = routeItr->second;
}
- }
- // If route is not available for this port, add it.
- if (mCurrentRoute == nullptr) {
- // Initialize the pipe.
- mCurrentRoute = std::make_shared<SubmixRoute>();
- if (::android::OK != mCurrentRoute->createPipe(mStreamConfig)) {
- LOG(ERROR) << __func__ << ": create pipe failed";
- return ::android::NO_INIT;
- }
- {
- std::lock_guard guard(sSubmixRoutesLock);
- sSubmixRoutes.emplace(mDeviceAddress, mCurrentRoute);
- }
- } else {
- if (!mCurrentRoute->isStreamConfigValid(mIsInput, mStreamConfig)) {
- LOG(ERROR) << __func__ << ": invalid stream config";
- return ::android::NO_INIT;
- }
- sp<MonoPipe> sink = mCurrentRoute->getSink();
- if (sink == nullptr) {
- LOG(ERROR) << __func__ << ": nullptr sink when opening stream";
- return ::android::NO_INIT;
- }
- // If the sink has been shutdown or pipe recreation is forced, delete the pipe and
- // recreate it.
- if (sink->isShutdown()) {
- LOG(DEBUG) << __func__ << ": Non-nullptr shut down sink when opening stream";
- if (::android::OK != mCurrentRoute->resetPipe()) {
- LOG(ERROR) << __func__ << ": reset pipe failed";
+ // If route is not available for this port, add it.
+ if (mCurrentRoute == nullptr) {
+ // Initialize the pipe.
+ mCurrentRoute = std::make_shared<SubmixRoute>();
+ if (::android::OK != mCurrentRoute->createPipe(mStreamConfig)) {
+ LOG(ERROR) << __func__ << ": create pipe failed";
return ::android::NO_INIT;
}
+ sSubmixRoutes.emplace(mDeviceAddress, mCurrentRoute);
+ }
+ }
+ if (!mCurrentRoute->isStreamConfigValid(mIsInput, mStreamConfig)) {
+ LOG(ERROR) << __func__ << ": invalid stream config";
+ return ::android::NO_INIT;
+ }
+ sp<MonoPipe> sink = mCurrentRoute->getSink();
+ if (sink == nullptr) {
+ LOG(ERROR) << __func__ << ": nullptr sink when opening stream";
+ return ::android::NO_INIT;
+ }
+ // If the sink has been shutdown or pipe recreation is forced, delete the pipe and
+ // recreate it.
+ if (sink->isShutdown()) {
+ LOG(DEBUG) << __func__ << ": Non-nullptr shut down sink when opening stream";
+ if (::android::OK != mCurrentRoute->resetPipe()) {
+ LOG(ERROR) << __func__ << ": reset pipe failed";
+ return ::android::NO_INIT;
}
}
@@ -110,6 +109,8 @@
::android::status_t StreamRemoteSubmix::start() {
mCurrentRoute->exitStandby(mIsInput);
+ mStartTimeNs = ::android::uptimeNanos();
+ mFramesSinceStart = 0;
return ::android::OK;
}
@@ -161,8 +162,21 @@
*latencyMs = getDelayInUsForFrameCount(getStreamPipeSizeInFrames()) / 1000;
LOG(VERBOSE) << __func__ << ": Latency " << *latencyMs << "ms";
mCurrentRoute->exitStandby(mIsInput);
- return (mIsInput ? inRead(buffer, frameCount, actualFrameCount)
- : outWrite(buffer, frameCount, actualFrameCount));
+ RETURN_STATUS_IF_ERROR(mIsInput ? inRead(buffer, frameCount, actualFrameCount)
+ : outWrite(buffer, frameCount, actualFrameCount));
+ const long bufferDurationUs =
+ (*actualFrameCount) * MICROS_PER_SECOND / mContext.getSampleRate();
+ const long totalDurationUs = (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
+ mFramesSinceStart += *actualFrameCount;
+ const long totalOffsetUs =
+ mFramesSinceStart * MICROS_PER_SECOND / mContext.getSampleRate() - totalDurationUs;
+ LOG(VERBOSE) << __func__ << ": totalOffsetUs " << totalOffsetUs;
+ if (totalOffsetUs > 0) {
+ const long sleepTimeUs = std::min(totalOffsetUs, bufferDurationUs);
+ LOG(VERBOSE) << __func__ << ": sleeping for " << sleepTimeUs << " us";
+ usleep(sleepTimeUs);
+ }
+ return ::android::OK;
}
::android::status_t StreamRemoteSubmix::refinePosition(StreamDescriptor::Position* position) {
@@ -200,12 +214,7 @@
if (sink != nullptr) {
if (sink->isShutdown()) {
sink.clear();
- const auto delayUs = getDelayInUsForFrameCount(frameCount);
- LOG(DEBUG) << __func__ << ": pipe shutdown, ignoring the write, sleeping for "
- << delayUs << " us";
- // the pipe has already been shutdown, this buffer will be lost but we must
- // simulate timing so we don't drain the output faster than realtime
- usleep(delayUs);
+ LOG(DEBUG) << __func__ << ": pipe shutdown, ignoring the write";
*actualFrameCount = frameCount;
return ::android::OK;
}
@@ -214,6 +223,9 @@
return ::android::UNKNOWN_ERROR;
}
+ LOG(VERBOSE) << __func__ << ": " << mDeviceAddress.toString() << ", " << frameCount
+ << " frames";
+
const bool shouldBlockWrite = mCurrentRoute->shouldBlockWrite();
size_t availableToWrite = sink->availableToWrite();
// NOTE: sink has been checked above and sink and source life cycles are synchronized
@@ -236,6 +248,8 @@
availableToWrite = sink->availableToWrite();
if (!shouldBlockWrite && frameCount > availableToWrite) {
+ LOG(WARNING) << __func__ << ": writing " << availableToWrite << " vs. requested "
+ << frameCount;
// Truncate the request to avoid blocking.
frameCount = availableToWrite;
}
@@ -258,92 +272,59 @@
*actualFrameCount = 0;
return ::android::UNKNOWN_ERROR;
}
- LOG(VERBOSE) << __func__ << ": wrote " << writtenFrames << "frames";
+ if (writtenFrames > 0 && frameCount > (size_t)writtenFrames) {
+ LOG(WARNING) << __func__ << ": wrote " << writtenFrames << " vs. requested " << frameCount;
+ }
*actualFrameCount = writtenFrames;
return ::android::OK;
}
::android::status_t StreamRemoteSubmix::inRead(void* buffer, size_t frameCount,
size_t* actualFrameCount) {
+ // in any case, it is emulated that data for the entire buffer was available
+ memset(buffer, 0, mStreamConfig.frameSize * frameCount);
+ *actualFrameCount = frameCount;
+
// about to read from audio source
sp<MonoPipeReader> source = mCurrentRoute->getSource();
if (source == nullptr) {
- int readErrorCount = mCurrentRoute->notifyReadError();
- if (readErrorCount < kMaxReadErrorLogs) {
+ if (++mReadErrorCount < kMaxReadErrorLogs) {
LOG(ERROR) << __func__
<< ": no audio pipe yet we're trying to read! (not all errors will be "
"logged)";
- } else {
- LOG(ERROR) << __func__ << ": Read errors " << readErrorCount;
}
- const auto delayUs = getDelayInUsForFrameCount(frameCount);
- LOG(DEBUG) << __func__ << ": no source, ignoring the read, sleeping for " << delayUs
- << " us";
- usleep(delayUs);
- memset(buffer, 0, mStreamConfig.frameSize * frameCount);
- *actualFrameCount = frameCount;
return ::android::OK;
}
+ LOG(VERBOSE) << __func__ << ": " << mDeviceAddress.toString() << ", " << frameCount
+ << " frames";
// read the data from the pipe
- int attempts = 0;
- const long delayUs = kReadAttemptSleepUs;
char* buff = (char*)buffer;
- size_t remainingFrames = frameCount;
- int availableToRead = source->availableToRead();
-
- while ((remainingFrames > 0) && (availableToRead > 0) && (attempts < kMaxReadFailureAttempts)) {
- LOG(VERBOSE) << __func__ << ": frames available to read " << availableToRead;
-
+ size_t actuallyRead = 0;
+ long remainingFrames = frameCount;
+ const long deadlineTimeNs = ::android::uptimeNanos() +
+ getDelayInUsForFrameCount(frameCount) * NANOS_PER_MICROSECOND;
+ while (remainingFrames > 0) {
ssize_t framesRead = source->read(buff, remainingFrames);
-
LOG(VERBOSE) << __func__ << ": frames read " << framesRead;
-
if (framesRead > 0) {
remainingFrames -= framesRead;
buff += framesRead * mStreamConfig.frameSize;
- availableToRead -= framesRead;
- LOG(VERBOSE) << __func__ << ": (attempts = " << attempts << ") got " << framesRead
+ LOG(VERBOSE) << __func__ << ": got " << framesRead
<< " frames, remaining =" << remainingFrames;
- } else {
- attempts++;
- LOG(WARNING) << __func__ << ": read returned " << framesRead
- << " , read failure attempts = " << attempts << ", sleeping for "
- << delayUs << " us";
- usleep(delayUs);
+ actuallyRead += framesRead;
+ }
+ if (::android::uptimeNanos() >= deadlineTimeNs) break;
+ if (framesRead <= 0) {
+ LOG(VERBOSE) << __func__ << ": read returned " << framesRead
+ << ", read failure, sleeping for " << kReadAttemptSleepUs << " us";
+ usleep(kReadAttemptSleepUs);
}
}
- // done using the source
- source.clear();
-
- if (remainingFrames > 0) {
- const size_t remainingBytes = remainingFrames * mStreamConfig.frameSize;
- LOG(VERBOSE) << __func__ << ": clearing remaining_frames = " << remainingFrames;
- memset(((char*)buffer) + (mStreamConfig.frameSize * frameCount) - remainingBytes, 0,
- remainingBytes);
+ if (actuallyRead < frameCount) {
+ LOG(WARNING) << __func__ << ": read " << actuallyRead << " vs. requested " << frameCount;
}
-
- long readCounterFrames = mCurrentRoute->updateReadCounterFrames(frameCount);
- *actualFrameCount = frameCount;
-
- // compute how much we need to sleep after reading the data by comparing the wall clock with
- // the projected time at which we should return.
- // wall clock after reading from the pipe
- auto recordDurationUs = std::chrono::duration_cast<std::chrono::microseconds>(
- std::chrono::steady_clock::now() - mCurrentRoute->getRecordStartTime());
-
- // readCounterFrames contains the number of frames that have been read since the beginning of
- // recording (including this call): it's converted to usec and compared to how long we've been
- // recording for, which gives us how long we must wait to sync the projected recording time, and
- // the observed recording time.
- const long projectedVsObservedOffsetUs =
- getDelayInUsForFrameCount(readCounterFrames) - recordDurationUs.count();
-
- LOG(VERBOSE) << __func__ << ": record duration " << recordDurationUs.count()
- << " us, will wait: " << projectedVsObservedOffsetUs << " us";
- if (projectedVsObservedOffsetUs > 0) {
- usleep(projectedVsObservedOffsetUs);
- }
+ mCurrentRoute->updateReadCounterFrames(*actualFrameCount);
return ::android::OK;
}
diff --git a/audio/aidl/default/r_submix/SubmixRoute.cpp b/audio/aidl/default/r_submix/SubmixRoute.cpp
index ddac64d..f04e607 100644
--- a/audio/aidl/default/r_submix/SubmixRoute.cpp
+++ b/audio/aidl/default/r_submix/SubmixRoute.cpp
@@ -81,11 +81,6 @@
return (mStreamInOpen || (mStreamInStandby && (mReadCounterFrames != 0)));
}
-int SubmixRoute::notifyReadError() {
- std::lock_guard guard(mLock);
- return ++mReadErrorCount;
-}
-
long SubmixRoute::updateReadCounterFrames(size_t frameCount) {
std::lock_guard guard(mLock);
mReadCounterFrames += frameCount;
@@ -103,7 +98,6 @@
}
mStreamInStandby = true;
mReadCounterFrames = 0;
- mReadErrorCount = 0;
} else {
mStreamOutOpen = true;
}
@@ -214,9 +208,6 @@
if (mStreamInStandby || mStreamOutStandbyTransition) {
mStreamInStandby = false;
mStreamOutStandbyTransition = false;
- // keep track of when we exit input standby (== first read == start "real recording")
- // or when we start recording silence, and reset projected time
- mRecordStartTime = std::chrono::steady_clock::now();
mReadCounterFrames = 0;
}
} else {
diff --git a/audio/aidl/default/r_submix/SubmixRoute.h b/audio/aidl/default/r_submix/SubmixRoute.h
index 92b95e9..252b1c9 100644
--- a/audio/aidl/default/r_submix/SubmixRoute.h
+++ b/audio/aidl/default/r_submix/SubmixRoute.h
@@ -16,7 +16,6 @@
#pragma once
-#include <chrono>
#include <mutex>
#include <android-base/thread_annotations.h>
@@ -83,14 +82,6 @@
std::lock_guard guard(mLock);
return mReadCounterFrames;
}
- int getReadErrorCount() {
- std::lock_guard guard(mLock);
- return mReadErrorCount;
- }
- std::chrono::time_point<std::chrono::steady_clock> getRecordStartTime() {
- std::lock_guard guard(mLock);
- return mRecordStartTime;
- }
sp<MonoPipe> getSink() {
std::lock_guard guard(mLock);
return mSink;
@@ -126,9 +117,6 @@
bool mStreamOutStandby GUARDED_BY(mLock) = true;
// how many frames have been requested to be read since standby
long mReadCounterFrames GUARDED_BY(mLock) = 0;
- int mReadErrorCount GUARDED_BY(mLock) = 0;
- // wall clock when recording starts
- std::chrono::time_point<std::chrono::steady_clock> mRecordStartTime GUARDED_BY(mLock);
// Pipe variables: they handle the ring buffer that "pipes" audio:
// - from the submix virtual audio output == what needs to be played
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index ad816c7..191f928 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -86,6 +86,9 @@
name: "VtsHalDownmixTargetTest",
defaults: ["VtsHalAudioTargetTestDefaults"],
srcs: ["VtsHalDownmixTargetTest.cpp"],
+ shared_libs: [
+ "libaudioutils",
+ ],
}
cc_test {
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 2c8edf2..d813554 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -283,4 +283,32 @@
}
return functor(result);
}
+
+ static void processAndWriteToOutput(std::vector<float>& inputBuffer,
+ std::vector<float>& outputBuffer,
+ const std::shared_ptr<IEffect>& mEffect,
+ IEffect::OpenEffectReturn* mOpenEffectReturn) {
+ // Initialize AidlMessagequeues
+ auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(mOpenEffectReturn->statusMQ);
+ ASSERT_TRUE(statusMQ->isValid());
+ auto inputMQ = std::make_unique<EffectHelper::DataMQ>(mOpenEffectReturn->inputDataMQ);
+ ASSERT_TRUE(inputMQ->isValid());
+ auto outputMQ = std::make_unique<EffectHelper::DataMQ>(mOpenEffectReturn->outputDataMQ);
+ ASSERT_TRUE(outputMQ->isValid());
+
+ // Enabling the process
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+ // Write from buffer to message queues and calling process
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer));
+
+ // Read the updated message queues into buffer
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 1, outputMQ,
+ outputBuffer.size(), outputBuffer));
+
+ // Disable the process
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+ }
};
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
index c01a9a2..d7db567 100644
--- a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -18,88 +18,114 @@
#define LOG_TAG "VtsHalDownmixTargetTest"
#include <android-base/logging.h>
+#include <audio_utils/ChannelMix.h>
#include "EffectHelper.h"
using namespace android;
+using aidl::android::hardware::audio::common::getChannelCount;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::Downmix;
using aidl::android::hardware::audio::effect::getEffectTypeUuidDownmix;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::IFactory;
using aidl::android::hardware::audio::effect::Parameter;
+using android::audio_utils::channels::ChannelMix;
using android::hardware::audio::common::testing::detail::TestExecutionTracer;
-/**
- * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
- * VtsAudioEffectTargetTest.
- */
-enum ParamName { PARAM_INSTANCE_NAME, PARAM_TYPE };
-using DownmixParamTestParam =
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, Downmix::Type>;
// Testing for enum values
-const std::vector<Downmix::Type> kTypeValues = {Downmix::Type::STRIP, Downmix::Type::FOLD};
+static const std::vector<Downmix::Type> kTypeValues = {ndk::enum_range<Downmix::Type>().begin(),
+ ndk::enum_range<Downmix::Type>().end()};
-class DownmixParamTest : public ::testing::TestWithParam<DownmixParamTestParam>,
- public EffectHelper {
+// Testing for supported layouts from AudioChannelLayout.h
+static const std::vector<int32_t> kLayoutValues = {
+ AudioChannelLayout::LAYOUT_STEREO, AudioChannelLayout::LAYOUT_2POINT1,
+ AudioChannelLayout::LAYOUT_TRI, AudioChannelLayout::LAYOUT_TRI_BACK,
+ AudioChannelLayout::LAYOUT_3POINT1, AudioChannelLayout::LAYOUT_2POINT0POINT2,
+ AudioChannelLayout::LAYOUT_2POINT1POINT2, AudioChannelLayout::LAYOUT_3POINT0POINT2,
+ AudioChannelLayout::LAYOUT_3POINT1POINT2, AudioChannelLayout::LAYOUT_QUAD,
+ AudioChannelLayout::LAYOUT_QUAD_SIDE, AudioChannelLayout::LAYOUT_SURROUND,
+ AudioChannelLayout::LAYOUT_PENTA, AudioChannelLayout::LAYOUT_5POINT1,
+ AudioChannelLayout::LAYOUT_5POINT1_SIDE, AudioChannelLayout::LAYOUT_5POINT1POINT2,
+ AudioChannelLayout::LAYOUT_5POINT1POINT4, AudioChannelLayout::LAYOUT_6POINT1,
+ AudioChannelLayout::LAYOUT_7POINT1, AudioChannelLayout::LAYOUT_7POINT1POINT2,
+ AudioChannelLayout::LAYOUT_7POINT1POINT4, AudioChannelLayout::LAYOUT_9POINT1POINT4,
+ AudioChannelLayout::LAYOUT_9POINT1POINT6, AudioChannelLayout::LAYOUT_13POINT_360RA,
+ AudioChannelLayout::LAYOUT_22POINT2};
+
+static const std::vector<int32_t> kChannels = {
+ AudioChannelLayout::CHANNEL_FRONT_LEFT,
+ AudioChannelLayout::CHANNEL_FRONT_RIGHT,
+ AudioChannelLayout::CHANNEL_FRONT_CENTER,
+ AudioChannelLayout::CHANNEL_LOW_FREQUENCY,
+ AudioChannelLayout::CHANNEL_BACK_LEFT,
+ AudioChannelLayout::CHANNEL_BACK_RIGHT,
+ AudioChannelLayout::CHANNEL_BACK_CENTER,
+ AudioChannelLayout::CHANNEL_SIDE_LEFT,
+ AudioChannelLayout::CHANNEL_SIDE_RIGHT,
+ AudioChannelLayout::CHANNEL_FRONT_LEFT_OF_CENTER,
+ AudioChannelLayout::CHANNEL_FRONT_RIGHT_OF_CENTER,
+ AudioChannelLayout::CHANNEL_TOP_CENTER,
+ AudioChannelLayout::CHANNEL_TOP_FRONT_LEFT,
+ AudioChannelLayout::CHANNEL_TOP_FRONT_CENTER,
+ AudioChannelLayout::CHANNEL_TOP_FRONT_RIGHT,
+ AudioChannelLayout::CHANNEL_TOP_BACK_LEFT,
+ AudioChannelLayout::CHANNEL_TOP_BACK_CENTER,
+ AudioChannelLayout::CHANNEL_TOP_BACK_RIGHT,
+ AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT,
+ AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT,
+ AudioChannelLayout::CHANNEL_BOTTOM_FRONT_LEFT,
+ AudioChannelLayout::CHANNEL_BOTTOM_FRONT_CENTER,
+ AudioChannelLayout::CHANNEL_BOTTOM_FRONT_RIGHT,
+ AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2,
+ AudioChannelLayout::CHANNEL_FRONT_WIDE_LEFT,
+ AudioChannelLayout::CHANNEL_FRONT_WIDE_RIGHT,
+};
+
+class DownmixEffectHelper : public EffectHelper {
public:
- DownmixParamTest() : mParamType(std::get<PARAM_TYPE>(GetParam())) {
- std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
- }
-
- void SetUp() override {
+ void SetUpDownmix(int32_t inputBufferLayout = AudioChannelLayout::LAYOUT_STEREO) {
ASSERT_NE(nullptr, mFactory);
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+ AudioChannelLayout inputChannelLayout =
+ AudioChannelLayout::make<AudioChannelLayout::layoutMask>(inputBufferLayout);
+
Parameter::Specific specific = getDefaultParamSpecific();
Parameter::Common common = EffectHelper::createParamCommon(
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
- kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
- IEffect::OpenEffectReturn ret;
- ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+ kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */,
+ inputChannelLayout);
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
ASSERT_NE(nullptr, mEffect);
}
- void TearDown() override {
+ void TearDownDownmix() {
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+ mOpenEffectReturn = IEffect::OpenEffectReturn{};
}
- static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
- std::shared_ptr<IFactory> mFactory;
- std::shared_ptr<IEffect> mEffect;
- Descriptor mDescriptor;
- Downmix::Type mParamType = Downmix::Type::STRIP;
-
- void SetAndGetDownmixParameters() {
- for (auto& it : mTags) {
- auto& tag = it.first;
- auto& dm = it.second;
-
- // set parameter
- Parameter expectParam;
- Parameter::Specific specific;
- specific.set<Parameter::Specific::downmix>(dm);
- expectParam.set<Parameter::specific>(specific);
- // All values are valid, set parameter should succeed
- EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectParam)) << expectParam.toString();
-
- // get parameter
- Parameter getParam;
- Parameter::Id id;
- Downmix::Id dmId;
- dmId.set<Downmix::Id::commonTag>(tag);
- id.set<Parameter::Id::downmixTag>(dmId);
- EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
-
- EXPECT_EQ(expectParam, getParam);
- }
+ Parameter createDownmixParam(Downmix::Type type) {
+ return Parameter::make<Parameter::specific>(
+ Parameter::Specific::make<Parameter::Specific::downmix>(
+ Downmix::make<Downmix::type>(type)));
+ }
+ void setParameters(Downmix::Type type) {
+ // set parameter
+ auto param = createDownmixParam(type);
+ EXPECT_STATUS(EX_NONE, mEffect->setParameter(param)) << param.toString();
}
- void addTypeParam(Downmix::Type type) {
- Downmix dm;
- dm.set<Downmix::type>(type);
- mTags.push_back({Downmix::type, dm});
+ void validateParameters(Downmix::Type type) {
+ auto leId = Downmix::Id::make<Downmix::Id::commonTag>(Downmix::Tag(Downmix::type));
+ auto id = Parameter::Id::make<Parameter::Id::downmixTag>(leId);
+ // get parameter
+ Parameter getParam;
+ EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+ auto expectedParam = createDownmixParam(type);
+ EXPECT_EQ(expectedParam, getParam) << "\nexpectedParam:" << expectedParam.toString()
+ << "\ngetParam:" << getParam.toString();
}
Parameter::Specific getDefaultParamSpecific() {
@@ -108,14 +134,281 @@
return specific;
}
- private:
- std::vector<std::pair<Downmix::Tag, Downmix>> mTags;
- void CleanUp() { mTags.clear(); }
+ void setDataTestParams(int32_t layoutType) {
+ mInputBuffer.resize(kBufferSize);
+ mOutputBuffer.resize(kBufferSize);
+
+ // Get the number of channels used
+ mInputChannelCount = getChannelCount(
+ AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layoutType));
+
+ // In case of downmix, output is always configured to stereo layout.
+ mOutputBufferSize = (mInputBuffer.size() / mInputChannelCount) * kOutputChannelCount;
+ }
+
+ // Generate mInputBuffer values between -kMaxDownmixSample to kMaxDownmixSample
+ void generateInputBuffer(size_t position, bool isStrip) {
+ size_t increment;
+ if (isStrip)
+ // Fill input at all the channels
+ increment = 1;
+ else
+ // Fill input at only one channel
+ increment = mInputChannelCount;
+
+ for (size_t i = position; i < mInputBuffer.size(); i += increment) {
+ mInputBuffer[i] =
+ ((static_cast<float>(std::rand()) / RAND_MAX) * 2 - 1) * kMaxDownmixSample;
+ }
+ }
+
+ bool isLayoutValid(int32_t inputLayout) {
+ if (inputLayout & kMaxChannelMask) {
+ return false;
+ }
+ return true;
+ }
+
+ static constexpr long kInputFrameCount = 100, kOutputFrameCount = 100;
+ std::shared_ptr<IFactory> mFactory;
+ Descriptor mDescriptor;
+ std::shared_ptr<IEffect> mEffect;
+ IEffect::OpenEffectReturn mOpenEffectReturn;
+
+ std::vector<float> mInputBuffer;
+ std::vector<float> mOutputBuffer;
+ size_t mInputChannelCount;
+ size_t mOutputBufferSize;
+ static constexpr size_t kBufferSize = 128;
+ static constexpr float kMaxDownmixSample = 1;
+ static constexpr int kOutputChannelCount = 2;
+ // Mask for layouts greater than MAX_INPUT_CHANNELS_SUPPORTED
+ static constexpr int32_t kMaxChannelMask =
+ ~((1 << ChannelMix<AUDIO_CHANNEL_OUT_STEREO>::MAX_INPUT_CHANNELS_SUPPORTED) - 1);
+};
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_TYPE };
+
+using DownmixParamTestParam =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, Downmix::Type>;
+
+class DownmixParamTest : public ::testing::TestWithParam<DownmixParamTestParam>,
+ public DownmixEffectHelper {
+ public:
+ DownmixParamTest() : mParamType(std::get<PARAM_TYPE>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+ }
+
+ void SetUp() override { SetUpDownmix(); }
+
+ void TearDown() override { TearDownDownmix(); }
+
+ const Downmix::Type mParamType;
};
TEST_P(DownmixParamTest, SetAndGetType) {
- EXPECT_NO_FATAL_FAILURE(addTypeParam(mParamType));
- SetAndGetDownmixParameters();
+ ASSERT_NO_FATAL_FAILURE(setParameters(mParamType));
+ ASSERT_NO_FATAL_FAILURE(validateParameters(mParamType));
+}
+
+enum FoldParamName { FOLD_INSTANCE_NAME, FOLD_INPUT_LAYOUT, FOLD_TEST_CHANNEL };
+
+using DownmixDataTestParamFold =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t>;
+
+class DownmixFoldDataTest : public ::testing::TestWithParam<DownmixDataTestParamFold>,
+ public DownmixEffectHelper {
+ public:
+ DownmixFoldDataTest() : mInputChannelLayout(std::get<FOLD_INPUT_LAYOUT>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<FOLD_INSTANCE_NAME>(GetParam());
+ }
+
+ void SetUp() override {
+ SetUpDownmix(mInputChannelLayout);
+ if (!isLayoutValid(mInputChannelLayout)) {
+ GTEST_SKIP() << "Layout not supported \n";
+ }
+ setDataTestParams(mInputChannelLayout);
+ }
+
+ void TearDown() override { TearDownDownmix(); }
+
+ void checkAtLeft(int32_t position) {
+ for (size_t i = 0, j = position; i < mOutputBufferSize;
+ i += kOutputChannelCount, j += mInputChannelCount) {
+ // Validate Left channel has audio
+ if (mInputBuffer[j] != 0) {
+ ASSERT_NE(mOutputBuffer[i], 0);
+ } else {
+ // No change in output when input is 0
+ ASSERT_EQ(mOutputBuffer[i], mInputBuffer[j]);
+ }
+ // Validate Right channel has no audio
+ ASSERT_EQ(mOutputBuffer[i + 1], 0);
+ }
+ }
+
+ void checkAtRight(int32_t position) {
+ for (size_t i = 0, j = position; i < mOutputBufferSize;
+ i += kOutputChannelCount, j += mInputChannelCount) {
+ // Validate Left channel has no audio
+ ASSERT_EQ(mOutputBuffer[i], 0);
+ // Validate Right channel has audio
+ if (mInputBuffer[j] != 0) {
+ ASSERT_NE(mOutputBuffer[i + 1], 0);
+ } else {
+ // No change in output when input is 0
+ ASSERT_EQ(mOutputBuffer[i + 1], mInputBuffer[j]);
+ }
+ }
+ }
+
+ void checkAtCenter(size_t position) {
+ for (size_t i = 0, j = position; i < mOutputBufferSize;
+ i += kOutputChannelCount, j += mInputChannelCount) {
+ // Validate both channels have audio
+ if (mInputBuffer[j] != 0) {
+ ASSERT_NE(mOutputBuffer[i], 0);
+ ASSERT_NE(mOutputBuffer[i + 1], 0);
+
+ } else {
+ // No change in output when input is 0
+ ASSERT_EQ(mOutputBuffer[i], mInputBuffer[j]);
+ ASSERT_EQ(mOutputBuffer[i + 1], mInputBuffer[j]);
+ }
+ }
+ }
+
+ void validateOutput(int32_t channel, size_t position) {
+ switch (channel) {
+ case AudioChannelLayout::CHANNEL_FRONT_LEFT:
+ case AudioChannelLayout::CHANNEL_BACK_LEFT:
+ case AudioChannelLayout::CHANNEL_SIDE_LEFT:
+ case AudioChannelLayout::CHANNEL_TOP_FRONT_LEFT:
+ case AudioChannelLayout::CHANNEL_BOTTOM_FRONT_LEFT:
+ case AudioChannelLayout::CHANNEL_TOP_BACK_LEFT:
+ case AudioChannelLayout::CHANNEL_FRONT_WIDE_LEFT:
+ case AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT:
+ checkAtLeft(position);
+ break;
+
+ case AudioChannelLayout::CHANNEL_FRONT_RIGHT:
+ case AudioChannelLayout::CHANNEL_BACK_RIGHT:
+ case AudioChannelLayout::CHANNEL_SIDE_RIGHT:
+ case AudioChannelLayout::CHANNEL_TOP_FRONT_RIGHT:
+ case AudioChannelLayout::CHANNEL_BOTTOM_FRONT_RIGHT:
+ case AudioChannelLayout::CHANNEL_TOP_BACK_RIGHT:
+ case AudioChannelLayout::CHANNEL_FRONT_WIDE_RIGHT:
+ case AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT:
+ case AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2:
+ checkAtRight(position);
+ break;
+
+ case AudioChannelLayout::CHANNEL_FRONT_CENTER:
+ case AudioChannelLayout::CHANNEL_BACK_CENTER:
+ case AudioChannelLayout::CHANNEL_TOP_FRONT_CENTER:
+ case AudioChannelLayout::CHANNEL_BOTTOM_FRONT_CENTER:
+ case AudioChannelLayout::CHANNEL_FRONT_LEFT_OF_CENTER:
+ case AudioChannelLayout::CHANNEL_FRONT_RIGHT_OF_CENTER:
+ case AudioChannelLayout::CHANNEL_TOP_CENTER:
+ case AudioChannelLayout::CHANNEL_TOP_BACK_CENTER:
+ checkAtCenter(position);
+ break;
+
+ case AudioChannelLayout::CHANNEL_LOW_FREQUENCY:
+ // If CHANNEL_LOW_FREQUENCY_2 is supported
+ if (mInputChannelLayout & AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2) {
+ // Validate that only Left channel has audio
+ checkAtLeft(position);
+ } else {
+ // Validate that both channels have audio
+ checkAtCenter(position);
+ }
+ break;
+ }
+ }
+
+ std::set<int32_t> getInputChannelLayouts() {
+ std::set<int32_t> supportedChannels;
+ for (int32_t channel : kChannels) {
+ if ((mInputChannelLayout & channel) == channel) {
+ supportedChannels.insert(channel);
+ }
+ }
+ return supportedChannels;
+ }
+
+ int32_t mInputChannelLayout;
+};
+
+TEST_P(DownmixFoldDataTest, DownmixProcessData) {
+ // Set FOLD type parameter
+ ASSERT_NO_FATAL_FAILURE(setParameters(Downmix::Type::FOLD));
+
+ // Get all the channels from input layout
+ std::set<int32_t> supportedChannels = getInputChannelLayouts();
+
+ for (int32_t channel : supportedChannels) {
+ size_t position = std::distance(supportedChannels.begin(), supportedChannels.find(channel));
+ generateInputBuffer(position, false /*isStripe*/);
+ ASSERT_NO_FATAL_FAILURE(
+ processAndWriteToOutput(mInputBuffer, mOutputBuffer, mEffect, &mOpenEffectReturn));
+ validateOutput(channel, position);
+ std::fill(mInputBuffer.begin(), mInputBuffer.end(), 0);
+ }
+}
+
+enum StripParamName { STRIP_INSTANCE_NAME, STRIP_INPUT_LAYOUT };
+
+using DownmixStripDataTestParam =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t>;
+
+class DownmixStripDataTest : public ::testing::TestWithParam<DownmixStripDataTestParam>,
+ public DownmixEffectHelper {
+ public:
+ DownmixStripDataTest() : mInputChannelLayout(std::get<STRIP_INPUT_LAYOUT>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<STRIP_INSTANCE_NAME>(GetParam());
+ }
+
+ void SetUp() override {
+ SetUpDownmix(mInputChannelLayout);
+ if (!isLayoutValid(mInputChannelLayout)) {
+ GTEST_SKIP() << "Layout not supported \n";
+ }
+ setDataTestParams(mInputChannelLayout);
+ }
+
+ void TearDown() override { TearDownDownmix(); }
+
+ void validateOutput() {
+ ASSERT_EQ(kBufferSize, mInputBuffer.size());
+ ASSERT_GE(kBufferSize, mOutputBufferSize);
+ for (size_t i = 0, j = 0; i < kBufferSize && j < mOutputBufferSize;
+ i += mInputChannelCount, j += kOutputChannelCount) {
+ ASSERT_EQ(mOutputBuffer[j], mInputBuffer[i]);
+ ASSERT_EQ(mOutputBuffer[j + 1], mInputBuffer[i + 1]);
+ }
+ for (size_t i = mOutputBufferSize; i < kBufferSize; i++) {
+ ASSERT_EQ(mOutputBuffer[i], mInputBuffer[i]);
+ }
+ }
+
+ int32_t mInputChannelLayout;
+};
+
+TEST_P(DownmixStripDataTest, DownmixProcessData) {
+ // Set STRIP type parameter
+ ASSERT_NO_FATAL_FAILURE(setParameters(Downmix::Type::STRIP));
+
+ // Generate input buffer, call process and compare outputs
+ generateInputBuffer(0 /*position*/, true /*isStripe*/);
+ ASSERT_NO_FATAL_FAILURE(
+ processAndWriteToOutput(mInputBuffer, mOutputBuffer, mEffect, &mOpenEffectReturn));
+ validateOutput();
}
INSTANTIATE_TEST_SUITE_P(
@@ -134,6 +427,39 @@
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DownmixParamTest);
+INSTANTIATE_TEST_SUITE_P(
+ DownmixTest, DownmixFoldDataTest,
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidDownmix())),
+ testing::ValuesIn(kLayoutValues)),
+ [](const testing::TestParamInfo<DownmixFoldDataTest::ParamType>& info) {
+ auto descriptor = std::get<FOLD_INSTANCE_NAME>(info.param).second;
+ std::string layout = std::to_string(std::get<FOLD_INPUT_LAYOUT>(info.param));
+ std::string name = getPrefix(descriptor) + "_fold" + "_layout" + layout;
+ std::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DownmixFoldDataTest);
+
+INSTANTIATE_TEST_SUITE_P(
+ DownmixTest, DownmixStripDataTest,
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidDownmix())),
+ testing::ValuesIn(kLayoutValues)),
+ [](const testing::TestParamInfo<DownmixStripDataTest::ParamType>& info) {
+ auto descriptor = std::get<STRIP_INSTANCE_NAME>(info.param).second;
+ std::string layout =
+ std::to_string(static_cast<int>(std::get<STRIP_INPUT_LAYOUT>(info.param)));
+ std::string name = getPrefix(descriptor) + "_strip" + "_layout" + layout;
+ std::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DownmixStripDataTest);
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
diff --git a/audio/effect/4.0/xml/Android.bp b/audio/effect/4.0/xml/Android.bp
index 8c03a35..bdffe60 100644
--- a/audio/effect/4.0/xml/Android.bp
+++ b/audio/effect/4.0/xml/Android.bp
@@ -9,9 +9,9 @@
genrule {
name: "audio_effects_conf_V4_0",
- srcs: ["audio_effects_conf.xsd"],
+ srcs: [":audio_effects_conf_V2_0"],
out: [
"audio_effects_conf_V4_0.xsd",
],
- cmd: "cp -f $(in) $(genDir)/audio_effects_conf_V4_0.xsd",
+ cmd: "cp -f $(in) $(out)",
}
diff --git a/audio/effect/4.0/xml/audio_effects_conf.xsd b/audio/effect/4.0/xml/audio_effects_conf.xsd
deleted file mode 120000
index 9d85fa7..0000000
--- a/audio/effect/4.0/xml/audio_effects_conf.xsd
+++ /dev/null
@@ -1 +0,0 @@
-../../2.0/xml/audio_effects_conf.xsd
\ No newline at end of file
diff --git a/audio/effect/5.0/xml/Android.bp b/audio/effect/5.0/xml/Android.bp
index 7982e2a..ed12e38 100644
--- a/audio/effect/5.0/xml/Android.bp
+++ b/audio/effect/5.0/xml/Android.bp
@@ -9,6 +9,6 @@
xsd_config {
name: "audio_effects_conf_V5_0",
- srcs: ["audio_effects_conf.xsd"],
+ srcs: [":audio_effects_conf_V2_0"],
package_name: "audio.effects.V5_0",
}
diff --git a/audio/effect/5.0/xml/audio_effects_conf.xsd b/audio/effect/5.0/xml/audio_effects_conf.xsd
deleted file mode 120000
index 9d85fa7..0000000
--- a/audio/effect/5.0/xml/audio_effects_conf.xsd
+++ /dev/null
@@ -1 +0,0 @@
-../../2.0/xml/audio_effects_conf.xsd
\ No newline at end of file
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
index 2148244..418dd7a 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum AacObjectType {
- MPEG2_LC = 0,
- MPEG4_LC = 1,
- MPEG4_LTP = 2,
- MPEG4_SCALABLE = 3,
+ MPEG2_LC,
+ MPEG4_LC,
+ MPEG4_LTP,
+ MPEG4_SCALABLE,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl
index 0499b70..675f9f2 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl
@@ -38,5 +38,5 @@
MONO = 1,
DUAL_MONO = 2,
TWS_STEREO = 4,
- UNKNOWN = 255,
+ UNKNOWN = 0xFF,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl
index f702939..a18303e 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl
@@ -34,6 +34,6 @@
package android.hardware.bluetooth.audio;
@Backing(type="int") @VintfStability
enum AptxAdaptiveInputMode {
- STEREO = 0,
- DUAL_MONO = 1,
+ STEREO = 0x00,
+ DUAL_MONO = 0x01,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxMode.aidl
index d5dd9d9..dd8cf08 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxMode.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="int") @VintfStability
enum AptxMode {
- UNKNOWN = 0,
- HIGH_QUALITY = 4096,
- LOW_LATENCY = 8192,
- ULTRA_LOW_LATENCY = 16384,
+ UNKNOWN = 0x00,
+ HIGH_QUALITY = 0x1000,
+ LOW_LATENCY = 0x2000,
+ ULTRA_LOW_LATENCY = 0x4000,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioContext.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioContext.aidl
new file mode 100644
index 0000000..5aafeb7
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioContext.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 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.bluetooth.audio;
+@VintfStability
+parcelable AudioContext {
+ int bitmask;
+ const int UNSPECIFIED = 0x0001;
+ const int CONVERSATIONAL = 0x0002;
+ const int MEDIA = 0x0004;
+ const int GAME = 0x0008;
+ const int INSTRUCTIONAL = 0x0010;
+ const int VOICE_ASSISTANTS = 0x0020;
+ const int LIVE_AUDIO = 0x0040;
+ const int SOUND_EFFECTS = 0x0080;
+ const int NOTIFICATIONS = 0x0100;
+ const int RINGTONE_ALERTS = 0x0200;
+ const int ALERTS = 0x0400;
+ const int EMERGENCY_ALARM = 0x0800;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
index 319a5e2..941344c 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
@@ -35,6 +35,6 @@
@Backing(type="int") @VintfStability
enum AudioLocation {
UNKNOWN = 1,
- FRONT_LEFT = 2,
- FRONT_RIGHT = 4,
+ FRONT_LEFT = (1 << 1) /* 2 */,
+ FRONT_RIGHT = (1 << 2) /* 4 */,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
index feacb80..2bb5cd8 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum ChannelMode {
- UNKNOWN = 0,
- MONO = 1,
- STEREO = 2,
- DUALMONO = 3,
+ UNKNOWN,
+ MONO,
+ STEREO,
+ DUALMONO,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecId.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecId.aidl
new file mode 100644
index 0000000..f3b4102
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecId.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright 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.bluetooth.audio;
+@VintfStability
+union CodecId {
+ android.hardware.bluetooth.audio.CodecId.A2dp a2dp = android.hardware.bluetooth.audio.CodecId.A2dp.SBC;
+ android.hardware.bluetooth.audio.CodecId.Core core;
+ android.hardware.bluetooth.audio.CodecId.Vendor vendor;
+ enum A2dp {
+ SBC = 0,
+ AAC = 2,
+ }
+ enum Core {
+ CVSD = 2,
+ MSBC = 5,
+ LC3 = 6,
+ }
+ parcelable Vendor {
+ int id;
+ int codecId;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl
new file mode 100644
index 0000000..2ca9d96
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright 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.bluetooth.audio;
+@VintfStability
+parcelable CodecInfo {
+ android.hardware.bluetooth.audio.CodecId id;
+ String name;
+ android.hardware.bluetooth.audio.CodecInfo.Transport transport;
+ parcelable A2dp {
+ byte[] capabilities;
+ android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+ int[] samplingFrequencyHz;
+ int[] bitdepth;
+ boolean lossless;
+ }
+ parcelable Hfp {
+ int inputDataPath = 1;
+ int outputDataPath = 1;
+ boolean useControllerCodec = true;
+ }
+ union Transport {
+ android.hardware.bluetooth.audio.CodecInfo.A2dp a2dp;
+ android.hardware.bluetooth.audio.CodecInfo.Hfp hfp;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
index 3e204f9..d4f205e 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
@@ -34,16 +34,16 @@
package android.hardware.bluetooth.audio;
@Backing(type="int") @VintfStability
enum CodecType {
- UNKNOWN = 0,
- SBC = 1,
- AAC = 2,
- APTX = 3,
- APTX_HD = 4,
- LDAC = 5,
- LC3 = 6,
- VENDOR = 7,
- APTX_ADAPTIVE = 8,
- OPUS = 9,
- APTX_ADAPTIVE_LE = 10,
- APTX_ADAPTIVE_LEX = 11,
+ UNKNOWN,
+ SBC,
+ AAC,
+ APTX,
+ APTX_HD,
+ LDAC,
+ LC3,
+ VENDOR,
+ APTX_ADAPTIVE,
+ OPUS,
+ APTX_ADAPTIVE_LE,
+ APTX_ADAPTIVE_LEX,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
index 5e33deb..c806b0a 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
@@ -36,4 +36,10 @@
interface IBluetoothAudioProviderFactory {
android.hardware.bluetooth.audio.AudioCapabilities[] getProviderCapabilities(in android.hardware.bluetooth.audio.SessionType sessionType);
android.hardware.bluetooth.audio.IBluetoothAudioProvider openProvider(in android.hardware.bluetooth.audio.SessionType sessionType);
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProviderFactory.ProviderInfo getProviderInfo(in android.hardware.bluetooth.audio.SessionType sessionType);
+ @VintfStability
+ parcelable ProviderInfo {
+ String name;
+ android.hardware.bluetooth.audio.CodecInfo[] codecInfos;
+ }
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
index 88d6faf..3d80c4b 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum LdacChannelMode {
- UNKNOWN = 0,
- STEREO = 1,
- DUAL = 2,
- MONO = 3,
+ UNKNOWN,
+ STEREO,
+ DUAL,
+ MONO,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
index 35e4358..a332dc5 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum LdacQualityIndex {
- HIGH = 0,
- MID = 1,
- LOW = 2,
- ABR = 3,
+ HIGH,
+ MID,
+ LOW,
+ ABR,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
index 091f6d7..9cf65d5 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
@@ -34,6 +34,6 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum SbcAllocMethod {
- ALLOC_MD_S = 0,
- ALLOC_MD_L = 1,
+ ALLOC_MD_S,
+ ALLOC_MD_L,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
index 6441a99..7779aa0 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
@@ -34,9 +34,9 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum SbcChannelMode {
- UNKNOWN = 0,
- JOINT_STEREO = 1,
- STEREO = 2,
- DUAL = 3,
- MONO = 4,
+ UNKNOWN,
+ JOINT_STEREO,
+ STEREO,
+ DUAL,
+ MONO,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
index 33a3187..4b2c10f 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
@@ -34,16 +34,16 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum SessionType {
- UNKNOWN = 0,
- A2DP_SOFTWARE_ENCODING_DATAPATH = 1,
- A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 2,
- HEARING_AID_SOFTWARE_ENCODING_DATAPATH = 3,
- LE_AUDIO_SOFTWARE_ENCODING_DATAPATH = 4,
- LE_AUDIO_SOFTWARE_DECODING_DATAPATH = 5,
- LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 6,
- LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH = 7,
- LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH = 8,
- LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 9,
- A2DP_SOFTWARE_DECODING_DATAPATH = 10,
- A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH = 11,
+ UNKNOWN,
+ A2DP_SOFTWARE_ENCODING_DATAPATH,
+ A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ A2DP_SOFTWARE_DECODING_DATAPATH,
+ A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioContext.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioContext.aidl
new file mode 100644
index 0000000..306e897
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioContext.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 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.bluetooth.audio;
+
+/**
+ * Context of the audio configuration.
+ * Defined by PACS (Le Audio) and used either by A2DP or LE Audio.
+ * The `bitmask` is any combination of BT Sig standardized values
+ * [Assigned Numbers - 6.12.3], defined in this scope.
+ */
+@VintfStability
+parcelable AudioContext {
+ const int UNSPECIFIED = 0x0001;
+ const int CONVERSATIONAL = 0x0002;
+ const int MEDIA = 0x0004;
+ const int GAME = 0x0008;
+ const int INSTRUCTIONAL = 0x0010;
+ const int VOICE_ASSISTANTS = 0x0020;
+ const int LIVE_AUDIO = 0x0040;
+ const int SOUND_EFFECTS = 0x0080;
+ const int NOTIFICATIONS = 0x0100;
+ const int RINGTONE_ALERTS = 0x0200;
+ const int ALERTS = 0x0400;
+ const int EMERGENCY_ALARM = 0x0800;
+
+ int bitmask;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecId.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecId.aidl
new file mode 100644
index 0000000..896a712
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecId.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 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.bluetooth.audio;
+
+@VintfStability
+union CodecId {
+ /**
+ * Codec Identifier defined for A2DP
+ * The values are assigned by BT Sig [Assigned Numbers - 6.5.1]
+ */
+ enum A2dp { SBC = 0, AAC = 2 }
+
+ /**
+ * Codec Identifier defined for the Bluetooth Core Specification
+ * The values are assigned by BT Sig [Assigned Numbers - 2.11]
+ */
+ enum Core { CVSD = 2, MSBC = 5, LC3 = 6 }
+
+ /**
+ * Vendor Codec:
+ * id 16 bits - Assigned by BT Sig
+ * codecId 16 bits - Assigned by the vendor
+ */
+ parcelable Vendor {
+ int id;
+ int codecId;
+ }
+
+ /**
+ * Standard (A2DP or Core numbering space) or vendor
+ */
+ A2dp a2dp = A2dp.SBC;
+ Core core;
+ Vendor vendor;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl
new file mode 100644
index 0000000..127cd7c
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl
@@ -0,0 +1,99 @@
+/*
+ * Copyright 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+import android.hardware.bluetooth.audio.CodecId;
+
+/**
+ * General information about a Codec
+ */
+@VintfStability
+parcelable CodecInfo {
+ /**
+ * Codec identifier and human readable name
+ */
+ CodecId id;
+ String name;
+
+ /**
+ * A2DP Context
+ */
+ parcelable A2dp {
+ /**
+ * The capabilities as defined by A2DP for codec interoperability
+ * requirements. With `id.a2dp`, the format is given by the `Codec
+ * Specific Information Elements` [A2DP - 4.3-6.2], and with `id.vendor`,
+ * by `Vendor Specific Value` [A2DP - 4.7.2].
+ */
+ byte[] capabilities;
+
+ /**
+ * PCM characteristics:
+ * - Mono, Dual-Mono or Stereo
+ * - Supported sampling frequencies, in Hz.
+ * - Fixed point resolution, basically 16, 24 or 32 bits by samples.
+ * The value 32 should be used for floating point representation.
+ *
+ * When the bitdepth is not an encoding/decoding parameter (don't take part
+ * in the interoperability), the `bitdepth` list shall have a single element
+ * indicating the bitdepth selected for the platform.
+ */
+ ChannelMode[] channelMode;
+ int[] samplingFrequencyHz;
+ int[] bitdepth;
+
+ /**
+ * Lossless capable characteristic
+ */
+ boolean lossless;
+ }
+
+ /**
+ * HFP Context
+ */
+ parcelable Hfp {
+ /**
+ * Vendor-specific identifiers of stream data paths, set in the
+ * HCI Command Enhanced Setup Synchronous Connection [Core - 4.E.7.1.45],
+ * in the command parameters respectively `Input_Data_Path` and
+ * `Output_Data_Path`. The value range from 0x01 to 0xFE.
+ * The stack operates as a pass-through; the client SHALL NOT
+ * interpret the values.
+ */
+ int inputDataPath = 1;
+ int outputDataPath = 1;
+
+ /**
+ * Whether the audio stream is encoded and decoded in the controller or
+ * locally; enable the controller transparent mode when the audio
+ * stream is locally processed.
+ */
+ boolean useControllerCodec = true;
+ }
+
+ /**
+ * Specific informations,
+ * depending on transport.
+ */
+ union Transport {
+ A2dp a2dp;
+ Hfp hfp;
+ }
+
+ Transport transport;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index d5c051e..558173e 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -59,9 +59,8 @@
* audioConfig.pcmConfig parameter. Invalid if streaming is offloaded
* from/to hardware or on failure
*/
- MQDescriptor<byte, SynchronizedReadWrite> startSession(
- in IBluetoothAudioPort hostIf, in AudioConfiguration audioConfig,
- in LatencyMode[] supportedLatencyModes);
+ MQDescriptor<byte, SynchronizedReadWrite> startSession(in IBluetoothAudioPort hostIf,
+ in AudioConfiguration audioConfig, in LatencyMode[] supportedLatencyModes);
/**
* Callback for IBluetoothAudioPort.startStream()
*
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
index 3cde22c..b9cec2d 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
@@ -17,8 +17,10 @@
package android.hardware.bluetooth.audio;
import android.hardware.bluetooth.audio.AudioCapabilities;
+import android.hardware.bluetooth.audio.CodecInfo;
import android.hardware.bluetooth.audio.IBluetoothAudioProvider;
import android.hardware.bluetooth.audio.SessionType;
+
/**
* This factory allows a HAL implementation to be split into multiple
* independent providers.
@@ -62,4 +64,24 @@
* @return provider The provider of the specified session type
*/
IBluetoothAudioProvider openProvider(in SessionType sessionType);
+
+ /**
+ * General information relative to a provider
+ * - An optional name
+ * - A list of codec information
+ */
+ @VintfStability
+ parcelable ProviderInfo {
+ String name;
+ CodecInfo[] codecInfos;
+ }
+
+ /**
+ * Get general information relative to a provider.
+ *
+ * @param sessionType Hardware Offload provider (*_HARDWARE_OFFLOAD_*)
+ * @return General information relative to the provider.
+ * The `null` value can be returned when the provider is not available
+ */
+ @nullable ProviderInfo getProviderInfo(in SessionType sessionType);
}
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
index 9c72e19..f9b18f8 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
@@ -168,4 +168,4 @@
} // namespace bluetooth
} // namespace hardware
} // namespace android
-} // namespace aidl
\ No newline at end of file
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
index 91731d4..7e928e9 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
@@ -135,8 +135,17 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderInfo(
+ SessionType session_type, std::optional<ProviderInfo>* _aidl_return) {
+ *_aidl_return = std::nullopt;
+
+ (void)session_type;
+
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
} // namespace android
-} // namespace aidl
\ No newline at end of file
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h
index b38cfd2..1afae64 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h
@@ -35,6 +35,10 @@
ndk::ScopedAStatus getProviderCapabilities(
const SessionType session_type,
std::vector<AudioCapabilities>* _aidl_return) override;
+
+ ndk::ScopedAStatus getProviderInfo(
+ SessionType in_sessionType,
+ std::optional<ProviderInfo>* _aidl_return) override;
};
} // namespace audio
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index 858fa38..40cd821 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -46,6 +46,8 @@
using aidl::android::hardware::bluetooth::audio::ChannelMode;
using aidl::android::hardware::bluetooth::audio::CodecCapabilities;
using aidl::android::hardware::bluetooth::audio::CodecConfiguration;
+using aidl::android::hardware::bluetooth::audio::CodecId;
+using aidl::android::hardware::bluetooth::audio::CodecInfo;
using aidl::android::hardware::bluetooth::audio::CodecType;
using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
@@ -598,6 +600,99 @@
}
/**
+ * Test that getProviderInfo, when implemented,
+ * returns empty information for session types for
+ * software data paths.
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_invalidSessionTypes) {
+ static constexpr SessionType kInvalidSessionTypes[]{
+ SessionType::UNKNOWN,
+ SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
+ };
+
+ for (auto session_type : kInvalidSessionTypes) {
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
+ std::nullopt;
+ auto aidl_retval =
+ provider_factory_->getProviderInfo(session_type, &provider_info);
+ if (!aidl_retval.isOk()) {
+ continue;
+ }
+
+ // If getProviderInfo is supported, the provider info
+ // must be empty for software session types.
+ ASSERT_FALSE(provider_info.has_value());
+ }
+}
+
+/**
+ * Test that getProviderInfo, when implemented,
+ * returns valid information for session types for
+ * a2dp hardware data paths.
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_a2dpSessionTypes) {
+ static constexpr SessionType kA2dpSessionTypes[]{
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ };
+
+ for (auto session_type : kA2dpSessionTypes) {
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
+ std::nullopt;
+ auto aidl_retval =
+ provider_factory_->getProviderInfo(session_type, &provider_info);
+ if (!aidl_retval.isOk() || !provider_info.has_value()) {
+ continue;
+ }
+
+ for (auto const& codec_info : provider_info->codecInfos) {
+ // The codec id must not be core.
+ ASSERT_NE(codec_info.id.getTag(), CodecId::core);
+ // The codec info must contain the information
+ // for a2dp transport.
+ ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::a2dp);
+ }
+ }
+}
+
+/**
+ * Test that getProviderInfo, when implemented,
+ * returns valid information for session types for
+ * le audio hardware data paths.
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_leAudioSessionTypes) {
+ static constexpr SessionType kLeAudioSessionTypes[]{
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ };
+
+ for (auto session_type : kLeAudioSessionTypes) {
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
+ std::nullopt;
+ auto aidl_retval =
+ provider_factory_->getProviderInfo(session_type, &provider_info);
+ if (!aidl_retval.isOk() || !provider_info.has_value()) {
+ continue;
+ }
+
+ for (auto const& codec_info : provider_info->codecInfos) {
+ // The codec id must not be a2dp.
+ ASSERT_NE(codec_info.id.getTag(), CodecId::a2dp);
+ // The codec info must contain the information
+ // for le audio transport.
+ // ASSERT_EQ(codec_info.transport.getTag(),
+ // CodecInfo::Transport::le_audio);
+ }
+ }
+}
+
+/**
* openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
*/
class BluetoothAudioProviderA2dpEncodingSoftwareAidl
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index 75081d6..e7659a4 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -78,7 +78,7 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.bluetooth.audio-V3-ndk",
+ "android.hardware.bluetooth.audio-V4-ndk",
"libxml2",
],
test_suites: [
diff --git a/bluetooth/finder/aidl/Android.bp b/bluetooth/finder/aidl/Android.bp
new file mode 100644
index 0000000..e606d2d
--- /dev/null
+++ b/bluetooth/finder/aidl/Android.bp
@@ -0,0 +1,34 @@
+// 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aidl_interface {
+ name: "android.hardware.bluetooth.finder",
+ vendor_available: true,
+ srcs: ["android/hardware/bluetooth/finder/*.aidl"],
+ stability: "vintf",
+
+ backend: {
+ ndk: {
+ enabled: true,
+ },
+ java: {
+ enabled: true,
+ platform_apis: true,
+ },
+ },
+}
diff --git a/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/Eid.aidl b/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/Eid.aidl
new file mode 100644
index 0000000..42461c5
--- /dev/null
+++ b/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/Eid.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.bluetooth.finder;
+@VintfStability
+parcelable Eid {
+ byte[20] bytes;
+}
diff --git a/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/IBluetoothFinder.aidl b/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/IBluetoothFinder.aidl
new file mode 100644
index 0000000..4bc9041
--- /dev/null
+++ b/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/IBluetoothFinder.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.bluetooth.finder;
+@VintfStability
+interface IBluetoothFinder {
+ void sendEids(in android.hardware.bluetooth.finder.Eid[] eids);
+ void setPoweredOffFinderMode(in boolean enable);
+ boolean getPoweredOffFinderMode();
+}
diff --git a/bluetooth/finder/aidl/android/hardware/bluetooth/finder/Eid.aidl b/bluetooth/finder/aidl/android/hardware/bluetooth/finder/Eid.aidl
new file mode 100644
index 0000000..ae9b159
--- /dev/null
+++ b/bluetooth/finder/aidl/android/hardware/bluetooth/finder/Eid.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.bluetooth.finder;
+
+/**
+ * Ephemeral Identifier
+ */
+@VintfStability
+parcelable Eid {
+ byte[20] bytes;
+}
diff --git a/bluetooth/finder/aidl/android/hardware/bluetooth/finder/IBluetoothFinder.aidl b/bluetooth/finder/aidl/android/hardware/bluetooth/finder/IBluetoothFinder.aidl
new file mode 100644
index 0000000..615739b
--- /dev/null
+++ b/bluetooth/finder/aidl/android/hardware/bluetooth/finder/IBluetoothFinder.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.bluetooth.finder;
+
+import android.hardware.bluetooth.finder.Eid;
+
+@VintfStability
+interface IBluetoothFinder {
+ /**
+ * API to set the EIDs to the Bluetooth Controller
+ *
+ * @param eids array of 20 bytes EID to the Bluetooth
+ * controller
+ */
+ void sendEids(in Eid[] eids);
+
+ /**
+ * API to enable the powered-off finder feature, which allows the Bluetooth controller to send
+ * beacons after the device is powered off.
+ *
+ * @param enable true to enable; false to disable
+ */
+ void setPoweredOffFinderMode(in boolean enable);
+
+ /**
+ * API for retrieving feature enablement status
+ *
+ * @return the value last set by setPoweredOffFinderMode, false if setPoweredOffFinderMode was
+ * never been invoked since boot.
+ */
+ boolean getPoweredOffFinderMode();
+}
diff --git a/bluetooth/finder/aidl/default/Android.bp b/bluetooth/finder/aidl/default/Android.bp
new file mode 100644
index 0000000..b364ae1
--- /dev/null
+++ b/bluetooth/finder/aidl/default/Android.bp
@@ -0,0 +1,42 @@
+// 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_binary {
+ name: "android.hardware.bluetooth.finder-service.default",
+ relative_install_path: "hw",
+ init_rc: ["bluetooth-finder-service-default.rc"],
+ vintf_fragments: [":manifest_android.hardware.bluetooth.finder-service.default.xml"],
+ vendor: true,
+ srcs: [
+ "BluetoothFinder.cpp",
+ "service.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.bluetooth.finder-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ "libhidlbase",
+ "libutils",
+ "liblog",
+ ],
+}
+
+filegroup {
+ name: "manifest_android.hardware.bluetooth.finder-service.default.xml",
+ srcs: ["bluetooth-finder-service-default.xml"],
+}
diff --git a/bluetooth/finder/aidl/default/BluetoothFinder.cpp b/bluetooth/finder/aidl/default/BluetoothFinder.cpp
new file mode 100644
index 0000000..236a1f8
--- /dev/null
+++ b/bluetooth/finder/aidl/default/BluetoothFinder.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#include "BluetoothFinder.h"
+
+namespace aidl::android::hardware::bluetooth::finder::impl {
+
+::ndk::ScopedAStatus BluetoothFinder::sendEids(const ::std::vector<Eid>& keys) {
+ keys_.insert(keys_.end(), keys.begin(), keys.end());
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus BluetoothFinder::setPoweredOffFinderMode(bool enable) {
+ pof_enabled_ = enable;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus BluetoothFinder::getPoweredOffFinderMode(
+ bool* _aidl_return) {
+ *_aidl_return = pof_enabled_;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::bluetooth::finder::impl
diff --git a/bluetooth/finder/aidl/default/BluetoothFinder.h b/bluetooth/finder/aidl/default/BluetoothFinder.h
new file mode 100644
index 0000000..16110f6
--- /dev/null
+++ b/bluetooth/finder/aidl/default/BluetoothFinder.h
@@ -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.
+ */
+
+#include <aidl/android/hardware/bluetooth/finder/BnBluetoothFinder.h>
+
+#include <vector>
+
+namespace aidl::android::hardware::bluetooth::finder::impl {
+
+using ::aidl::android::hardware::bluetooth::finder::BnBluetoothFinder;
+using ::aidl::android::hardware::bluetooth::finder::Eid;
+
+class BluetoothFinder : public BnBluetoothFinder {
+ public:
+ BluetoothFinder() = default;
+
+ ::ndk::ScopedAStatus sendEids(const ::std::vector<Eid>& keys) override;
+ ::ndk::ScopedAStatus setPoweredOffFinderMode(bool enable) override;
+ ::ndk::ScopedAStatus getPoweredOffFinderMode(bool* _aidl_return) override;
+
+ private:
+ bool pof_enabled_;
+ std::vector<Eid> keys_;
+};
+
+} // namespace aidl::android::hardware::bluetooth::finder::impl
diff --git a/bluetooth/finder/aidl/default/bluetooth-finder-service-default.rc b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.rc
new file mode 100644
index 0000000..fea07f0
--- /dev/null
+++ b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.rc
@@ -0,0 +1,6 @@
+service vendor.bluetooth.finder-default /vendor/bin/hw/android.hardware.bluetooth.finder.default
+ class hal
+ capabilities BLOCK_SUSPEND NET_ADMIN SYS_NICE
+ user bluetooth
+ group bluetooth
+ task_profiles ServicePerformance
diff --git a/bluetooth/finder/aidl/default/bluetooth-finder-service-default.xml b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.xml
new file mode 100644
index 0000000..be7c00d
--- /dev/null
+++ b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.bluetooth.finder</name>
+ <version>1</version>
+ <fqname>IBluetoothFinder/default</fqname>
+ </hal>
+</manifest>
diff --git a/bluetooth/finder/aidl/default/service.cpp b/bluetooth/finder/aidl/default/service.cpp
new file mode 100644
index 0000000..a117df8
--- /dev/null
+++ b/bluetooth/finder/aidl/default/service.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "aidl.android.hardware.bluetooth.finder.default"
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+#include "BluetoothFinder.h"
+
+using ::aidl::android::hardware::bluetooth::finder::impl::BluetoothFinder;
+
+int main(int /* argc */, char** /* argv */) {
+ ALOGI("Bluetooth Finder HAL registering");
+ if (!ABinderProcess_setThreadPoolMaxThreadCount(0)) {
+ ALOGE("failed to set thread pool max thread count");
+ return 1;
+ }
+
+ std::shared_ptr<BluetoothFinder> service =
+ ndk::SharedRefBase::make<BluetoothFinder>();
+ std::string instance =
+ std::string() + BluetoothFinder::descriptor + "/default";
+ auto result =
+ AServiceManager_addService(service->asBinder().get(), instance.c_str());
+ if (result == STATUS_OK) {
+ ABinderProcess_joinThreadPool();
+ } else {
+ ALOGE("Could not register as a service!");
+ }
+ return 0;
+}
diff --git a/bluetooth/finder/aidl/vts/Android.bp b/bluetooth/finder/aidl/vts/Android.bp
new file mode 100644
index 0000000..6b0285e
--- /dev/null
+++ b/bluetooth/finder/aidl/vts/Android.bp
@@ -0,0 +1,41 @@
+// 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 {
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalBluetoothFinderTargetTest",
+ defaults: [
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalBluetoothFinderTargetTest.cpp"],
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "libbinder_ndk",
+ "liblog",
+ "libutils",
+ ],
+ static_libs: [
+ "android.hardware.bluetooth.finder-V1-ndk",
+ "libbluetooth-types",
+ ],
+ test_config: "VtsHalBluetoothFinderTargetTest.xml",
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.cpp b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.cpp
new file mode 100644
index 0000000..be07a7d
--- /dev/null
+++ b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.cpp
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/bluetooth/finder/IBluetoothFinder.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+
+#include <array>
+#include <vector>
+
+using ::aidl::android::hardware::bluetooth::finder::Eid;
+using ::aidl::android::hardware::bluetooth::finder::IBluetoothFinder;
+using ::ndk::ScopedAStatus;
+
+class BluetoothFinderTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ ALOGI("SetUp Finder Test");
+ bluetooth_finder = IBluetoothFinder::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+ ASSERT_NE(bluetooth_finder, nullptr);
+ }
+
+ virtual void TearDown() override {
+ ALOGI("TearDown Finder Test");
+ bluetooth_finder = nullptr;
+ ASSERT_EQ(bluetooth_finder, nullptr);
+ }
+
+ ScopedAStatus sendEids(uint8_t num);
+ ScopedAStatus setPoweredOffFinderMode(bool enable);
+ ScopedAStatus getPoweredOffFinderMode(bool* status);
+
+ private:
+ std::shared_ptr<IBluetoothFinder> bluetooth_finder;
+};
+
+ScopedAStatus BluetoothFinderTest::sendEids(uint8_t numKeys) {
+ std::vector<Eid> keys(numKeys);
+ for (uint_t i = 0; i < numKeys; i++) {
+ std::array<uint8_t, 20> key;
+ key.fill(i + 1);
+ keys[i].bytes = key;
+ }
+ return bluetooth_finder->sendEids(keys);
+}
+
+ScopedAStatus BluetoothFinderTest::setPoweredOffFinderMode(bool enable) {
+ return bluetooth_finder->setPoweredOffFinderMode(enable);
+}
+
+ScopedAStatus BluetoothFinderTest::getPoweredOffFinderMode(bool* status) {
+ return bluetooth_finder->getPoweredOffFinderMode(status);
+}
+
+TEST_P(BluetoothFinderTest, SendEidsSingle) {
+ ScopedAStatus status = sendEids(1);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothFinderTest, Send255Eids) {
+ ScopedAStatus status = sendEids(255);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothFinderTest, setAndGetPoweredOffFinderModeEnable) {
+ ScopedAStatus status = setPoweredOffFinderMode(true);
+ ASSERT_TRUE(status.isOk());
+ bool pof_status;
+ status = getPoweredOffFinderMode(&pof_status);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(pof_status);
+}
+
+TEST_P(BluetoothFinderTest, setAndGetPoweredOffFinderModeDisable) {
+ ScopedAStatus status = setPoweredOffFinderMode(false);
+ ASSERT_TRUE(status.isOk());
+ bool pof_status;
+ status = getPoweredOffFinderMode(&pof_status);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(!pof_status);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothFinderTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothFinderTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothFinder::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_startThreadPool();
+ int status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+ return status;
+}
diff --git a/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.xml b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.xml
new file mode 100644
index 0000000..46053dd
--- /dev/null
+++ b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.xml
@@ -0,0 +1,33 @@
+<!--
+ 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.
+-->
+
+<configuration description="Runs VtsHalBluetoothFinderTargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalBluetoothFinderTargetTest->/data/local/tmp/VtsHalBluetoothFinderTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalBluetoothFinderTargetTest" />
+ </test>
+</configuration>
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index b3ca293..9bee3b9 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -90,7 +90,7 @@
"compatibility_matrix.9.xml",
],
kernel_configs: [
- "kernel_config_v_5.15",
"kernel_config_v_6.1",
+ "kernel_config_v_6.6",
],
}
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml
index 9f6b78b..de2e1d1 100644
--- a/compatibility_matrices/compatibility_matrix.9.xml
+++ b/compatibility_matrices/compatibility_matrix.9.xml
@@ -147,6 +147,14 @@
</interface>
</hal>
<hal format="aidl" optional="true">
+ <name>android.hardware.bluetooth.finder</name>
+ <version>1</version>
+ <interface>
+ <name>IBluetoothFinder</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="aidl" optional="true">
<name>android.hardware.boot</name>
<interface>
<name>IBootControl</name>
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 822770d..d3f6ae3 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -1792,6 +1792,12 @@
std::string empty_boot_key(32, '\0');
std::string verified_boot_key_str((const char*)verified_boot_key.data(),
verified_boot_key.size());
+ if (get_vsr_api_level() >= __ANDROID_API_V__) {
+ // The attestation should contain the SHA-256 hash of the verified boot
+ // key. However, this was not checked for earlier versions of the KeyMint
+ // HAL so only be strict for VSR-V and above.
+ EXPECT_LE(verified_boot_key.size(), 32);
+ }
EXPECT_NE(property_get("ro.boot.verifiedbootstate", property_value, ""), 0);
if (!strcmp(property_value, "green")) {
EXPECT_EQ(verified_boot_state, VerifiedBoot::VERIFIED);
diff --git a/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
index c9a156d..9f7322a 100644
--- a/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
+++ b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
@@ -114,6 +114,12 @@
const auto& vbKey = rot->asArray()->get(pos++);
ASSERT_TRUE(vbKey);
ASSERT_TRUE(vbKey->asBstr());
+ if (get_vsr_api_level() >= __ANDROID_API_V__) {
+ // The attestation should contain the SHA-256 hash of the verified boot
+ // key. However, this not was checked for earlier versions of the KeyMint
+ // HAL so only be strict for VSR-V and above.
+ ASSERT_LE(vbKey->asBstr()->value().size(), 32);
+ }
const auto& deviceLocked = rot->asArray()->get(pos++);
ASSERT_TRUE(deviceLocked);
diff --git a/security/rkp/README.md b/security/rkp/README.md
index 15ea817..71f70cb 100644
--- a/security/rkp/README.md
+++ b/security/rkp/README.md
@@ -190,3 +190,30 @@
* [RpcHardwareInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl)
* [DeviceInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl)
+### Support for Android Virtualization Framework
+
+The Android Virtualization Framwork (AVF) relies on RKP to provision keys for VMs. A
+privileged vm, the RKP VM, is reponsible for generating and managing the keys for client
+VMs that run virtualized workloads. See the following for more background information on the
+RKP VM:
+* [rkp-vm]: https://android.googlesource.com/platform/packages/modules/Virtualization/+/main/service_vm/README.md#rkp-vm-remote-key-provisioning-virtual-machine
+* [rkp-service]: https://source.android.com/docs/core/ota/modular-system/remote-key-provisioning#stack-architecture
+
+It is important to distinquish the RKP VM from other components, such as KeyMint. An
+[RKP VM marker](https://pigweed.googlesource.com/open-dice/+/HEAD/docs/android.md#configuration-descriptor)
+(key `-70006) is used for this purpose. The existence or absence of this marker is used to
+identify the type of component decribed by a given DICE chain.
+
+The following describes which certificate types may be request based on the RKP VM marker:
+1. "rkp-vm": If a DICE chain has zero or more certificates without the RKP VM
+ marker followed by one or more certificates with the marker, then that chain
+ describes an RKP VM. If there are further certificates without the RKP VM
+ marker, then the chain does not describe an RKP VM.
+
+ Implementations must include the first RPK VM marker as early as possible
+ after the point of divergence between TEE and non-TEE components in the DICE
+ chain, prior to loading the Android Bootloader (ABL).
+2. "widevine" or "keymint": If there are no certificates with the RKP VM
+ marker then it describes a TEE component.
+3. None: Any component described by a DICE chain that does not match the above
+ two categories.
\ No newline at end of file
diff --git a/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
index 61404d4..3c43238 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
+++ b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
@@ -14,8 +14,9 @@
; be extended without requiring a version bump of the HAL. Custom certificate types may
; be used, but the provisioning server may reject the request for an unknown certificate
; type. The currently defined certificate types are:
-; - "widevine"
-; - "keymint"
+; * "widevine" -- Widevine content protection system
+; * "keymint" -- KeyMint HAL
+; * "rkp-vm" -- See "Support for Android Virtualization Framework" in the README.md file.
CertificateType = tstr
KeysToSign = [ * PublicKey ] ; Please see PublicKey.cddl for the PublicKey definition.
@@ -112,6 +113,7 @@
? -70003 : int / tstr, ; Component version
? -70004 : null, ; Resettable
? -70005 : uint, ; Security version
+ ? -70006 : null, ; RKP VM marker
}
; Each entry in the DICE chain is a DiceChainEntryPayload signed by the key from the previous
diff --git a/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
index 0212e7e..8a3c6f0 100644
--- a/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
@@ -36,6 +36,7 @@
ALOGE("HdmiCecMock died");
auto hdmiCecMock = static_cast<HdmiCecMock*>(cookie);
hdmiCecMock->mCecThreadRun = false;
+ pthread_join(hdmiCecMock->mThreadId, NULL);
}
ScopedAStatus HdmiCecMock::addLogicalAddress(CecLogicalAddress addr, Result* _aidl_return) {
@@ -89,7 +90,9 @@
mCallback = callback;
if (callback != nullptr) {
- AIBinder_linkToDeath(this->asBinder().get(), mDeathRecipient.get(), 0 /* cookie */);
+ mDeathRecipient =
+ ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+ AIBinder_linkToDeath(callback->asBinder().get(), mDeathRecipient.get(), this /* cookie */);
mInputFile = open(CEC_MSG_IN_FIFO, O_RDWR | O_CLOEXEC);
mOutputFile = open(CEC_MSG_OUT_FIFO, O_RDWR | O_CLOEXEC);
@@ -220,7 +223,7 @@
int r = -1;
// Open the input pipe
- while (mInputFile < 0) {
+ while (mCecThreadRun && mInputFile < 0) {
usleep(1000 * 1000);
mInputFile = open(CEC_MSG_IN_FIFO, O_RDONLY | O_CLOEXEC);
}
@@ -257,7 +260,15 @@
HdmiCecMock::HdmiCecMock() {
ALOGE("[halimp_aidl] Opening a virtual CEC HAL for testing and virtual machine.");
mCallback = nullptr;
- mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
+}
+
+HdmiCecMock::~HdmiCecMock() {
+ ALOGE("[halimp_aidl] HdmiCecMock shutting down.");
+ mCallback = nullptr;
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
+ mCecThreadRun = false;
+ pthread_join(mThreadId, NULL);
}
} // namespace implementation
diff --git a/tv/hdmi/cec/aidl/default/HdmiCecMock.h b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
index aca0581..e78b1cf 100644
--- a/tv/hdmi/cec/aidl/default/HdmiCecMock.h
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
@@ -40,6 +40,7 @@
struct HdmiCecMock : public BnHdmiCec {
HdmiCecMock();
+ ~HdmiCecMock();
::ndk::ScopedAStatus addLogicalAddress(CecLogicalAddress addr, Result* _aidl_return) override;
::ndk::ScopedAStatus clearLogicalAddress() override;
::ndk::ScopedAStatus enableAudioReturnChannel(int32_t portId, bool enable) override;