Merge "audio: add dump on Streams, StreamWrapper and Module." into main
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index c6c1b5d..762c75e 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -252,9 +252,10 @@
mState == StreamDescriptor::State::ACTIVE ||
mState == StreamDescriptor::State::PAUSED ||
mState == StreamDescriptor::State::DRAINING) {
- if (hasMmapFlag(mContext->getFlags())) {
- populateReply(&reply, mIsConnected);
- } else if (!read(fmqByteCount, &reply)) {
+ if (bool success = hasMmapFlag(mContext->getFlags())
+ ? readMmap(&reply)
+ : read(fmqByteCount, &reply);
+ !success) {
mState = StreamDescriptor::State::ERROR;
}
if (mState == StreamDescriptor::State::IDLE ||
@@ -383,6 +384,24 @@
return !fatal;
}
+bool StreamInWorkerLogic::readMmap(StreamDescriptor::Reply* reply) {
+ void* buffer = nullptr;
+ size_t frameCount = 0;
+ size_t actualFrameCount = 0;
+ int32_t latency = mContext->getNominalLatencyMs();
+ // use default-initialized parameter values for mmap stream.
+ if (::android::status_t status =
+ mDriver->transfer(buffer, frameCount, &actualFrameCount, &latency);
+ status == ::android::OK) {
+ populateReply(reply, mIsConnected);
+ reply->latencyMs = latency;
+ return true;
+ } else {
+ LOG(ERROR) << __func__ << ": transfer failed: " << status;
+ return false;
+ }
+}
+
const std::string StreamOutWorkerLogic::kThreadName = "writer";
void StreamOutWorkerLogic::onBufferStateChange(size_t bufferFramesLeft) {
@@ -523,9 +542,10 @@
if (mState != StreamDescriptor::State::ERROR &&
mState != StreamDescriptor::State::TRANSFERRING &&
mState != StreamDescriptor::State::TRANSFER_PAUSED) {
- if (hasMmapFlag(mContext->getFlags())) {
- populateReply(&reply, mIsConnected);
- } else if (!write(fmqByteCount, &reply)) {
+ if (bool success = hasMmapFlag(mContext->getFlags())
+ ? writeMmap(&reply)
+ : write(fmqByteCount, &reply);
+ !success) {
mState = StreamDescriptor::State::ERROR;
}
std::shared_ptr<IStreamCallback> asyncCallback = mContext->getAsyncCallback();
@@ -700,6 +720,24 @@
return !fatal;
}
+bool StreamOutWorkerLogic::writeMmap(StreamDescriptor::Reply* reply) {
+ void* buffer = nullptr;
+ size_t frameCount = 0;
+ size_t actualFrameCount = 0;
+ int32_t latency = mContext->getNominalLatencyMs();
+ // use default-initialized parameter values for mmap stream.
+ if (::android::status_t status =
+ mDriver->transfer(buffer, frameCount, &actualFrameCount, &latency);
+ status == ::android::OK) {
+ populateReply(reply, mIsConnected);
+ reply->latencyMs = latency;
+ return true;
+ } else {
+ LOG(ERROR) << __func__ << ": transfer failed: " << status;
+ return false;
+ }
+}
+
StreamCommonImpl::~StreamCommonImpl() {
// It is responsibility of the class that implements 'DriverInterface' to call 'cleanupWorker'
// in the destructor. Note that 'cleanupWorker' can not be properly called from this destructor
diff --git a/audio/aidl/default/include/core-impl/DriverStubImpl.h b/audio/aidl/default/include/core-impl/DriverStubImpl.h
index a1a6c82..84f869a 100644
--- a/audio/aidl/default/include/core-impl/DriverStubImpl.h
+++ b/audio/aidl/default/include/core-impl/DriverStubImpl.h
@@ -22,7 +22,9 @@
class DriverStubImpl : virtual public DriverInterface {
public:
- explicit DriverStubImpl(const StreamContext& context);
+ explicit DriverStubImpl(const StreamContext& context)
+ : DriverStubImpl(context, 500 /*asyncSleepTimeUs*/) {}
+ DriverStubImpl(const StreamContext& context, int asyncSleepTimeUs);
::android::status_t init(DriverCallbackInterface* callback) override;
::android::status_t drain(StreamDescriptor::DrainMode) override;
@@ -40,6 +42,8 @@
const int mSampleRate;
const bool mIsAsynchronous;
const bool mIsInput;
+ const int32_t mMixPortHandle;
+ const int mAsyncSleepTimeUs;
bool mIsInitialized = false; // Used for validating the state machine logic.
bool mIsStandby = true; // Used for validating the state machine logic.
int64_t mStartTimeNs = 0;
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index dc7420b..376c684 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -307,6 +307,7 @@
private:
bool read(size_t clientSize, StreamDescriptor::Reply* reply);
+ bool readMmap(StreamDescriptor::Reply* reply);
};
using StreamInWorker = StreamWorkerImpl<StreamInWorkerLogic>;
@@ -325,6 +326,7 @@
private:
bool write(size_t clientSize, StreamDescriptor::Reply* reply);
+ bool writeMmap(StreamDescriptor::Reply* reply);
std::shared_ptr<IStreamOutEventCallback> mEventCallback;
diff --git a/audio/aidl/default/include/core-impl/StreamOffloadStub.h b/audio/aidl/default/include/core-impl/StreamOffloadStub.h
index 3b452f9..67abe95 100644
--- a/audio/aidl/default/include/core-impl/StreamOffloadStub.h
+++ b/audio/aidl/default/include/core-impl/StreamOffloadStub.h
@@ -60,11 +60,14 @@
::android::status_t drain(StreamDescriptor::DrainMode drainMode) override;
::android::status_t flush() override;
::android::status_t pause() override;
+ ::android::status_t start() override;
::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
int32_t* latencyMs) override;
void shutdown() override;
private:
+ ::android::status_t startWorkerIfNeeded();
+
DspSimulatorState mState;
DspSimulatorWorker mDspWorker;
bool mDspWorkerStarted = false;
diff --git a/audio/aidl/default/stub/DriverStubImpl.cpp b/audio/aidl/default/stub/DriverStubImpl.cpp
index 107affb..0d129e6 100644
--- a/audio/aidl/default/stub/DriverStubImpl.cpp
+++ b/audio/aidl/default/stub/DriverStubImpl.cpp
@@ -24,19 +24,27 @@
namespace aidl::android::hardware::audio::core {
-DriverStubImpl::DriverStubImpl(const StreamContext& context)
+DriverStubImpl::DriverStubImpl(const StreamContext& context, int asyncSleepTimeUs)
: mBufferSizeFrames(context.getBufferSizeInFrames()),
mFrameSizeBytes(context.getFrameSize()),
mSampleRate(context.getSampleRate()),
mIsAsynchronous(!!context.getAsyncCallback()),
- mIsInput(context.isInput()) {}
+ mIsInput(context.isInput()),
+ mMixPortHandle(context.getMixPortHandle()),
+ mAsyncSleepTimeUs(asyncSleepTimeUs) {}
+
+#define LOG_ENTRY() \
+ LOG(DEBUG) << "[" << (mIsInput ? "in" : "out") << "|ioHandle:" << mMixPortHandle << "] " \
+ << __func__;
::android::status_t DriverStubImpl::init(DriverCallbackInterface* /*callback*/) {
+ LOG_ENTRY();
mIsInitialized = true;
return ::android::OK;
}
::android::status_t DriverStubImpl::drain(StreamDescriptor::DrainMode) {
+ LOG_ENTRY();
if (!mIsInitialized) {
LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
}
@@ -46,14 +54,15 @@
const size_t delayUs = static_cast<size_t>(
std::roundf(mBufferSizeFrames * kMicrosPerSecond / mSampleRate));
usleep(delayUs);
- } else {
- usleep(500);
+ } else if (mAsyncSleepTimeUs) {
+ usleep(mAsyncSleepTimeUs);
}
}
return ::android::OK;
}
::android::status_t DriverStubImpl::flush() {
+ LOG_ENTRY();
if (!mIsInitialized) {
LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
}
@@ -61,6 +70,7 @@
}
::android::status_t DriverStubImpl::pause() {
+ LOG_ENTRY();
if (!mIsInitialized) {
LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
}
@@ -68,6 +78,7 @@
}
::android::status_t DriverStubImpl::standby() {
+ LOG_ENTRY();
if (!mIsInitialized) {
LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
}
@@ -76,6 +87,7 @@
}
::android::status_t DriverStubImpl::start() {
+ LOG_ENTRY();
if (!mIsInitialized) {
LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
}
@@ -87,6 +99,7 @@
::android::status_t DriverStubImpl::transfer(void* buffer, size_t frameCount,
size_t* actualFrameCount, int32_t*) {
+ // No LOG_ENTRY as this is called very often.
if (!mIsInitialized) {
LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
}
@@ -95,7 +108,7 @@
}
*actualFrameCount = frameCount;
if (mIsAsynchronous) {
- usleep(500);
+ if (mAsyncSleepTimeUs) usleep(mAsyncSleepTimeUs);
} else {
mFramesSinceStart += *actualFrameCount;
const long bufferDurationUs = (*actualFrameCount) * MICROS_PER_SECOND / mSampleRate;
@@ -120,6 +133,7 @@
}
void DriverStubImpl::shutdown() {
+ LOG_ENTRY();
mIsInitialized = false;
}
diff --git a/audio/aidl/default/stub/StreamOffloadStub.cpp b/audio/aidl/default/stub/StreamOffloadStub.cpp
index fb12697..95cef35 100644
--- a/audio/aidl/default/stub/StreamOffloadStub.cpp
+++ b/audio/aidl/default/stub/StreamOffloadStub.cpp
@@ -81,11 +81,13 @@
}
DriverOffloadStubImpl::DriverOffloadStubImpl(const StreamContext& context)
- : DriverStubImpl(context),
+ : DriverStubImpl(context, 0 /*asyncSleepTimeUs*/),
mState{context.getFormat().encoding, context.getSampleRate(),
250 /*earlyNotifyMs*/ * context.getSampleRate() / MILLIS_PER_SECOND,
static_cast<int64_t>(context.getBufferSizeInFrames()) / 2},
- mDspWorker(mState) {}
+ mDspWorker(mState) {
+ LOG_IF(FATAL, !mIsAsynchronous) << "The steam must be used in asynchronous mode";
+}
::android::status_t DriverOffloadStubImpl::init(DriverCallbackInterface* callback) {
RETURN_STATUS_IF_ERROR(DriverStubImpl::init(callback));
@@ -99,10 +101,7 @@
}
::android::status_t DriverOffloadStubImpl::drain(StreamDescriptor::DrainMode drainMode) {
- // Does not call into the DriverStubImpl::drain.
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
+ RETURN_STATUS_IF_ERROR(DriverStubImpl::drain(drainMode));
std::lock_guard l(mState.lock);
if (!mState.clipFramesLeft.empty()) {
// Cut playback of the current clip.
@@ -132,23 +131,27 @@
return ::android::OK;
}
+::android::status_t DriverOffloadStubImpl::start() {
+ RETURN_STATUS_IF_ERROR(DriverStubImpl::start());
+ RETURN_STATUS_IF_ERROR(startWorkerIfNeeded());
+ bool hasClips; // Can be start after paused draining.
+ {
+ std::lock_guard l(mState.lock);
+ hasClips = !mState.clipFramesLeft.empty();
+ LOG(DEBUG) << __func__
+ << ": clipFramesLeft: " << ::android::internal::ToString(mState.clipFramesLeft);
+ }
+ if (hasClips) {
+ mDspWorker.resume();
+ }
+ return ::android::OK;
+}
+
::android::status_t DriverOffloadStubImpl::transfer(void* buffer, size_t frameCount,
- size_t* actualFrameCount,
- int32_t* /*latencyMs*/) {
- // Does not call into the DriverStubImpl::transfer.
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
- if (mIsStandby) {
- LOG(FATAL) << __func__ << ": must not happen while in standby";
- }
- if (!mDspWorkerStarted) {
- // This is an "audio service thread," must have elevated priority.
- if (!mDspWorker.start("dsp_sim", ANDROID_PRIORITY_URGENT_AUDIO)) {
- return ::android::NO_INIT;
- }
- mDspWorkerStarted = true;
- }
+ size_t* actualFrameCount, int32_t* latencyMs) {
+ RETURN_STATUS_IF_ERROR(
+ DriverStubImpl::transfer(buffer, frameCount, actualFrameCount, latencyMs));
+ RETURN_STATUS_IF_ERROR(startWorkerIfNeeded());
// Scan the buffer for clip headers.
*actualFrameCount = frameCount;
while (buffer != nullptr && frameCount > 0) {
@@ -189,6 +192,18 @@
void DriverOffloadStubImpl::shutdown() {
LOG(DEBUG) << __func__ << ": stopping the DSP simulator worker";
mDspWorker.stop();
+ DriverStubImpl::shutdown();
+}
+
+::android::status_t DriverOffloadStubImpl::startWorkerIfNeeded() {
+ if (!mDspWorkerStarted) {
+ // This is an "audio service thread," must have elevated priority.
+ if (!mDspWorker.start("dsp_sim", ANDROID_PRIORITY_URGENT_AUDIO)) {
+ return ::android::NO_INIT;
+ }
+ mDspWorkerStarted = true;
+ }
+ return ::android::OK;
}
// static
diff --git a/audio/aidl/vts/VtsHalAECTargetTest.cpp b/audio/aidl/vts/VtsHalAECTargetTest.cpp
index c007f18..2fc126e 100644
--- a/audio/aidl/vts/VtsHalAECTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAECTargetTest.cpp
@@ -140,12 +140,12 @@
TEST_P(AECParamTest, SetAndGetEchoDelay) {
addEchoDelayParam(mEchoDelay);
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
}
TEST_P(AECParamTest, SetAndGetMobileMode) {
addMobileModeParam(mMobileMode);
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
}
std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
diff --git a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
index 72a2d5e..033cb9d 100644
--- a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
@@ -140,17 +140,17 @@
TEST_P(AGC1ParamTest, SetAndGetTargetPeakLevelParam) {
addTargetPeakLevelParam(mTargetPeakLevel);
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
}
TEST_P(AGC1ParamTest, SetAndGetMaxCompressionGain) {
addMaxCompressionGainParam(mMaxCompressionGain);
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
}
TEST_P(AGC1ParamTest, SetAndGetEnableLimiter) {
addEnableLimiterParam(mEnableLimiter);
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
}
std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
diff --git a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
index ccac8c5..9dec383 100644
--- a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
@@ -146,17 +146,17 @@
TEST_P(AGC2ParamTest, SetAndGetDigitalGainParam) {
addDigitalGainParam(mGain);
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
}
TEST_P(AGC2ParamTest, SetAndGetSaturationMargin) {
addSaturationMarginParam(mMargin);
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
}
TEST_P(AGC2ParamTest, SetAndGetLevelEstimator) {
addLevelEstimatorParam(mLevelEstimator);
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
}
std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
diff --git a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
index 7b15e5e..713af9a 100644
--- a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
@@ -367,8 +367,15 @@
auto criterionValue = criterionRule.criterionAndValue;
auto matchesWhen = criterionRule.matchingRule;
auto criteriaIt = find_if(criteria.begin(), criteria.end(), [&](const auto& criterion) {
+ auto getForceConfigTag = [](const AudioHalCapCriterionV2& forceConfig) {
+ return forceConfig.get<AudioHalCapCriterionV2::forceConfigForUse>()
+ .values[0].getTag();
+ };
return criterion.has_value() &&
- criterion.value().getTag() == selectionCriterion.getTag();
+ criterion.value().getTag() == selectionCriterion.getTag() &&
+ (criterion.value().getTag() != AudioHalCapCriterionV2::forceConfigForUse ||
+ getForceConfigTag(criterion.value()) ==
+ getForceConfigTag(selectionCriterion));
});
EXPECT_NE(criteriaIt, criteria.end())
<< " Invalid rule criterion " << toString(selectionCriterion.getTag());
@@ -515,7 +522,8 @@
std::unordered_set<std::string> configurationNames;
for (const AudioHalCapConfiguration& configuration : domain.configurations) {
EXPECT_TRUE(configurationNames.insert(configuration.name).second);
- ValidateAudioHalConfigurationRule(configuration.rule, criteria);
+ ASSERT_NO_FATAL_FAILURE(
+ ValidateAudioHalConfigurationRule(configuration.rule, criteria));
}
auto domainParameters = domain.configurations[0].parameterSettings;
for (const auto& settingParameter : domainParameters) {
@@ -590,7 +598,8 @@
}
EXPECT_NO_FATAL_FAILURE(ValidateAudioHalCapCriterion(criterion.value()));
}
- ValidateAudioHalCapDomains(capCfg.domains.value(), capCfg.criteriaV2.value());
+ ASSERT_NO_FATAL_FAILURE(
+ ValidateAudioHalCapDomains(capCfg.domains.value(), capCfg.criteriaV2.value()));
}
/**
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 8bbb60b..21b7aff 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -5012,7 +5012,7 @@
std::make_tuple(std::string("Pause"), kAidlVersion1, 0, StreamTypeFilter::SYNC,
makePauseCommands(false, true), false /*validatePositionIncrease*/);
static const NamedCommandSequence kPauseOutAsyncSeq =
- std::make_tuple(std::string("Pause"), kAidlVersion1, kStreamTransientStateTransitionDelayMs,
+ std::make_tuple(std::string("Pause"), kAidlVersion3, kStreamTransientStateTransitionDelayMs,
StreamTypeFilter::ASYNC, makePauseCommands(false, false),
false /*validatePositionIncrease*/);
@@ -5117,9 +5117,8 @@
kDrainOutSyncSeq, kDrainOutAsyncSeq,
kDrainEarlyOutAsyncSeq, kDrainPauseOutSyncSeq,
kDrainPauseOutAsyncSeq, kDrainEarlyPauseOutAsyncSeq,
- kStandbyOutSyncSeq, kStandbyOutAsyncSeq,
- kPauseOutSyncSeq, // kPauseOutAsyncSeq,
- kFlushOutSyncSeq, kFlushOutAsyncSeq,
+ kStandbyOutSyncSeq, kStandbyOutAsyncSeq, kPauseOutSyncSeq,
+ kPauseOutAsyncSeq, kFlushOutSyncSeq, kFlushOutAsyncSeq,
kDrainPauseFlushOutSyncSeq, kDrainPauseFlushOutAsyncSeq),
testing::Values(false, true)),
GetStreamIoTestName);
diff --git a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
index a19aa56..5621285 100644
--- a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
@@ -56,7 +56,7 @@
/// Effect factory testing.
class EffectFactoryTest : public testing::TestWithParam<std::string> {
public:
- void SetUp() override { connectAndGetFactory(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(connectAndGetFactory()); }
void TearDown() override {
for (auto& effect : mEffects) {
@@ -253,7 +253,7 @@
creatAndDestroyDescs(descs);
restartAndGetFactory();
- connectAndGetFactory();
+ ASSERT_NO_FATAL_FAILURE(connectAndGetFactory());
creatAndDestroyDescs(descs);
}
@@ -265,7 +265,7 @@
std::vector<std::shared_ptr<IEffect>> effects = createWithDescs(descs);
restartAndGetFactory();
- connectAndGetFactory();
+ ASSERT_NO_FATAL_FAILURE(connectAndGetFactory());
destroyEffects(effects, EX_ILLEGAL_ARGUMENT);
}
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
index 5c5be3a..720a040 100644
--- a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -190,7 +190,7 @@
std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
}
- void SetUp() override { SetUpDownmix(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDownmix()); }
void TearDown() override { TearDownDownmix(); }
@@ -216,7 +216,7 @@
void SetUp() override {
SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
- SetUpDownmix(mInputChannelLayout);
+ ASSERT_NO_FATAL_FAILURE(SetUpDownmix(mInputChannelLayout));
if (int32_t version;
mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
GTEST_SKIP() << "Skipping the data test for version: " << version << "\n";
@@ -288,7 +288,7 @@
case AudioChannelLayout::CHANNEL_TOP_BACK_LEFT:
case AudioChannelLayout::CHANNEL_FRONT_WIDE_LEFT:
case AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT:
- checkAtLeft(position);
+ ASSERT_NO_FATAL_FAILURE(checkAtLeft(position));
break;
case AudioChannelLayout::CHANNEL_FRONT_RIGHT:
@@ -300,7 +300,7 @@
case AudioChannelLayout::CHANNEL_FRONT_WIDE_RIGHT:
case AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT:
case AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2:
- checkAtRight(position);
+ ASSERT_NO_FATAL_FAILURE(checkAtRight(position));
break;
case AudioChannelLayout::CHANNEL_FRONT_CENTER:
@@ -311,17 +311,17 @@
case AudioChannelLayout::CHANNEL_FRONT_RIGHT_OF_CENTER:
case AudioChannelLayout::CHANNEL_TOP_CENTER:
case AudioChannelLayout::CHANNEL_TOP_BACK_CENTER:
- checkAtCenter(position);
+ ASSERT_NO_FATAL_FAILURE(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);
+ ASSERT_NO_FATAL_FAILURE(checkAtLeft(position));
} else {
// Validate that both channels have audio
- checkAtCenter(position);
+ ASSERT_NO_FATAL_FAILURE(checkAtCenter(position));
}
break;
}
@@ -371,7 +371,7 @@
}
void SetUp() override {
- SetUpDownmix(mInputChannelLayout);
+ ASSERT_NO_FATAL_FAILURE(SetUpDownmix(mInputChannelLayout));
if (int32_t version;
mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
GTEST_SKIP() << "Skipping the data test for version: " << version << "\n";
@@ -406,7 +406,7 @@
mInputChannelCount /*channelCount*/, kMaxDownmixSample);
ASSERT_NO_FATAL_FAILURE(
processAndWriteToOutput(mInputBuffer, mOutputBuffer, mEffect, &mOpenEffectReturn));
- validateOutput();
+ ASSERT_NO_FATAL_FAILURE(validateOutput());
}
INSTANTIATE_TEST_SUITE_P(
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
index 95bcaf0..2ce7b51 100644
--- a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -39,6 +39,8 @@
using aidl::android::hardware::audio::effect::Parameter;
using android::hardware::audio::common::testing::detail::TestExecutionTracer;
+constexpr int32_t kMinDataTestHalVersion = 3;
+
/**
* Here we focus on specific parameter checking, general IEffect interfaces testing performed in
* VtsAudioEffectTargetTest.
@@ -120,6 +122,14 @@
float calculateDb(const std::vector<float>& input, size_t startSamplePos);
+ void getMagnitudeValue(const std::vector<float>& output, std::vector<float>& bufferMag);
+
+ void checkInputAndOutputEquality(const std::vector<float>& outputMag);
+
+ void setUpDataTest(const std::vector<int>& testFrequencies, float fullScaleSineDb);
+
+ void createChannelConfig();
+
// enqueue test parameters
void addEngineConfig(const DynamicsProcessing::EngineArchitecture& cfg);
void addPreEqChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
@@ -131,13 +141,32 @@
void addLimiterConfig(const std::vector<DynamicsProcessing::LimiterConfig>& cfg);
void addInputGain(const std::vector<DynamicsProcessing::InputGain>& inputGain);
+ void checkHalVersion();
+
static constexpr float kPreferredProcessingDurationMs = 10.0f;
static constexpr int kBandCount = 5;
static constexpr int kSamplingFrequency = 44100;
static constexpr int kFrameCount = 2048;
static constexpr int kInputFrequency = 1000;
static constexpr size_t kStartIndex = 15 * kSamplingFrequency / 1000; // skip 15ms
- static constexpr float kToleranceDb = 0.05;
+ static constexpr float kToleranceDb = 0.5;
+ static constexpr int kNPointFFT = 1024;
+ static constexpr float kBinWidth = (float)kSamplingFrequency / kNPointFFT;
+ // Full scale sine wave with 1000 Hz frequency is -3 dB
+ static constexpr float kSineFullScaleDb = -3;
+ // Full scale sine wave with 100 Hz and 1000 Hz frequency is -6 dB
+ static constexpr float kSineMultitoneFullScaleDb = -6;
+ const std::vector<int> kCutoffFreqHz = {200 /*0th band cutoff*/, 2000 /*1st band cutoff*/};
+ std::vector<int> mMultitoneTestFrequencies = {100, 1000};
+ // Calculating normalizing factor by dividing the number of FFT points by half and the number of
+ // test frequencies. The normalization accounts for the FFT splitting the signal into positive
+ // and negative frequencies. Additionally, during multi-tone input generation, sample values are
+ // normalized to the range [-1, 1] by dividing them by the number of test frequencies.
+ float mNormalizingFactor = (kNPointFFT / (2 * mMultitoneTestFrequencies.size()));
+ std::vector<int> mBinOffsets;
+ std::vector<DynamicsProcessing::ChannelConfig> mChannelConfig;
+ std::vector<float> mInput;
+ float mInputDb;
std::shared_ptr<IFactory> mFactory;
std::shared_ptr<IEffect> mEffect;
Descriptor mDescriptor;
@@ -416,6 +445,38 @@
}
}
+void DynamicsProcessingTestHelper::getMagnitudeValue(const std::vector<float>& output,
+ std::vector<float>& bufferMag) {
+ std::vector<float> subOutput(output.begin() + kStartIndex, output.end());
+ EXPECT_NO_FATAL_FAILURE(calculateMagnitudeMono(bufferMag, subOutput, mBinOffsets, kNPointFFT));
+}
+
+void DynamicsProcessingTestHelper::checkInputAndOutputEquality(
+ const std::vector<float>& outputMag) {
+ std::vector<float> inputMag(mBinOffsets.size());
+ EXPECT_NO_FATAL_FAILURE(getMagnitudeValue(mInput, inputMag));
+ for (size_t i = 0; i < inputMag.size(); i++) {
+ EXPECT_NEAR(calculateDb({inputMag[i] / mNormalizingFactor}),
+ calculateDb({outputMag[i] / mNormalizingFactor}), kToleranceDb);
+ }
+}
+
+void DynamicsProcessingTestHelper::setUpDataTest(const std::vector<int>& testFrequencies,
+ float fullScaleSineDb) {
+ ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect());
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ ASSERT_NO_FATAL_FAILURE(
+ generateSineWave(testFrequencies, mInput, 1.0, kSamplingFrequency, mChannelLayout));
+ mInputDb = calculateDb(mInput);
+ ASSERT_NEAR(mInputDb, fullScaleSineDb, kToleranceDb);
+}
+
+void DynamicsProcessingTestHelper::createChannelConfig() {
+ for (int i = 0; i < mChannelCount; i++) {
+ mChannelConfig.push_back(DynamicsProcessing::ChannelConfig(i, true));
+ }
+}
+
void DynamicsProcessingTestHelper::addEngineConfig(
const DynamicsProcessing::EngineArchitecture& cfg) {
DynamicsProcessing dp;
@@ -491,6 +552,13 @@
mTags.push_back({DynamicsProcessing::inputGain, dp});
}
+void DynamicsProcessingTestHelper::checkHalVersion() {
+ if (int32_t version;
+ mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
+ GTEST_SKIP() << "Skipping the data test for version: " << version << "\n";
+ }
+}
+
void fillLimiterConfig(std::vector<DynamicsProcessing::LimiterConfig>& limiterConfigList,
int channelIndex, bool enable, int linkGroup, float attackTime,
float releaseTime, float ratio, float threshold, float postGain) {
@@ -527,6 +595,15 @@
.postGainDb = postGainDb};
}
+DynamicsProcessing::EqBandConfig creatEqBandConfig(int channel, int band, float cutOffFreqHz,
+ float gainDb, bool enable) {
+ return DynamicsProcessing::EqBandConfig{.channel = channel,
+ .band = band,
+ .enable = enable,
+ .cutoffFrequencyHz = cutOffFreqHz,
+ .gainDb = gainDb};
+}
+
/**
* Test DynamicsProcessing Engine Configuration
*/
@@ -558,7 +635,7 @@
fillEngineArchConfig(mCfg, GetParam());
};
- void SetUp() override { SetUpDynamicsProcessingEffect(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -610,7 +687,7 @@
: DynamicsProcessingTestHelper(std::get<INPUT_GAIN_INSTANCE_NAME>(GetParam())),
mInputGain(std::get<INPUT_GAIN_PARAM>(GetParam())) {};
- void SetUp() override { SetUpDynamicsProcessingEffect(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -650,11 +727,8 @@
}
void SetUp() override {
- SetUpDynamicsProcessingEffect();
- SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
- ASSERT_NO_FATAL_FAILURE(generateSineWave(kInputFrequency /*Input Frequency*/, mInput, 1.0,
- kSamplingFrequency, mChannelLayout));
- mInputDb = calculateDb(mInput);
+ ASSERT_NO_FATAL_FAILURE(
+ setUpDataTest({static_cast<int>(kInputFrequency)}, kSineFullScaleDb));
}
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -665,8 +739,6 @@
}
std::vector<DynamicsProcessing::InputGain> mInputGain;
- std::vector<float> mInput;
- float mInputDb;
};
TEST_P(DynamicsProcessingInputGainDataTest, SetAndGetInputGain) {
@@ -735,7 +807,7 @@
fillLimiterConfig(mLimiterConfigList, GetParam());
}
- void SetUp() override { SetUpDynamicsProcessingEffect(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -786,12 +858,8 @@
}
void SetUp() override {
- SetUpDynamicsProcessingEffect();
- SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
ASSERT_NO_FATAL_FAILURE(
- generateSineWave(kInputFrequency, mInput, 1.0, kSamplingFrequency, mChannelLayout));
- mInputDb = calculateDb(mInput);
- ASSERT_NEAR(mInputDb, kSineFullScaleDb, kToleranceDb);
+ setUpDataTest({static_cast<int>(kInputFrequency)}, kSineFullScaleDb));
}
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -825,11 +893,8 @@
static constexpr float kDefaultThreshold = -10;
static constexpr float kDefaultPostGain = 0;
static constexpr float kInputFrequency = 1000;
- // Full scale sine wave with 1000 Hz frequency is -3 dB
- static constexpr float kSineFullScaleDb = -3;
+ static constexpr float kLimiterTestToleranceDb = 0.05;
std::vector<DynamicsProcessing::LimiterConfig> mLimiterConfigList;
- std::vector<float> mInput;
- float mInputDb;
int mBufferSize;
};
@@ -849,7 +914,7 @@
}
float outputDb = calculateDb(output, kStartIndex);
if (threshold >= mInputDb || kDefaultRatio == 1) {
- EXPECT_NEAR(mInputDb, outputDb, kToleranceDb);
+ EXPECT_NEAR(mInputDb, outputDb, kLimiterTestToleranceDb);
} else {
float calculatedThreshold = 0;
ASSERT_NO_FATAL_FAILURE(computeThreshold(kDefaultRatio, outputDb, calculatedThreshold));
@@ -876,7 +941,7 @@
float outputDb = calculateDb(output, kStartIndex);
if (kDefaultThreshold >= mInputDb) {
- EXPECT_NEAR(mInputDb, outputDb, kToleranceDb);
+ EXPECT_NEAR(mInputDb, outputDb, kLimiterTestToleranceDb);
} else {
float calculatedRatio = 0;
ASSERT_NO_FATAL_FAILURE(computeRatio(kDefaultThreshold, outputDb, calculatedRatio));
@@ -894,7 +959,7 @@
ASSERT_NO_FATAL_FAILURE(generateSineWave(kInputFrequency, mInput, dBToAmplitude(postGainDb),
kSamplingFrequency, mChannelLayout));
mInputDb = calculateDb(mInput);
- EXPECT_NEAR(mInputDb, kSineFullScaleDb - postGainDb, kToleranceDb);
+ EXPECT_NEAR(mInputDb, kSineFullScaleDb - postGainDb, kLimiterTestToleranceDb);
for (int i = 0; i < mChannelCount; i++) {
fillLimiterConfig(mLimiterConfigList, i, true, kDefaultLinkerGroup, kDefaultAttackTime,
kDefaultReleaseTime, 1, kDefaultThreshold, postGainDb);
@@ -904,7 +969,7 @@
continue;
}
float outputDb = calculateDb(output, kStartIndex);
- EXPECT_NEAR(outputDb, mInputDb + postGainDb, kToleranceDb)
+ EXPECT_NEAR(outputDb, mInputDb + postGainDb, kLimiterTestToleranceDb)
<< "PostGain: " << postGainDb << ", OutputDb: " << outputDb;
}
}
@@ -927,7 +992,7 @@
if (isEnabled) {
EXPECT_NE(mInputDb, calculateDb(output, kStartIndex));
} else {
- EXPECT_NEAR(mInputDb, calculateDb(output, kStartIndex), kToleranceDb);
+ EXPECT_NEAR(mInputDb, calculateDb(output, kStartIndex), kLimiterTestToleranceDb);
}
}
}
@@ -963,7 +1028,7 @@
: DynamicsProcessingTestHelper(std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(GetParam())),
mCfg(std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(GetParam())) {}
- void SetUp() override { SetUpDynamicsProcessingEffect(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -1025,13 +1090,10 @@
const EqBandConfigTestParams& params) {
const std::vector<std::pair<int, float>> cutOffFreqs = std::get<EQ_BAND_CUT_OFF_FREQ>(params);
int bandCount = cutOffFreqs.size();
- cfgs.resize(bandCount);
for (int i = 0; i < bandCount; i++) {
- cfgs[i].channel = std::get<EQ_BAND_CHANNEL>(params);
- cfgs[i].band = cutOffFreqs[i].first;
- cfgs[i].enable = true /*Eqband Enable*/;
- cfgs[i].cutoffFrequencyHz = cutOffFreqs[i].second;
- cfgs[i].gainDb = std::get<EQ_BAND_GAIN>(params);
+ cfgs.push_back(creatEqBandConfig(std::get<EQ_BAND_CHANNEL>(params), cutOffFreqs[i].first,
+ cutOffFreqs[i].second, std::get<EQ_BAND_GAIN>(params),
+ true));
}
}
@@ -1043,7 +1105,7 @@
fillEqBandConfig(mCfgs, GetParam());
}
- void SetUp() override { SetUpDynamicsProcessingEffect(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -1147,6 +1209,130 @@
});
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestEqBandConfig);
+class DynamicsProcessingEqBandConfigDataTest
+ : public ::testing::TestWithParam<std::pair<std::shared_ptr<IFactory>, Descriptor>>,
+ public DynamicsProcessingTestHelper {
+ public:
+ DynamicsProcessingEqBandConfigDataTest()
+ : DynamicsProcessingTestHelper(GetParam(), AudioChannelLayout::LAYOUT_MONO) {
+ mInput.resize(kFrameCount * mChannelCount);
+ mBinOffsets.resize(mMultitoneTestFrequencies.size());
+ }
+
+ void SetUp() override {
+ ASSERT_NO_FATAL_FAILURE(
+ setUpDataTest(mMultitoneTestFrequencies, kSineMultitoneFullScaleDb));
+ }
+
+ void TearDown() override { TearDownDynamicsProcessingEffect(); }
+
+ void addEqParam(bool isPreEq) {
+ createChannelConfig();
+ auto stage = isPreEq ? mEngineConfigPreset.preEqStage : mEngineConfigPreset.postEqStage;
+ stage.bandCount = mCfgs.size();
+ addEngineConfig(mEngineConfigPreset);
+ isPreEq ? addPreEqChannelConfig(mChannelConfig) : addPostEqChannelConfig(mChannelConfig);
+ isPreEq ? addPreEqBandConfigs(mCfgs) : addPostEqBandConfigs(mCfgs);
+ }
+
+ void setEqParamAndProcess(std::vector<float>& output, bool isPreEq) {
+ addEqParam(isPreEq);
+ ASSERT_NO_FATAL_FAILURE(setParamsAndProcess(mInput, output));
+ }
+
+ void fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig>& cfgs, int channelIndex,
+ int bandIndex, int cutOffFreqHz, float gainDb, bool enable) {
+ cfgs.push_back(creatEqBandConfig(channelIndex, bandIndex, static_cast<float>(cutOffFreqHz),
+ gainDb, enable));
+ }
+
+ void validateOutput(const std::vector<float>& output, float gainDb, size_t bandIndex,
+ bool enable) {
+ std::vector<float> outputMag(mBinOffsets.size());
+ EXPECT_NO_FATAL_FAILURE(getMagnitudeValue(output, outputMag));
+ if (gainDb == 0 || !enable) {
+ EXPECT_NO_FATAL_FAILURE(checkInputAndOutputEquality(outputMag));
+ } else if (gainDb > 0) {
+ // For positive gain, current band's magnitude is greater than the other band's
+ // magnitude
+ EXPECT_GT(outputMag[bandIndex], outputMag[bandIndex ^ 1]);
+ } else {
+ // For negative gain, current band's magnitude is less than the other band's magnitude
+ EXPECT_LT(outputMag[bandIndex], outputMag[bandIndex ^ 1]);
+ }
+ }
+
+ void analyseMultiBandOutput(float gainDb, bool isPreEq, bool enable = true) {
+ std::vector<float> output(mInput.size());
+ roundToFreqCenteredToFftBin(mMultitoneTestFrequencies, mBinOffsets, kBinWidth);
+ // Set Equalizer values for two bands
+ for (size_t i = 0; i < kCutoffFreqHz.size(); i++) {
+ for (int channelIndex = 0; channelIndex < mChannelCount; channelIndex++) {
+ fillEqBandConfig(mCfgs, channelIndex, i, kCutoffFreqHz[i], gainDb, enable);
+ fillEqBandConfig(mCfgs, channelIndex, i ^ 1, kCutoffFreqHz[i ^ 1], 0, enable);
+ }
+ ASSERT_NO_FATAL_FAILURE(setEqParamAndProcess(output, isPreEq));
+
+ if (isAllParamsValid()) {
+ ASSERT_NO_FATAL_FAILURE(validateOutput(output, gainDb, i, enable));
+ }
+ cleanUpEqConfig();
+ }
+ }
+
+ void cleanUpEqConfig() {
+ CleanUp();
+ mCfgs.clear();
+ mChannelConfig.clear();
+ }
+
+ const std::vector<float> kTestGainDbValues = {-200, -100, 0, 100, 200};
+ std::vector<DynamicsProcessing::EqBandConfig> mCfgs;
+};
+
+TEST_P(DynamicsProcessingEqBandConfigDataTest, IncreasingPreEqGain) {
+ for (float gainDb : kTestGainDbValues) {
+ ASSERT_NO_FATAL_FAILURE(generateSineWave(mMultitoneTestFrequencies, mInput,
+ dBToAmplitude(gainDb), kSamplingFrequency,
+ mChannelLayout));
+ cleanUpEqConfig();
+ ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(gainDb, true /*pre-equalizer*/));
+ }
+}
+
+TEST_P(DynamicsProcessingEqBandConfigDataTest, IncreasingPostEqGain) {
+ for (float gainDb : kTestGainDbValues) {
+ ASSERT_NO_FATAL_FAILURE(generateSineWave(mMultitoneTestFrequencies, mInput,
+ dBToAmplitude(gainDb), kSamplingFrequency,
+ mChannelLayout));
+ cleanUpEqConfig();
+ ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(gainDb, false /*post-equalizer*/));
+ }
+}
+
+TEST_P(DynamicsProcessingEqBandConfigDataTest, PreEqEnableDisable) {
+ ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(10 /*gain dB*/, true /*pre-equalizer*/,
+ false /*disable equalizer*/));
+}
+
+TEST_P(DynamicsProcessingEqBandConfigDataTest, PostEqEnableDisable) {
+ ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(10 /*gain dB*/, false /*post-equalizer*/,
+ false /*disable equalizer*/));
+}
+
+INSTANTIATE_TEST_SUITE_P(DynamicsProcessingTest, DynamicsProcessingEqBandConfigDataTest,
+ testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+ [](const auto& info) {
+ auto descriptor = info.param;
+ std::string name = getPrefix(descriptor.second);
+ std::replace_if(
+ name.begin(), name.end(),
+ [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingEqBandConfigDataTest);
+
/**
* Test DynamicsProcessing MbcBandConfig
*/
@@ -1211,7 +1397,7 @@
fillMbcBandConfig(mCfgs, GetParam());
}
- void SetUp() override { SetUpDynamicsProcessingEffect(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -1259,24 +1445,18 @@
DynamicsProcessingMbcBandConfigDataTest()
: DynamicsProcessingTestHelper(GetParam(), AudioChannelLayout::LAYOUT_MONO) {
mInput.resize(kFrameCount * mChannelCount);
- mBinOffsets.resize(mTestFrequencies.size());
+ mBinOffsets.resize(mMultitoneTestFrequencies.size());
}
void SetUp() override {
- SetUpDynamicsProcessingEffect();
- SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
- ASSERT_NO_FATAL_FAILURE(generateSineWave(mTestFrequencies, mInput, 1.0, kSamplingFrequency,
- mChannelLayout));
- mInputDb = calculateDb(mInput);
- ASSERT_NEAR(mInputDb, kFullScaleDb, kToleranceDb);
+ ASSERT_NO_FATAL_FAILURE(
+ setUpDataTest(mMultitoneTestFrequencies, kSineMultitoneFullScaleDb));
}
void TearDown() override { TearDownDynamicsProcessingEffect(); }
void setMbcParamsAndProcess(std::vector<float>& output) {
- for (int i = 0; i < mChannelCount; i++) {
- mChannelConfig.push_back(DynamicsProcessing::ChannelConfig(i, true));
- }
+ createChannelConfig();
mEngineConfigPreset.mbcStage.bandCount = mCfgs.size();
addEngineConfig(mEngineConfigPreset);
addMbcChannelConfig(mChannelConfig);
@@ -1293,23 +1473,12 @@
noiseGate, expanderRatio, preGain, postGain));
}
- void getMagnitudeValue(const std::vector<float>& output, std::vector<float>& bufferMag) {
- std::vector<float> subOutput(output.begin() + kStartIndex, output.end());
- EXPECT_NO_FATAL_FAILURE(
- calculateMagnitudeMono(bufferMag, subOutput, mBinOffsets, kNPointFFT));
- }
-
void validateOutput(const std::vector<float>& output, float threshold, float ratio,
size_t bandIndex) {
std::vector<float> outputMag(mBinOffsets.size());
EXPECT_NO_FATAL_FAILURE(getMagnitudeValue(output, outputMag));
if (threshold >= mInputDb || ratio == 1) {
- std::vector<float> inputMag(mBinOffsets.size());
- EXPECT_NO_FATAL_FAILURE(getMagnitudeValue(mInput, inputMag));
- for (size_t i = 0; i < inputMag.size(); i++) {
- EXPECT_NEAR(calculateDb({inputMag[i] / mNormalizingFactor}),
- calculateDb({outputMag[i] / mNormalizingFactor}), kToleranceDb);
- }
+ EXPECT_NO_FATAL_FAILURE(checkInputAndOutputEquality(outputMag));
} else {
// Current band's magnitude is less than the other band's magnitude
EXPECT_LT(outputMag[bandIndex], outputMag[bandIndex ^ 1]);
@@ -1318,17 +1487,16 @@
void analyseMultiBandOutput(float threshold, float ratio) {
std::vector<float> output(mInput.size());
- roundToFreqCenteredToFftBin(mTestFrequencies, mBinOffsets, kBinWidth);
- std::vector<int> cutoffFreqHz = {200 /*0th band cutoff*/, 2000 /*1st band cutoff*/};
+ roundToFreqCenteredToFftBin(mMultitoneTestFrequencies, mBinOffsets, kBinWidth);
// Set MBC values for two bands
- for (size_t i = 0; i < cutoffFreqHz.size(); i++) {
+ for (size_t i = 0; i < kCutoffFreqHz.size(); i++) {
for (int channelIndex = 0; channelIndex < mChannelCount; channelIndex++) {
fillMbcBandConfig(mCfgs, channelIndex, threshold, ratio, kDefaultNoiseGateDb,
- kDefaultExpanderRatio, i, cutoffFreqHz[i], kDefaultPreGainDb,
+ kDefaultExpanderRatio, i, kCutoffFreqHz[i], kDefaultPreGainDb,
kDefaultPostGainDb);
fillMbcBandConfig(mCfgs, channelIndex, kDefaultThresholdDb, kDefaultRatio,
kDefaultNoiseGateDb, kDefaultExpanderRatio, i ^ 1,
- cutoffFreqHz[i ^ 1], kDefaultPreGainDb, kDefaultPostGainDb);
+ kCutoffFreqHz[i ^ 1], kDefaultPreGainDb, kDefaultPostGainDb);
}
ASSERT_NO_FATAL_FAILURE(setMbcParamsAndProcess(output));
@@ -1345,8 +1513,6 @@
mChannelConfig.clear();
}
- static constexpr int kNPointFFT = 1024;
- static constexpr float kToleranceDb = 0.5;
static constexpr float kDefaultPostGainDb = 0;
static constexpr float kDefaultPreGainDb = 0;
static constexpr float kDefaultAttackTime = 0;
@@ -1356,20 +1522,7 @@
static constexpr float kDefaultNoiseGateDb = -10;
static constexpr float kDefaultExpanderRatio = 1;
static constexpr float kDefaultRatio = 1;
- static constexpr float kBinWidth = (float)kSamplingFrequency / kNPointFFT;
- // Full scale sine wave with 100 Hz and 1000 Hz frequency is -6 dB
- static constexpr float kFullScaleDb = -6;
- std::vector<int> mTestFrequencies = {100, 1000};
- // Calculating normalizing factor by dividing the number of FFT points by half and the number of
- // test frequencies. The normalization accounts for the FFT splitting the signal into positive
- // and negative frequencies. Additionally, during multi-tone input generation, sample values are
- // normalized to the range [-1, 1] by dividing them by the number of test frequencies.
- float mNormalizingFactor = (kNPointFFT / (2 * mTestFrequencies.size()));
std::vector<DynamicsProcessing::MbcBandConfig> mCfgs;
- std::vector<DynamicsProcessing::ChannelConfig> mChannelConfig;
- std::vector<int> mBinOffsets;
- std::vector<float> mInput;
- float mInputDb;
};
TEST_P(DynamicsProcessingMbcBandConfigDataTest, IncreasingThreshold) {
@@ -1396,11 +1549,11 @@
std::vector<float> postGainDbValues = {-55, -30, 0, 30, 55};
std::vector<float> output(mInput.size());
for (float postGainDb : postGainDbValues) {
- ASSERT_NO_FATAL_FAILURE(generateSineWave(mTestFrequencies, mInput,
+ ASSERT_NO_FATAL_FAILURE(generateSineWave(mMultitoneTestFrequencies, mInput,
dBToAmplitude(postGainDb), kSamplingFrequency,
mChannelLayout));
mInputDb = calculateDb(mInput);
- EXPECT_NEAR(mInputDb, kFullScaleDb - postGainDb, kToleranceDb);
+ EXPECT_NEAR(mInputDb, kSineMultitoneFullScaleDb - postGainDb, kToleranceDb);
cleanUpMbcConfig();
for (int i = 0; i < mChannelCount; i++) {
fillMbcBandConfig(mCfgs, i, kDefaultThresholdDb, kDefaultRatio, kDefaultNoiseGateDb,
@@ -1417,6 +1570,51 @@
}
}
+TEST_P(DynamicsProcessingMbcBandConfigDataTest, IncreasingPreGain) {
+ /*
+ Depending on the pregain values, samples undergo either compression or expansion process.
+ At -6 dB input,
+ - Expansion is expected at -60 dB,
+ - Compression at 10, 34 and 60 dB
+ - No compression or expansion at -34, -10, -1 dB.
+ */
+ std::vector<float> preGainDbValues = {-60, -34, -10, -1, 10, 34, 60};
+ std::vector<float> output(mInput.size());
+ float thresholdDb = -7;
+ float noiseGateDb = -40;
+ std::vector<float> ratioValues = {1, 1.5, 2, 2.5, 3};
+ for (float ratio : ratioValues) {
+ for (float preGainDb : preGainDbValues) {
+ float expectedOutputDb;
+ float inputWithPreGain = mInputDb + preGainDb;
+ if (inputWithPreGain > thresholdDb) {
+ SCOPED_TRACE("Compressor ratio: " + std::to_string(ratio));
+ expectedOutputDb =
+ (inputWithPreGain - thresholdDb) / ratio + thresholdDb - preGainDb;
+ } else if (inputWithPreGain < noiseGateDb) {
+ SCOPED_TRACE("Expander ratio: " + std::to_string(ratio));
+ expectedOutputDb =
+ (inputWithPreGain - noiseGateDb) * ratio + noiseGateDb - preGainDb;
+ } else {
+ expectedOutputDb = mInputDb;
+ }
+ cleanUpMbcConfig();
+ for (int i = 0; i < mChannelCount; i++) {
+ fillMbcBandConfig(mCfgs, i, thresholdDb, ratio /*compressor ratio*/, noiseGateDb,
+ ratio /*expander ratio*/, 0 /*band index*/,
+ 2000 /*cutoffFrequency*/, preGainDb, kDefaultPostGainDb);
+ }
+ EXPECT_NO_FATAL_FAILURE(setMbcParamsAndProcess(output));
+ if (!isAllParamsValid()) {
+ continue;
+ }
+ float outputDb = calculateDb(output, kStartIndex);
+ EXPECT_NEAR(outputDb, expectedOutputDb, kToleranceDb)
+ << "PreGain: " << preGainDb << ", OutputDb: " << outputDb;
+ }
+ }
+}
+
INSTANTIATE_TEST_SUITE_P(DynamicsProcessingTest, DynamicsProcessingMbcBandConfigDataTest,
testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index 0222923..9b1a3b3 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -305,7 +305,7 @@
: EnvironmentalReverbHelper(std::get<DESCRIPTOR_INDEX>(GetParam())) {
std::tie(mTag, mParamValue) = std::get<TAG_VALUE_PAIR>(GetParam());
}
- void SetUp() override { SetUpReverb(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpReverb()); }
void TearDown() override { TearDownReverb(); }
EnvironmentalReverb::Tag mTag;
@@ -350,7 +350,7 @@
SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
ASSERT_NO_FATAL_FAILURE(
generateSineWave(kInputFrequency, mInput, 1.0, kSamplingFrequency, mChannelLayout));
- SetUpReverb();
+ ASSERT_NO_FATAL_FAILURE(SetUpReverb());
}
void TearDown() override {
SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
@@ -387,11 +387,11 @@
};
TEST_P(EnvironmentalReverbDataTest, IncreasingParamValue) {
- assertEnergyIncreasingWithParameter(false);
+ ASSERT_NO_FATAL_FAILURE(assertEnergyIncreasingWithParameter(false));
}
TEST_P(EnvironmentalReverbDataTest, WithBypassEnabled) {
- assertZeroEnergyWithBypass(true);
+ ASSERT_NO_FATAL_FAILURE(assertZeroEnergyWithBypass(true));
}
INSTANTIATE_TEST_SUITE_P(
@@ -420,7 +420,7 @@
}
void SetUp() override {
SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
- SetUpReverb();
+ ASSERT_NO_FATAL_FAILURE(SetUpReverb());
createEnvParam(EnvironmentalReverb::roomLevelMb, kMinRoomLevel);
ASSERT_NO_FATAL_FAILURE(
setAndVerifyParam(EX_NONE, mEnvParam, EnvironmentalReverb::roomLevelMb));
@@ -478,7 +478,7 @@
SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
ASSERT_NO_FATAL_FAILURE(
generateSineWave(kInputFrequency, mInput, 1.0, kSamplingFrequency, mChannelLayout));
- SetUpReverb();
+ ASSERT_NO_FATAL_FAILURE(SetUpReverb());
}
void TearDown() override {
SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
@@ -559,7 +559,7 @@
ASSERT_NO_FATAL_FAILURE(generateSineWave(kInputFrequency, mInput, 1.0,
kSamplingFrequency, mChannelLayout));
}
- SetUpReverb();
+ ASSERT_NO_FATAL_FAILURE(SetUpReverb());
}
void TearDown() override {
SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index ace0597..b1515bc 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -133,7 +133,7 @@
std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
}
- void SetUp() override { SetUpLoudnessEnhancer(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpLoudnessEnhancer()); }
void TearDown() override { TearDownLoudnessEnhancer(); }
int mParamGainMb = 0;
};
@@ -164,7 +164,7 @@
void SetUp() override {
SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
- SetUpLoudnessEnhancer();
+ ASSERT_NO_FATAL_FAILURE(SetUpLoudnessEnhancer());
// Creating AidlMessageQueues
mStatusMQ = std::make_unique<EffectHelper::StatusMQ>(mOpenEffectReturn.statusMQ);
@@ -255,13 +255,13 @@
TEST_P(LoudnessEnhancerDataTest, IncreasingGains) {
static const std::vector<int> kIncreasingGains = {50, 100};
- assertSequentialGains(kIncreasingGains, true /*isIncreasing*/);
+ ASSERT_NO_FATAL_FAILURE(assertSequentialGains(kIncreasingGains, true /*isIncreasing*/));
}
TEST_P(LoudnessEnhancerDataTest, DecreasingGains) {
static const std::vector<int> kDecreasingGains = {-50, -100};
- assertSequentialGains(kDecreasingGains, false /*isIncreasing*/);
+ ASSERT_NO_FATAL_FAILURE(assertSequentialGains(kDecreasingGains, false /*isIncreasing*/));
}
TEST_P(LoudnessEnhancerDataTest, MinimumGain) {
diff --git a/audio/aidl/vts/VtsHalNSTargetTest.cpp b/audio/aidl/vts/VtsHalNSTargetTest.cpp
index c5a9bad..0618048 100644
--- a/audio/aidl/vts/VtsHalNSTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalNSTargetTest.cpp
@@ -141,12 +141,12 @@
TEST_P(NSParamTest, SetAndGetLevel) {
addLevelParam(mLevel);
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
}
TEST_P(NSParamTest, SetAndGetType) {
addLevelParam(mLevel);
- SetAndGetParameters();
+ ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
}
INSTANTIATE_TEST_SUITE_P(
diff --git a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
index f127c81..3fbda96 100644
--- a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
@@ -187,13 +187,13 @@
std::vector<PresetReverb::Presets> roomPresets = {PresetReverb::Presets::LARGEROOM,
PresetReverb::Presets::MEDIUMROOM,
PresetReverb::Presets::SMALLROOM};
- validateIncreasingEnergy(roomPresets);
+ ASSERT_NO_FATAL_FAILURE(validateIncreasingEnergy(roomPresets));
}
TEST_P(PresetReverbProcessTest, DecreasingHallSize) {
std::vector<PresetReverb::Presets> hallPresets = {PresetReverb::Presets::LARGEHALL,
PresetReverb::Presets::MEDIUMHALL};
- validateIncreasingEnergy(hallPresets);
+ ASSERT_NO_FATAL_FAILURE(validateIncreasingEnergy(hallPresets));
}
TEST_P(PresetReverbProcessTest, PresetPlate) {
diff --git a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
index f019e2a..586ed67 100644
--- a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
@@ -183,7 +183,7 @@
generateInputBuffer(mInputBuffer, 0, true, mChannelCount, kMaxAudioSampleValue);
}
- void SetUp() override { SetUpVisualizer(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpVisualizer()); }
void TearDown() override { TearDownVisualizer(); }
@@ -252,7 +252,7 @@
std::get<PARAM_SCALING_MODE>(GetParam()),
std::get<PARAM_MEASUREMENT_MODE>(GetParam())) {}
- void SetUp() override { SetUpVisualizer(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpVisualizer()); }
void TearDown() override { TearDownVisualizer(); }
};
diff --git a/bluetooth/aidl/Android.bp b/bluetooth/aidl/Android.bp
index 4ee2f49..0daecf7 100644
--- a/bluetooth/aidl/Android.bp
+++ b/bluetooth/aidl/Android.bp
@@ -16,6 +16,13 @@
srcs: ["android/hardware/bluetooth/*.aidl"],
stability: "vintf",
backend: {
+ cpp: {
+ // FIXME should this be disabled?
+ // prefer NDK backend which can be used anywhere
+ // If you disable this, you also need to delete the C++
+ // translate code.
+ enabled: true,
+ },
rust: {
enabled: true,
},
@@ -37,4 +44,5 @@
},
],
frozen: true,
+
}
diff --git a/bluetooth/aidl/default/Android.bp b/bluetooth/aidl/default/Android.bp
index d3f6364..46a6983 100644
--- a/bluetooth/aidl/default/Android.bp
+++ b/bluetooth/aidl/default/Android.bp
@@ -2,61 +2,58 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
-cc_library_static {
- name: "libbluetoothhcihalimpl",
- vendor_available: true,
- host_supported: true,
- srcs: [
- "BluetoothHci.cpp",
- "net_bluetooth_mgmt.cpp",
- ],
+cc_defaults {
+ name: "android.hardware.bluetooth-service-build-defaults",
cflags: [
"-Wall",
"-Wextra",
],
- header_libs: [
- "libbluetooth_offload_hal_headers",
+ shared_libs: [
+ "android.hardware.bluetooth-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "libhidlbase",
+ "liblog",
+ "libutils",
],
static_libs: [
"android.hardware.bluetooth.async",
"android.hardware.bluetooth.hci",
- ],
- shared_libs: [
- "libbase",
- "libcutils",
- "liblog",
- "libutils",
+ "libbluetooth_offload_hal",
],
}
-rust_binary {
+cc_library_static {
+ name: "libbluetoothhcihalimpl",
+ vendor_available: true,
+ defaults: ["android.hardware.bluetooth-service-build-defaults"],
+ srcs: [
+ "BluetoothHci.cpp",
+ "net_bluetooth_mgmt.cpp",
+ ],
+}
+
+cc_binary {
name: "android.hardware.bluetooth-service.default",
- crate_name: "bluetooth_hci_hal_server",
relative_install_path: "hw",
init_rc: ["bluetooth-service-default.rc"],
vintf_fragments: [":manifest_android.hardware.bluetooth-service.default.xml"],
vendor: true,
- prefer_rlib: true,
- srcs: ["main.rs"],
- rustlibs: [
- "android.hardware.bluetooth-V1-rust",
- "libbluetooth_offload_hal",
- "libbluetooth_offload_leaudio_hci",
- "libbinder_rs",
- "liblogger",
- "liblog_rust",
- ],
- static_libs: [
- "android.hardware.bluetooth.async",
- "android.hardware.bluetooth.hci",
- "libbluetoothhcihalimpl",
+ defaults: ["android.hardware.bluetooth-service-build-defaults"],
+ srcs: [
+ "service.cpp",
],
shared_libs: [
+ "android.hardware.bluetooth-V1-ndk",
"libbase",
- "libc++",
- "libcutils",
- "liblog",
+ "libbinder_ndk",
+ "libhidlbase",
"libutils",
+ "liblog",
+ ],
+ static_libs: [
+ "libbluetoothhcihalimpl",
],
}
diff --git a/bluetooth/aidl/default/BluetoothHci.cpp b/bluetooth/aidl/default/BluetoothHci.cpp
index bcdb67e..5ac3afe 100644
--- a/bluetooth/aidl/default/BluetoothHci.cpp
+++ b/bluetooth/aidl/default/BluetoothHci.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,20 +16,18 @@
#define LOG_TAG "android.hardware.bluetooth.service.default"
+#include "BluetoothHci.h"
+
#include <cutils/properties.h>
#include <fcntl.h>
-#include <hal/ffi.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <poll.h>
#include <string.h>
+#include <sys/uio.h>
#include <termios.h>
-#include <future>
-#include <memory>
-#include <vector>
-
-#include "async_fd_watcher.h"
-#include "h4_protocol.h"
#include "log/log.h"
-#include "net_bluetooth_mgmt.h"
namespace {
int SetTerminalRaw(int fd) {
@@ -46,6 +44,7 @@
using namespace ::android::hardware::bluetooth::hci;
using namespace ::android::hardware::bluetooth::async;
+using aidl::android::hardware::bluetooth::hal::Status;
namespace aidl::android::hardware::bluetooth::impl {
@@ -62,298 +61,234 @@
return str.compare(0, prefix.length(), prefix) == 0;
}
-class Hal {
- public:
- Hal(const std::string& dev_path = "/dev/hvc5") {
- char property_bytes[PROPERTY_VALUE_MAX];
- property_get("vendor.ser.bt-uart", property_bytes, dev_path.c_str());
- mDevPath = std::string(property_bytes);
- }
+BluetoothHci::BluetoothHci(const std::string& dev_path) {
+ char property_bytes[PROPERTY_VALUE_MAX];
+ property_get("vendor.ser.bt-uart", property_bytes, dev_path.c_str());
+ mDevPath = std::string(property_bytes);
+}
- static void Initialize(void* instance,
- const struct hal_callbacks* callbacks) {
- static_cast<Hal*>(instance)->Initialize(callbacks);
- }
-
- static void Close(void* instance) { static_cast<Hal*>(instance)->Close(); }
-
- static void SendCommand(void* instance, const uint8_t* data, size_t len) {
- static_cast<Hal*>(instance)->SendCommand(
- std::vector<uint8_t>(data, data + len));
- }
-
- static void SendAcl(void* instance, const uint8_t* data, size_t len) {
- static_cast<Hal*>(instance)->SendAcl(
- std::vector<uint8_t>(data, data + len));
- }
-
- static void SendSco(void* instance, const uint8_t* data, size_t len) {
- static_cast<Hal*>(instance)->SendSco(
- std::vector<uint8_t>(data, data + len));
- }
-
- static void SendIso(void* instance, const uint8_t* data, size_t len) {
- static_cast<Hal*>(instance)->SendIso(
- std::vector<uint8_t>(data, data + len));
- }
-
- private:
- int getFdFromDevPath() {
- int fd = open(mDevPath.c_str(), O_RDWR);
- if (fd < 0) {
- ALOGE("Could not connect to bt: %s (%s)", mDevPath.c_str(),
- strerror(errno));
- return fd;
- }
- if (int ret = SetTerminalRaw(fd) < 0) {
- ALOGI("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret,
- strerror(errno));
- }
+int BluetoothHci::getFdFromDevPath() {
+ int fd = open(mDevPath.c_str(), O_RDWR);
+ if (fd < 0) {
+ ALOGE("Could not connect to bt: %s (%s)", mDevPath.c_str(),
+ strerror(errno));
return fd;
}
+ if (int ret = SetTerminalRaw(fd) < 0) {
+ ALOGI("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret,
+ strerror(errno));
+ }
+ return fd;
+}
- void reset() {
- // Send a reset command and wait until the command complete comes back.
+void BluetoothHci::reset() {
+ // Send a reset command and wait until the command complete comes back.
- std::vector<uint8_t> reset = {0x03, 0x0c, 0x00};
+ std::vector<uint8_t> reset = {0x03, 0x0c, 0x00};
- auto resetPromise = std::make_shared<std::promise<void>>();
- auto resetFuture = resetPromise->get_future();
+ auto resetPromise = std::make_shared<std::promise<void>>();
+ auto resetFuture = resetPromise->get_future();
- mH4 = std::make_shared<H4Protocol>(
- mFd,
- [](const std::vector<uint8_t>& raw_command) {
- ALOGI("Discarding %d bytes with command type",
- static_cast<int>(raw_command.size()));
- },
- [](const std::vector<uint8_t>& raw_acl) {
- ALOGI("Discarding %d bytes with acl type",
- static_cast<int>(raw_acl.size()));
- },
- [](const std::vector<uint8_t>& raw_sco) {
- ALOGI("Discarding %d bytes with sco type",
- static_cast<int>(raw_sco.size()));
- },
- [resetPromise](const std::vector<uint8_t>& raw_event) {
- std::vector<uint8_t> reset_complete = {0x0e, 0x04, 0x01,
- 0x03, 0x0c, 0x00};
- bool valid = raw_event.size() == 6 &&
- raw_event[0] == reset_complete[0] &&
- raw_event[1] == reset_complete[1] &&
- // Don't compare the number of packets field.
- raw_event[3] == reset_complete[3] &&
- raw_event[4] == reset_complete[4] &&
- raw_event[5] == reset_complete[5];
- if (valid) {
- resetPromise->set_value();
- } else {
- ALOGI("Discarding %d bytes with event type",
- static_cast<int>(raw_event.size()));
- }
- },
- [](const std::vector<uint8_t>& raw_iso) {
- ALOGI("Discarding %d bytes with iso type",
- static_cast<int>(raw_iso.size()));
- },
- [this]() {
- ALOGI("HCI socket device disconnected while waiting for reset");
- mFdWatcher.StopWatchingFileDescriptors();
- });
- mFdWatcher.WatchFdForNonBlockingReads(mFd,
- [this](int) { mH4->OnDataReady(); });
+ mH4 = std::make_shared<H4Protocol>(
+ mFd,
+ [](const std::vector<uint8_t>& raw_command) {
+ ALOGI("Discarding %d bytes with command type",
+ static_cast<int>(raw_command.size()));
+ },
+ [](const std::vector<uint8_t>& raw_acl) {
+ ALOGI("Discarding %d bytes with acl type",
+ static_cast<int>(raw_acl.size()));
+ },
+ [](const std::vector<uint8_t>& raw_sco) {
+ ALOGI("Discarding %d bytes with sco type",
+ static_cast<int>(raw_sco.size()));
+ },
+ [resetPromise](const std::vector<uint8_t>& raw_event) {
+ std::vector<uint8_t> reset_complete = {0x0e, 0x04, 0x01,
+ 0x03, 0x0c, 0x00};
+ bool valid = raw_event.size() == 6 &&
+ raw_event[0] == reset_complete[0] &&
+ raw_event[1] == reset_complete[1] &&
+ // Don't compare the number of packets field.
+ raw_event[3] == reset_complete[3] &&
+ raw_event[4] == reset_complete[4] &&
+ raw_event[5] == reset_complete[5];
+ if (valid) {
+ resetPromise->set_value();
+ } else {
+ ALOGI("Discarding %d bytes with event type",
+ static_cast<int>(raw_event.size()));
+ }
+ },
+ [](const std::vector<uint8_t>& raw_iso) {
+ ALOGI("Discarding %d bytes with iso type",
+ static_cast<int>(raw_iso.size()));
+ },
+ [this]() {
+ ALOGI("HCI socket device disconnected while waiting for reset");
+ mFdWatcher.StopWatchingFileDescriptors();
+ });
+ mFdWatcher.WatchFdForNonBlockingReads(mFd,
+ [this](int) { mH4->OnDataReady(); });
- if (!send(PacketType::COMMAND, reset)) {
- ALOGE("Error sending reset command");
- }
- auto status = resetFuture.wait_for(std::chrono::seconds(1));
- mFdWatcher.StopWatchingFileDescriptors();
- if (status == std::future_status::ready) {
- ALOGI("HCI Reset successful");
- } else {
- ALOGE("HCI Reset Response not received in one second");
- }
-
- resetPromise.reset();
+ send(PacketType::COMMAND, reset);
+ auto status = resetFuture.wait_for(std::chrono::seconds(1));
+ mFdWatcher.StopWatchingFileDescriptors();
+ if (status == std::future_status::ready) {
+ ALOGI("HCI Reset successful");
+ } else {
+ ALOGE("HCI Reset Response not received in one second");
}
- void Initialize(const struct hal_callbacks* callbacks) {
- ALOGI(__func__);
+ resetPromise.reset();
+}
- HalState old_state = HalState::READY;
- {
- std::lock_guard<std::mutex> guard(mStateMutex);
- if (mState != HalState::READY) {
- old_state = mState;
- } else {
- mState = HalState::INITIALIZING;
- }
- }
+void BluetoothHci::initialize(
+ const std::shared_ptr<hal::IBluetoothHciCallbacks>& cb) {
+ ALOGI(__func__);
- if (old_state != HalState::READY) {
- ALOGE("initialize: Unexpected State %d", static_cast<int>(old_state));
- Close();
- callbacks->initialization_complete(callbacks->handle,
- STATUS_ALREADY_INITIALIZED);
- return;
- }
-
- mCallbacks = std::make_unique<struct hal_callbacks>(*callbacks);
- management_.reset(new NetBluetoothMgmt);
- mFd = management_->openHci();
- if (mFd < 0) {
- management_.reset();
-
- ALOGI("Unable to open Linux interface, trying default path.");
- mFd = getFdFromDevPath();
- if (mFd < 0) {
- mState = HalState::READY;
- mCallbacks->initialization_complete(mCallbacks->handle,
- STATUS_UNABLE_TO_OPEN_INTERFACE);
- return;
- }
- }
-
- // TODO: HCI Reset on emulators since the bluetooth controller
- // cannot be powered on/off during the HAL setup; and the stack
- // might received spurious packets/events during boottime.
- // Proper solution would be to use bt-virtio or vsock to better
- // control the link to rootcanal and the controller lifetime.
- const std::string kBoardProperty = "ro.product.board";
- const std::string kCuttlefishBoard = "cutf";
- auto board_name = GetSystemProperty(kBoardProperty);
- if (board_name.has_value() &&
- (starts_with(board_name.value(), "cutf") ||
- starts_with(board_name.value(), "goldfish"))) {
- reset();
- }
-
- mH4 = std::make_shared<H4Protocol>(
- mFd,
- [](const std::vector<uint8_t>& /* raw_command */) {
- LOG_ALWAYS_FATAL("Unexpected command!");
- },
- [this](const std::vector<uint8_t>& raw_acl) {
- mCallbacks->acl_received(mCallbacks->handle, raw_acl.data(),
- raw_acl.size());
- },
- [this](const std::vector<uint8_t>& raw_sco) {
- mCallbacks->sco_received(mCallbacks->handle, raw_sco.data(),
- raw_sco.size());
- },
- [this](const std::vector<uint8_t>& raw_event) {
- mCallbacks->event_received(mCallbacks->handle, raw_event.data(),
- raw_event.size());
- },
- [this](const std::vector<uint8_t>& raw_iso) {
- mCallbacks->iso_received(mCallbacks->handle, raw_iso.data(),
- raw_iso.size());
- },
- [this]() {
- ALOGI("HCI socket device disconnected");
- mFdWatcher.StopWatchingFileDescriptors();
- });
- mFdWatcher.WatchFdForNonBlockingReads(mFd,
- [this](int) { mH4->OnDataReady(); });
-
- {
- std::lock_guard<std::mutex> guard(mStateMutex);
- mState = HalState::ONE_CLIENT;
- }
-
- ALOGI("initialization complete");
- mCallbacks->initialization_complete(mCallbacks->handle, STATUS_SUCCESS);
+ if (cb == nullptr) {
+ ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
+ abort();
}
- void Close() {
- ALOGI(__func__);
- {
- std::lock_guard<std::mutex> guard(mStateMutex);
- if (mState != HalState::ONE_CLIENT) {
- LOG_ALWAYS_FATAL_IF(mState == HalState::INITIALIZING,
- "mState is INITIALIZING");
- ALOGI("Already closed");
- return;
- }
- mCallbacks.reset();
- mState = HalState::CLOSING;
- }
-
- mFdWatcher.StopWatchingFileDescriptors();
-
- if (management_) {
- management_->closeHci();
- } else {
- ::close(mFd);
- }
-
- {
- std::lock_guard<std::mutex> guard(mStateMutex);
- mState = HalState::READY;
- mH4 = nullptr;
- }
- }
-
- void SendCommand(const std::vector<uint8_t>& data) {
- send(PacketType::COMMAND, data);
- }
- void SendAcl(const std::vector<uint8_t>& data) {
- send(PacketType::ACL_DATA, data);
- }
- void SendSco(const std::vector<uint8_t>& data) {
- send(PacketType::SCO_DATA, data);
- }
- void SendIso(const std::vector<uint8_t>& data) {
- send(PacketType::ISO_DATA, data);
- }
-
- bool send(PacketType type, const std::vector<uint8_t>& v) {
- if (v.empty()) {
- ALOGE("Packet is empty, no data was found to be sent");
- return false;
- }
-
+ HalState old_state = HalState::READY;
+ {
std::lock_guard<std::mutex> guard(mStateMutex);
- if (mH4 == nullptr) {
- ALOGE("Illegal State");
- return false;
+ if (mState != HalState::READY) {
+ old_state = mState;
+ } else {
+ mState = HalState::INITIALIZING;
}
-
- mH4->Send(type, v);
- return true;
}
- std::unique_ptr<struct hal_callbacks> mCallbacks;
- std::string mDevPath;
- int mFd{-1};
- ::android::hardware::bluetooth::async::AsyncFdWatcher mFdWatcher;
- std::shared_ptr<::android::hardware::bluetooth::hci::H4Protocol> mH4;
- std::unique_ptr<NetBluetoothMgmt> management_{};
+ if (old_state != HalState::READY) {
+ ALOGE("initialize: Unexpected State %d", static_cast<int>(old_state));
+ close();
+ cb->initializationComplete(Status::ALREADY_INITIALIZED);
+ }
- // Don't close twice or open before close is complete
- std::mutex mStateMutex;
- enum class HalState {
- READY,
- INITIALIZING,
- ONE_CLIENT,
- CLOSING,
- } mState{HalState::READY};
-};
+ mCb = cb;
+ management_.reset(new NetBluetoothMgmt);
+ mFd = management_->openHci();
+ if (mFd < 0) {
+ management_.reset();
+
+ ALOGI("Unable to open Linux interface, trying default path.");
+ mFd = getFdFromDevPath();
+ if (mFd < 0) {
+ mState = HalState::READY;
+ cb->initializationComplete(Status::UNABLE_TO_OPEN_INTERFACE);
+ }
+ }
+
+ // TODO: HCI Reset on emulators since the bluetooth controller
+ // cannot be powered on/off during the HAL setup; and the stack
+ // might received spurious packets/events during boottime.
+ // Proper solution would be to use bt-virtio or vsock to better
+ // control the link to rootcanal and the controller lifetime.
+ const std::string kBoardProperty = "ro.product.board";
+ const std::string kCuttlefishBoard = "cutf";
+ auto board_name = GetSystemProperty(kBoardProperty);
+ if (board_name.has_value() && (
+ starts_with(board_name.value(), "cutf") ||
+ starts_with(board_name.value(), "goldfish"))) {
+ reset();
+ }
+
+ mH4 = std::make_shared<H4Protocol>(
+ mFd,
+ [](const std::vector<uint8_t>& /* raw_command */) {
+ LOG_ALWAYS_FATAL("Unexpected command!");
+ },
+ [this](const std::vector<uint8_t>& raw_acl) {
+ mCb->aclDataReceived(raw_acl);
+ },
+ [this](const std::vector<uint8_t>& raw_sco) {
+ mCb->scoDataReceived(raw_sco);
+ },
+ [this](const std::vector<uint8_t>& raw_event) {
+ mCb->hciEventReceived(raw_event);
+ },
+ [this](const std::vector<uint8_t>& raw_iso) {
+ mCb->isoDataReceived(raw_iso);
+ },
+ [this]() {
+ ALOGI("HCI socket device disconnected");
+ mFdWatcher.StopWatchingFileDescriptors();
+ });
+ mFdWatcher.WatchFdForNonBlockingReads(mFd,
+ [this](int) { mH4->OnDataReady(); });
+
+ {
+ std::lock_guard<std::mutex> guard(mStateMutex);
+ mState = HalState::ONE_CLIENT;
+ }
+ ALOGI("initialization complete");
+ mCb->initializationComplete(Status::SUCCESS);
+}
+
+void BluetoothHci::close() {
+ ALOGI(__func__);
+ {
+ std::lock_guard<std::mutex> guard(mStateMutex);
+ if (mState != HalState::ONE_CLIENT) {
+ LOG_ALWAYS_FATAL_IF(mState == HalState::INITIALIZING,
+ "mState is INITIALIZING");
+ ALOGI("Already closed");
+ }
+ mState = HalState::CLOSING;
+ }
+
+ mFdWatcher.StopWatchingFileDescriptors();
+
+ if (management_) {
+ management_->closeHci();
+ } else {
+ ::close(mFd);
+ }
+
+ {
+ std::lock_guard<std::mutex> guard(mStateMutex);
+ mState = HalState::READY;
+ mH4 = nullptr;
+ }
+}
+
+void BluetoothHci::clientDied() {
+ ALOGI(__func__);
+ close();
+}
+
+void BluetoothHci::sendHciCommand(const std::vector<uint8_t>& packet) {
+ return send(PacketType::COMMAND, packet);
+}
+
+void BluetoothHci::sendAclData(const std::vector<uint8_t>& packet) {
+ return send(PacketType::ACL_DATA, packet);
+}
+
+void BluetoothHci::sendScoData(const std::vector<uint8_t>& packet) {
+ return send(PacketType::SCO_DATA, packet);
+}
+
+void BluetoothHci::sendIsoData(const std::vector<uint8_t>& packet) {
+ return send(PacketType::ISO_DATA, packet);
+}
+
+void BluetoothHci::send(PacketType type, const std::vector<uint8_t>& v) {
+ if (v.empty()) {
+ ALOGE("Packet is empty, no data was found to be sent");
+ abort();
+ }
+
+ std::lock_guard<std::mutex> guard(mStateMutex);
+ if (mH4 == nullptr) {
+ ALOGE("Illegal State");
+ abort();
+ }
+
+ mH4->Send(type, v);
+}
} // namespace aidl::android::hardware::bluetooth::impl
-
-extern "C" {
-
-using namespace aidl::android::hardware::bluetooth::impl;
-
-struct hal_interface hal_new() {
- return (struct hal_interface){
- .handle = new Hal(),
- .initialize = &Hal::Initialize,
- .close = &Hal::Close,
- .send_command = &Hal::SendCommand,
- .send_acl = &Hal::SendAcl,
- .send_sco = &Hal::SendSco,
- .send_iso = &Hal::SendIso,
- };
-}
-}
diff --git a/bluetooth/aidl/default/BluetoothHci.h b/bluetooth/aidl/default/BluetoothHci.h
new file mode 100644
index 0000000..5c31468
--- /dev/null
+++ b/bluetooth/aidl/default/BluetoothHci.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hal/ffi.h>
+
+#include <future>
+#include <string>
+
+#include "async_fd_watcher.h"
+#include "h4_protocol.h"
+#include "net_bluetooth_mgmt.h"
+
+namespace aidl::android::hardware::bluetooth::impl {
+
+// This Bluetooth HAL implementation connects with a serial port at dev_path_.
+class BluetoothHci : public hal::IBluetoothHci {
+ public:
+ BluetoothHci(const std::string& dev_path = "/dev/hvc5");
+
+ void initialize(
+ const std::shared_ptr<hal::IBluetoothHciCallbacks>& cb) override;
+
+ void sendHciCommand(const std::vector<uint8_t>& packet) override;
+
+ void sendAclData(const std::vector<uint8_t>& packet) override;
+
+ void sendScoData(const std::vector<uint8_t>& packet) override;
+
+ void sendIsoData(const std::vector<uint8_t>& packet) override;
+
+ void close() override;
+
+ void clientDied() override;
+
+ static void OnPacketReady();
+
+ static BluetoothHci* get();
+
+ private:
+ int mFd{-1};
+ std::shared_ptr<hal::IBluetoothHciCallbacks> mCb = nullptr;
+
+ std::shared_ptr<::android::hardware::bluetooth::hci::H4Protocol> mH4;
+
+ std::string mDevPath;
+
+ ::android::hardware::bluetooth::async::AsyncFdWatcher mFdWatcher;
+
+ int getFdFromDevPath();
+ void send(::android::hardware::bluetooth::hci::PacketType type,
+ const std::vector<uint8_t>& packet);
+ std::unique_ptr<NetBluetoothMgmt> management_{};
+
+ // Send a reset command and discard all packets until a reset is received.
+ void reset();
+
+ // Don't close twice or open before close is complete
+ std::mutex mStateMutex;
+ enum class HalState {
+ READY,
+ INITIALIZING,
+ ONE_CLIENT,
+ CLOSING,
+ } mState{HalState::READY};
+};
+
+} // namespace aidl::android::hardware::bluetooth::impl
diff --git a/bluetooth/aidl/default/main.rs b/bluetooth/aidl/default/main.rs
deleted file mode 100644
index b30162a..0000000
--- a/bluetooth/aidl/default/main.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2024, 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.
-
-use android_hardware_bluetooth::aidl::android::hardware::bluetooth::IBluetoothHci::{
- self,
- IBluetoothHci as _
-};
-use android_hardware_bluetooth::binder;
-use bluetooth_offload_hal::{ HciHalProxy, CInterface };
-use bluetooth_offload_leaudio_hci::LeAudioModuleBuilder;
-use log;
-use std::panic;
-
-fn new_hal() -> CInterface {
- extern "C" { fn hal_new() -> CInterface; }
- unsafe { hal_new() }
-}
-
-fn main() {
- logger::init(
- logger::Config::default()
- .with_max_level(log::LevelFilter::Debug)
- .with_tag_on_device("android.hardware.bluetooth"),
- );
-
- panic::set_hook(Box::new(|panic_info| {
- log::error!("{}", panic_info);
- }));
-
- log::info!("Bluetooth HAL starting up");
-
- binder::ProcessState::set_thread_pool_max_thread_count(0);
- binder::ProcessState::start_thread_pool();
-
- binder::add_service(
- &format!("{}/default", IBluetoothHci::BpBluetoothHci::get_descriptor()),
- IBluetoothHci::BnBluetoothHci::new_binder(
- HciHalProxy::new(
- vec![ Box::new(LeAudioModuleBuilder {}) ],
- new_hal()
- ),
- binder::BinderFeatures::default(),
- ).as_binder()
- ).expect("Failed to register service");
-
- binder::ProcessState::join_thread_pool();
-}
diff --git a/bluetooth/aidl/default/service.cpp b/bluetooth/aidl/default/service.cpp
new file mode 100644
index 0000000..9e1a22c
--- /dev/null
+++ b/bluetooth/aidl/default/service.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "aidl.android.hardware.bluetooth.service.default"
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "BluetoothHci.h"
+
+using ::aidl::android::hardware::bluetooth::hal::IBluetoothHci_addService;
+using ::aidl::android::hardware::bluetooth::impl::BluetoothHci;
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+
+int main(int /* argc */, char** /* argv */) {
+ ALOGI("Bluetooth HAL starting");
+ if (!ABinderProcess_setThreadPoolMaxThreadCount(0)) {
+ ALOGI("failed to set thread pool max thread count");
+ return 1;
+ }
+
+ IBluetoothHci_addService(new BluetoothHci());
+ ABinderProcess_joinThreadPool();
+ return 0;
+}
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp
index 6b9046c..10c347b 100644
--- a/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp
@@ -102,7 +102,7 @@
kBlockLength16
};
-enum { kSubbands8 = kSubbands.first, kSubbands4 };
+enum { kSubbands4 = kSubbands.first, kSubbands8 };
enum {
kAllocationMethodSnr = kAllocationMethod.first,
@@ -486,7 +486,7 @@
}
min_bitpool = std::max(min_bitpool, uint8_t(lcaps.get(kMinimumBitpool)));
- max_bitpool = std::max(max_bitpool, uint8_t(lcaps.get(kMaximumBitpool)));
+ max_bitpool = std::min(max_bitpool, uint8_t(lcaps.get(kMaximumBitpool)));
if (hint) {
min_bitpool =
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
index 8d03fae..d68113d 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
@@ -78,8 +78,7 @@
cookie);
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
- onSessionReady(_aidl_return);
- return ndk::ScopedAStatus::ok();
+ return onSessionReady(_aidl_return);
}
ndk::ScopedAStatus BluetoothAudioProvider::endSession() {
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index a52d761..2fde910 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -2843,11 +2843,11 @@
if (asymmetric) {
source_ase_requriement.aseConfiguration.codecConfiguration = {
- CodecSpecificConfigurationLtv::SamplingFrequency::HZ8000,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation};
} else {
source_ase_requriement.aseConfiguration.codecConfiguration = {
- CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ32000,
CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation};
}
diff --git a/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocCapabilities.aidl b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocCapabilities.aidl
index 003da11..9cd63d6 100644
--- a/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocCapabilities.aidl
+++ b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocCapabilities.aidl
@@ -37,8 +37,9 @@
/**
* The value used by the Host stack for the local Maximum Packet Size shall be the value
* LE_ACL_Data_Packet_Length returned by the controller in response to the command HCI LE Read
- * Buffer Size. Then, the MPS size must be in range 1 to 255. We do not make the MPS
- * configurable in HAL because using the maximum value does not require a large amount of
- * memory.
+ * Buffer Size if Total_Num_LE_ACL_Data_Packets is not zero. The MPS shall be the value
+ * ACL_Data_Packet_Length returned in response to the command HCI Read Buffer Size if
+ * Total_Num_LE_ACL_Data_Packets is zero. We do not make the MPS configurable in HAL because
+ * using the maximum value does not require a large amount of memory.
*/
}
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 63ef223..0d37060 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -88,8 +88,6 @@
"compatibility_matrix.5.xml",
],
kernel_configs: [
- "kernel_config_r_4.14",
- "kernel_config_r_4.19",
"kernel_config_r_5.4",
],
}
diff --git a/compatibility_matrices/compatibility_matrix.5.xml b/compatibility_matrices/compatibility_matrix.5.xml
index 1cf98b0..d01a6ea 100644
--- a/compatibility_matrices/compatibility_matrix.5.xml
+++ b/compatibility_matrices/compatibility_matrix.5.xml
@@ -1,578 +1,7 @@
<compatibility-matrix version="1.0" type="framework" level="5">
- <hal format="hidl">
- <name>android.hardware.atrace</name>
- <version>1.0</version>
- <interface>
- <name>IAtraceDevice</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.audio</name>
- <version>6.0</version>
- <interface>
- <name>IDevicesFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.audio.effect</name>
- <version>6.0</version>
- <interface>
- <name>IEffectsFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.authsecret</name>
- <version>1.0</version>
- <interface>
- <name>IAuthSecret</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.automotive.audiocontrol</name>
- <version>1.0</version>
- <version>2.0</version>
- <interface>
- <name>IAudioControl</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.automotive.can</name>
- <version>1.0</version>
- <interface>
- <name>ICanBus</name>
- <regex-instance>.*</regex-instance>
- </interface>
- <interface>
- <name>ICanController</name>
- <regex-instance>.*</regex-instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.automotive.evs</name>
- <version>1.0-1</version>
- <interface>
- <name>IEvsEnumerator</name>
- <instance>default</instance>
- <regex-instance>[a-z]+/[0-9]+</regex-instance>
- </interface>
- </hal>
- <hal format="aidl">
- <name>android.hardware.automotive.occupant_awareness</name>
- <interface>
- <name>IOccupantAwareness</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.automotive.sv</name>
- <version>1.0</version>
- <interface>
- <name>ISurroundViewService</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.automotive.vehicle</name>
- <version>2.0</version>
- <interface>
- <name>IVehicle</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.biometrics.face</name>
- <version>1.0</version>
- <interface>
- <name>IBiometricsFace</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.biometrics.fingerprint</name>
- <version>2.1-2</version>
- <interface>
- <name>IBiometricsFingerprint</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.bluetooth</name>
- <version>1.0-1</version>
- <interface>
- <name>IBluetoothHci</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.bluetooth.audio</name>
- <version>2.0</version>
- <interface>
- <name>IBluetoothAudioProvidersFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.boot</name>
- <version>1.1</version>
- <interface>
- <name>IBootControl</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.broadcastradio</name>
- <version>1.0-1</version>
- <interface>
- <name>IBroadcastRadioFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.broadcastradio</name>
- <version>2.0</version>
- <interface>
- <name>IBroadcastRadio</name>
- <regex-instance>.*</regex-instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.camera.provider</name>
- <version>2.4-6</version>
- <interface>
- <name>ICameraProvider</name>
- <regex-instance>[^/]+/[0-9]+</regex-instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.cas</name>
- <version>1.1-2</version>
- <interface>
- <name>IMediaCasService</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.confirmationui</name>
- <version>1.0</version>
- <interface>
- <name>IConfirmationUI</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.contexthub</name>
- <version>1.0-1</version>
- <interface>
- <name>IContexthub</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.drm</name>
- <version>1.3</version>
- <interface>
- <name>ICryptoFactory</name>
- <regex-instance>.*</regex-instance>
- </interface>
- <interface>
- <name>IDrmFactory</name>
- <regex-instance>.*</regex-instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.dumpstate</name>
- <version>1.1</version>
- <interface>
- <name>IDumpstateDevice</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.gatekeeper</name>
- <version>1.0</version>
- <interface>
- <name>IGatekeeper</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.gnss</name>
- <version>2.0-1</version>
- <interface>
- <name>IGnss</name>
- <instance>default</instance>
- </interface>
- </hal>
- <!-- Either the AIDL or the HIDL allocator HAL must exist on the device.
- If the HIDL composer HAL exists, it must be at least version 2.0.
- See DeviceManifestTest.GrallocHal -->
- <hal format="hidl">
- <name>android.hardware.graphics.allocator</name>
- <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
- <version>2.0</version>
- <version>3.0</version>
- <version>4.0</version>
- <interface>
- <name>IAllocator</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.graphics.composer</name>
- <version>2.1-4</version>
- <interface>
- <name>IComposer</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.graphics.mapper</name>
- <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
- <version>2.1</version>
- <version>3.0</version>
- <version>4.0</version>
- <interface>
- <name>IMapper</name>
- <instance>default</instance>
- </interface>
- </hal>
- <!-- Either the AIDL or the HIDL health HAL must exist on the device.
- If the HIDL health HAL exists, it must be at least version 2.1.
- See DeviceManifestTest.HealthHal -->
- <hal format="hidl">
- <name>android.hardware.health</name>
- <version>2.1</version>
- <interface>
- <name>IHealth</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.health.storage</name>
- <version>1.0</version>
- <interface>
- <name>IStorage</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="aidl">
- <name>android.hardware.identity</name>
- <!--
- b/178458001: identity V2 is introduced in R, but Android R VINTF does not support AIDL
- versions. Hence, we only specify identity V2 in compatibility_matrix.5.xml in Android S+
- branches. In Android R branches, the matrix implicitly specifies V1.
- SingleManifestTest.ManifestAidlHalsServed has an exemption for this.
- -->
- <version>1-2</version>
- <interface>
- <name>IIdentityCredentialStore</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.ir</name>
- <version>1.0</version>
- <interface>
- <name>IConsumerIr</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.input.classifier</name>
- <version>1.0</version>
- <interface>
- <name>IInputClassifier</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.keymaster</name>
- <version>3.0</version>
- <version>4.0-1</version>
- <interface>
- <name>IKeymasterDevice</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.keymaster</name>
- <version>4.0-1</version>
- <interface>
- <name>IKeymasterDevice</name>
- <instance>strongbox</instance>
- </interface>
- </hal>
- <hal format="aidl">
- <name>android.hardware.light</name>
- <interface>
- <name>ILights</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.media.c2</name>
- <version>1.0-1</version>
- <interface>
- <name>IComponentStore</name>
- <instance>software</instance>
- <regex-instance>default[0-9]*</regex-instance>
- <regex-instance>vendor[0-9]*_software</regex-instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.media.c2</name>
- <version>1.0</version>
- <interface>
- <name>IConfigurable</name>
- <instance>default</instance>
- <instance>software</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.media.omx</name>
- <version>1.0</version>
- <interface>
- <name>IOmx</name>
- <instance>default</instance>
- </interface>
- <interface>
- <name>IOmxStore</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.memtrack</name>
- <version>1.0</version>
- <interface>
- <name>IMemtrack</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.neuralnetworks</name>
- <version>1.0-3</version>
- <interface>
- <name>IDevice</name>
- <regex-instance>.*</regex-instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.nfc</name>
- <version>1.2</version>
- <interface>
- <name>INfc</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.oemlock</name>
- <version>1.0</version>
- <interface>
- <name>IOemLock</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="aidl">
- <name>android.hardware.power</name>
- <interface>
- <name>IPower</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.power.stats</name>
- <version>1.0</version>
- <interface>
- <name>IPowerStats</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.radio</name>
- <version>1.4</version>
- <version>1.5</version>
- <interface>
- <name>IRadio</name>
- <instance>slot1</instance>
- <instance>slot2</instance>
- <instance>slot3</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.radio</name>
- <version>1.2</version>
- <interface>
- <name>ISap</name>
- <instance>slot1</instance>
- <instance>slot2</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.radio.config</name>
- <!--
- See compatibility_matrix.4.xml on versioning of radio config HAL.
- -->
- <version>1.1</version>
- <interface>
- <name>IRadioConfig</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.renderscript</name>
- <version>1.0</version>
- <interface>
- <name>IDevice</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="aidl">
- <name>android.hardware.rebootescrow</name>
- <interface>
- <name>IRebootEscrow</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.secure_element</name>
- <version>1.0-2</version>
- <interface>
- <name>ISecureElement</name>
- <regex-instance>eSE[1-9][0-9]*</regex-instance>
- <regex-instance>SIM[1-9][0-9]*</regex-instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.sensors</name>
- <version>1.0</version>
- <version>2.0-1</version>
- <interface>
- <name>ISensors</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.soundtrigger</name>
- <version>2.0-3</version>
- <interface>
- <name>ISoundTriggerHw</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.tetheroffload.config</name>
- <version>1.0</version>
- <interface>
- <name>IOffloadConfig</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.tetheroffload.control</name>
- <version>1.0</version>
- <interface>
- <name>IOffloadControl</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.thermal</name>
- <version>2.0</version>
- <interface>
- <name>IThermal</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.tv.cec</name>
- <version>1.0</version>
- <interface>
- <name>IHdmiCec</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.tv.input</name>
- <version>1.0</version>
- <interface>
- <name>ITvInput</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.tv.tuner</name>
- <version>1.0</version>
- <interface>
- <name>ITuner</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.usb</name>
- <version>1.0-2</version>
- <interface>
- <name>IUsb</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.usb.gadget</name>
- <version>1.0-1</version>
- <interface>
- <name>IUsbGadget</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="aidl">
- <name>android.hardware.vibrator</name>
- <interface>
- <name>IVibrator</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.vr</name>
- <version>1.0</version>
- <interface>
- <name>IVr</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.weaver</name>
- <version>1.0</version>
- <interface>
- <name>IWeaver</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.wifi</name>
- <version>1.0-4</version>
- <interface>
- <name>IWifi</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.wifi.hostapd</name>
- <version>1.0-2</version>
- <interface>
- <name>IHostapd</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl">
- <name>android.hardware.wifi.supplicant</name>
- <version>1.0-3</version>
- <interface>
- <name>ISupplicant</name>
- <instance>default</instance>
- </interface>
- </hal>
+ <!--
+ Android R FCM has been deprecated, but this file is kept
+ to help manage the android11-5.4 kernel config requirements as that
+ kernel version is not being deprecated with the R FCM.
+ -->
</compatibility-matrix>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index 1d5b2bd..fdbeab0 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -104,6 +104,28 @@
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
"android.hardware.vibrator@1.3",
+
+ // b/392700935 for HALs deprecated in R
+ "android.hardware.automotive.audiocontrol@1.0",
+ "android.hardware.automotive.audiocontrol@2.0",
+ "android.hardware.boot@1.1",
+ "android.hardware.contexthub@1.0",
+ "android.hardware.contexthub@1.1",
+ "android.hardware.health.storage@1.0",
+ "android.hardware.memtrack@1.0",
+ "android.hardware.power.stats@1.0",
+ "android.hardware.radio@1.4",
+ "android.hardware.radio@1.5",
+ "android.hardware.soundtrigger@2.0",
+ "android.hardware.soundtrigger@2.1",
+ "android.hardware.soundtrigger@2.2",
+ "android.hardware.tetheroffload.control@1.0",
+ "android.hardware.vr@1.0",
+ "android.hardware.wifi.supplicant@1.0",
+ "android.hardware.wifi.supplicant@1.1",
+ "android.hardware.wifi@1.0",
+ "android.hardware.wifi@1.1",
+ "android.hardware.wifi@1.2",
};
auto package_has_prefix = [&](const std::string& prefix) {
diff --git a/configstore/OWNERS b/configstore/OWNERS
index 70ad434..74789b5 100644
--- a/configstore/OWNERS
+++ b/configstore/OWNERS
@@ -1,3 +1,2 @@
# Bug component: 24939
-lpy@google.com
diff --git a/confirmationui/1.0/default/OWNERS b/confirmationui/1.0/default/OWNERS
index 17aed51..d8b8840 100644
--- a/confirmationui/1.0/default/OWNERS
+++ b/confirmationui/1.0/default/OWNERS
@@ -1,3 +1,2 @@
# Bug component: 1124672
-jdanis@google.com
swillden@google.com
diff --git a/confirmationui/1.0/vts/OWNERS b/confirmationui/1.0/vts/OWNERS
index aa07242..b0ee996 100644
--- a/confirmationui/1.0/vts/OWNERS
+++ b/confirmationui/1.0/vts/OWNERS
@@ -1,4 +1,3 @@
# Bug component: 1124672
-jdanis@google.com
swillden@google.com
yim@google.com
diff --git a/confirmationui/support/OWNERS b/confirmationui/support/OWNERS
index 17aed51..d8b8840 100644
--- a/confirmationui/support/OWNERS
+++ b/confirmationui/support/OWNERS
@@ -1,3 +1,2 @@
# Bug component: 1124672
-jdanis@google.com
swillden@google.com
diff --git a/gatekeeper/1.0/default/OWNERS b/gatekeeper/1.0/default/OWNERS
index c97fba6..d552a9a 100644
--- a/gatekeeper/1.0/default/OWNERS
+++ b/gatekeeper/1.0/default/OWNERS
@@ -1,3 +1,2 @@
# Bug component: 1124862
-jdanis@google.com
swillden@google.com
diff --git a/gatekeeper/1.0/software/OWNERS b/gatekeeper/1.0/software/OWNERS
index c97fba6..d552a9a 100644
--- a/gatekeeper/1.0/software/OWNERS
+++ b/gatekeeper/1.0/software/OWNERS
@@ -1,3 +1,2 @@
# Bug component: 1124862
-jdanis@google.com
swillden@google.com
diff --git a/gnss/OWNERS b/gnss/OWNERS
index 57982e7..2c54f9f 100644
--- a/gnss/OWNERS
+++ b/gnss/OWNERS
@@ -2,7 +2,6 @@
gomo@google.com
smalkos@google.com
-trong@google.com
wyattriley@google.com
yim@google.com
yuhany@google.com
diff --git a/graphics/OWNERS b/graphics/OWNERS
index 4317831..9ba1ee0 100644
--- a/graphics/OWNERS
+++ b/graphics/OWNERS
@@ -5,5 +5,4 @@
alecmouri@google.com
chrisforbes@google.com
jreck@google.com
-lpy@google.com
sumir@google.com
diff --git a/ir/OWNERS b/ir/OWNERS
index 04de9ef..376fe0a 100644
--- a/ir/OWNERS
+++ b/ir/OWNERS
@@ -1,2 +1,2 @@
# Bug component: 163905
-connoro@google.com
+devinmoore@google.com
\ No newline at end of file
diff --git a/nfc/1.0/default/OWNERS b/nfc/1.0/default/OWNERS
index 5febd1d..e681870 100644
--- a/nfc/1.0/default/OWNERS
+++ b/nfc/1.0/default/OWNERS
@@ -1,2 +1 @@
rmojumder@google.com
-zachoverflow@google.com
diff --git a/nfc/1.2/vts/OWNERS b/nfc/1.2/vts/OWNERS
index 21d4df1..eeeadd1 100644
--- a/nfc/1.2/vts/OWNERS
+++ b/nfc/1.2/vts/OWNERS
@@ -1,3 +1,2 @@
-zachoverflow@google.com
jackcwyu@google.com
georgekgchang@google.com
diff --git a/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp b/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
index 9c44c3a..d3fcbb3 100644
--- a/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
+++ b/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
@@ -153,8 +153,7 @@
SyncEventGuard guard(sNfaVsCommand);
sNfaVsCommand.notifyOne();
} break;
- case NCI_ANDROID_SET_PASSIVE_OBSERVER_TECH:
- case NCI_ANDROID_PASSIVE_OBSERVE: {
+ case NCI_ANDROID_SET_PASSIVE_OBSERVER_TECH: {
if (param_len == 5) {
if ((p_param[0] & NCI_MT_MASK) == (NCI_MT_RSP << NCI_MT_SHIFT)) {
sVSCmdStatus = p_param[4];
@@ -190,36 +189,6 @@
}
/*
- * Enable passive observe mode.
- */
-tNFA_STATUS static nfaObserveModeEnable(bool enable) {
- tNFA_STATUS status = NFA_STATUS_FAILED;
-
- status = NFA_StopRfDiscovery();
- if (status == NFA_STATUS_OK) {
- if (!sNfaEnableDisablePollingEvent.wait(1000)) {
- LOG(WARNING) << "Timeout waiting to disable NFC RF discovery";
- return NFA_STATUS_TIMEOUT;
- }
- }
-
- uint8_t cmd[] = {NCI_ANDROID_PASSIVE_OBSERVE,
- static_cast<uint8_t>(enable ? NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE
- : NCI_ANDROID_PASSIVE_OBSERVE_PARAM_DISABLE)};
-
- status = NFA_SendVsCommand(NCI_MSG_PROP_ANDROID, sizeof(cmd), cmd, nfaVSCallback);
-
- if (status == NFA_STATUS_OK) {
- if (!sNfaVsCommand.wait(1000)) {
- LOG(WARNING) << "Timeout waiting for set observe mode command response";
- return NFA_STATUS_TIMEOUT;
- }
- }
-
- return status;
-}
-
-/*
* Get observe mode state.
*/
tNFA_STATUS static nfaQueryObserveModeState() {
@@ -322,33 +291,6 @@
};
/*
- * ObserveModeEnableDisable:
- * Attempts to enable observe mode. Does not test Observe Mode functionality,
- * but simply verifies that the enable command responds successfully.
- *
- * @VsrTest = GMS-VSR-3.2.8-001
- */
-TEST_P(NfcBehaviorChanges, ObserveModeEnableDisable) {
- if (get_vsr_api_level() < 202404) {
- GTEST_SKIP() << "Skipping test for board API level < 202404";
- }
-
- tNFA_STATUS status = nfaObserveModeEnable(true);
- ASSERT_EQ(status, NFA_STATUS_OK);
-
- status = nfaQueryObserveModeState();
- ASSERT_EQ(status, NFA_STATUS_OK);
- ASSERT_NE(sObserveModeState, 0);
-
- status = nfaObserveModeEnable(false);
- ASSERT_EQ(status, NFA_STATUS_OK);
-
- status = nfaQueryObserveModeState();
- ASSERT_EQ(status, NFA_STATUS_OK);
- ASSERT_EQ(sObserveModeState, 0);
-}
-
-/*
* SetPassiveObserverTech_getCaps:
* Verifies GET_CAPS returns get correct value for observe mode capabilities.
*/
diff --git a/power/1.0/vts/OWNERS b/power/1.0/vts/OWNERS
index 6de2cd5..53948b9 100644
--- a/power/1.0/vts/OWNERS
+++ b/power/1.0/vts/OWNERS
@@ -1,2 +1 @@
# Bug component: 158088
-connoro@google.com
diff --git a/power/1.1/vts/functional/OWNERS b/power/1.1/vts/functional/OWNERS
index 6de2cd5..53948b9 100644
--- a/power/1.1/vts/functional/OWNERS
+++ b/power/1.1/vts/functional/OWNERS
@@ -1,2 +1 @@
# Bug component: 158088
-connoro@google.com
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 1908d05..0ae4b96 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -550,8 +550,14 @@
void deleteKey(in byte[] keyBlob);
/**
- * Deletes all keys in the hardware keystore. Used when keystore is reset completely. After
- * this function is called all keys created previously must be rendered permanently unusable.
+ * Deletes all keys in the hardware keystore. Used when keystore is reset completely.
+ *
+ * For StrongBox KeyMint: After this function is called all keys created previously must be
+ * rendered permanently unusable.
+ *
+ * For TEE KeyMint: After this function is called all keys with Tag::ROLLBACK_RESISTANCE in
+ * their hardware-enforced authorization lists must be rendered permanently unusable. Keys
+ * without Tag::ROLLBACK_RESISTANCE may or may not be rendered unusable.
*/
void deleteAllKeys();
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index da3427a..a8ccabf 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -100,6 +100,9 @@
export_static_lib_headers: [
"libkeymint_support",
],
+ shared_libs: [
+ "libkeystore2_flags_cc",
+ ],
static_libs: [
"libgmock_ndk",
],
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 0c86a27..0ec76a5 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -29,6 +29,7 @@
#include <android-base/strings.h>
#include <android/binder_manager.h>
#include <android/content/pm/IPackageManagerNative.h>
+#include <android_security_keystore2.h>
#include <cppbor_parse.h>
#include <cutils/properties.h>
#include <gmock/gmock.h>
@@ -387,11 +388,11 @@
os_patch_level_ = getOsPatchlevel();
vendor_patch_level_ = getVendorPatchlevel();
- // TODO(b/369375199): temporary code, remove when apexd -> keystore2 -> KeyMint transmission
- // of module info happens.
- {
- GTEST_LOG_(INFO) << "Setting MODULE_HASH to fake value as fallback";
- // Ensure that a MODULE_HASH value is definitely present in KeyMint (if it's >= v4).
+ if (!::android::security::keystore2::attest_modules()) {
+ // Some tests (for v4+) require that the KeyMint instance has been
+ // provided with a module hash value. If the keystore2 flag is off,
+ // this will not happen, so set a fake value here instead.
+ GTEST_LOG_(INFO) << "Setting MODULE_HASH to fake value as fallback when flag off";
vector<uint8_t> fakeModuleHash = {
0xf3, 0xf1, 0x1f, 0xe5, 0x13, 0x05, 0xfe, 0xfa, 0xe9, 0xc3, 0x53,
0xef, 0x69, 0xdf, 0x9f, 0xd7, 0x0c, 0x1e, 0xcc, 0x2c, 0x2c, 0x62,
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 2f34b9d..5a6eea1 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -9134,5 +9134,12 @@
}
}
}
+ // Some tests rely on information about the state of the system having been received by KeyMint,
+ // so ensure that has happened before running tests.
+ using namespace std::chrono_literals;
+ if (!android::base::WaitForProperty("keystore.module_hash.sent", "true", 30s)) {
+ std::cerr << "Warning: running test before keystore.module_hash.sent is true\n";
+ }
+
return RUN_ALL_TESTS();
}
diff --git a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 21c5315..00112b1 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -54,8 +54,12 @@
* use by the IRemotelyProvisionedComponent.
*
* The root keypair is generated by immutable code (e.g. ROM), from a Unique Device Secret (UDS).
- * The keypair that is generated from it can be referred to as the UDS_Pub/UDS_Priv keys. After the
- * device-unique secret is used, it must be made unavailable to any later boot stage.
+ * The UDS is a hardware-bound secret that forms the root of identify for the device and code
+ * running on the device. The keypair generated from the UDS is referred to as the UDS_Pub/UDS_Priv
+ * keypair. After the device-unique secret is used, it must be made unavailable to any later boot
+ * stage. Refer to the
+ * [Open Profile for DICE ](https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md#uds-details)
+ * specification for more details on the UDS.
*
* In this way, booting the device incrementally builds a certificate chain that (a) identifies and
* validates the integrity of every stage and (b) contains a set of public keys that correspond to
@@ -95,8 +99,8 @@
*
* 2) The CDI_Leaf_Priv key cannot be used to sign arbitrary data.
*
- * 3) Backend infrastructure does not correlate UDS_Pub with the certificates signed and sent back
- * to the device.
+ * 3) Backend infrastructure very closely guards access to UDS_Pub, limiting it to the minimum
+ * set of services that need to know it for security, privacy, and counter-abuse purposes.
*
* Versioning
* ==========
diff --git a/security/secretkeeper/OWNERS b/security/secretkeeper/OWNERS
index acf4c6c..d63ba9b 100644
--- a/security/secretkeeper/OWNERS
+++ b/security/secretkeeper/OWNERS
@@ -1,6 +1,5 @@
# Bug component: 867125
-alanstokes@google.com
drysdale@google.com
hasinitg@google.com
shikhapanwar@google.com
diff --git a/security/see/hwcrypto/aidl/Android.bp b/security/see/hwcrypto/aidl/Android.bp
index c64b827..2115f19 100644
--- a/security/see/hwcrypto/aidl/Android.bp
+++ b/security/see/hwcrypto/aidl/Android.bp
@@ -31,6 +31,7 @@
},
frozen: true,
system_ext_specific: true,
+ vendor_available: true,
versions_with_info: [
{
version: "1",
diff --git a/security/see/hwcrypto/aidl/vts/functional/Android.bp b/security/see/hwcrypto/aidl/vts/functional/Android.bp
index beb8976..c2514d1 100644
--- a/security/see/hwcrypto/aidl/vts/functional/Android.bp
+++ b/security/see/hwcrypto/aidl/vts/functional/Android.bp
@@ -19,6 +19,8 @@
rust_defaults {
name: "hw_crypto_hal_aidl_rust_defaults",
enabled: false,
+ prefer_rlib: true,
+ vendor_available: true,
rustlibs: [
"libbinder_rs",
"android.hardware.security.see.hwcrypto-V1-rust",
@@ -30,7 +32,7 @@
"librustutils",
],
arch: {
- x86_64: {
+ arm64: {
enabled: true,
},
},
@@ -47,22 +49,6 @@
],
}
-rust_binary {
- name: "wait_hw_crypto",
- prefer_rlib: true,
- defaults: [
- "hw_crypto_hal_aidl_rust_defaults",
- ],
- srcs: ["wait_service.rs"],
- rustlibs: [
- "libhwcryptohal_vts_test",
- "liblogger",
- "liblog_rust",
- "libanyhow",
- "libclap",
- ],
-}
-
rust_test {
name: "VtsAidlHwCryptoConnTest",
srcs: ["connection_test.rs"],
@@ -73,11 +59,4 @@
rustlibs: [
"libhwcryptohal_vts_test",
],
- data: [
- ":trusty_test_vm_elf",
- ":trusty_test_vm_config",
- ":trusty_vm_launcher_sh",
- ":trusty_wait_ready_sh",
- ":wait_hw_crypto",
- ],
}
diff --git a/security/see/hwcrypto/aidl/vts/functional/AndroidTest.xml b/security/see/hwcrypto/aidl/vts/functional/AndroidTestSystem.xml
similarity index 92%
rename from security/see/hwcrypto/aidl/vts/functional/AndroidTest.xml
rename to security/see/hwcrypto/aidl/vts/functional/AndroidTestSystem.xml
index 73290cf..649be23 100644
--- a/security/see/hwcrypto/aidl/vts/functional/AndroidTest.xml
+++ b/security/see/hwcrypto/aidl/vts/functional/AndroidTestSystem.xml
@@ -27,8 +27,8 @@
<option name="push-file" key="trusty-wait-ready.sh" value="/data/local/tmp/trusty_test_vm/trusty-wait-ready.sh" />
<option name="push-file" key="wait_hw_crypto" value="/data/local/tmp/trusty_test_vm/wait_hw_crypto" />
<option name="push-file" key="trusty-test_vm-config.json" value="/data/local/tmp/trusty_test_vm/trusty-test_vm-config.json" />
- <option name="push-file" key="trusty_test_vm_elf" value="/data/local/tmp/trusty_test_vm/trusty_test_vm_elf" />
- <option name="push-file" key="VtsAidlHwCryptoConnTest" value="/data/local/tmp/VtsAidlHwCryptoConnTest" />
+ <option name="push-file" key="trusty_test_vm.elf" value="/data/local/tmp/trusty_test_vm/trusty_test_vm.elf" />
+ <option name="push-file" key="VtsAidlHwCryptoConnTestSystem" value="/data/local/tmp/VtsAidlHwCryptoConnTestSystem" />
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="throw-if-cmd-fail" value="true" />
@@ -47,7 +47,7 @@
<test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
<option name="test-device-path" value="/data/local/tmp" />
- <option name="module-name" value="VtsAidlHwCryptoConnTest" />
+ <option name="module-name" value="VtsAidlHwCryptoConnTestSystem" />
<!-- Rust tests are run in parallel by default. Run these ones
single-threaded, so that one test's secrets don't affect
the behaviour of a different test. -->
diff --git a/security/see/hwcrypto/aidl/vts/functional/lib.rs b/security/see/hwcrypto/aidl/vts/functional/lib.rs
index e14ac83..81ae3fa 100644
--- a/security/see/hwcrypto/aidl/vts/functional/lib.rs
+++ b/security/see/hwcrypto/aidl/vts/functional/lib.rs
@@ -17,19 +17,32 @@
//! VTS test library for HwCrypto functionality.
//! It provides the base clases necessaries to write HwCrypto VTS tests
-use anyhow::{Context, Result};
+#[cfg(target_arch = "x86_64")]
+use anyhow::Context;
+use anyhow::Result;
+#[cfg(target_arch = "x86_64")]
use binder::{ExceptionCode, FromIBinder, IntoBinderResult, ParcelFileDescriptor};
+#[cfg(target_arch = "x86_64")]
use rpcbinder::RpcSession;
+#[cfg(target_arch = "x86_64")]
use vsock::VsockStream;
+#[cfg(target_arch = "x86_64")]
use std::os::fd::{FromRawFd, IntoRawFd};
+#[cfg(target_arch = "x86_64")]
use std::fs::File;
+#[cfg(target_arch = "x86_64")]
use std::io::Read;
+#[cfg(target_arch = "x86_64")]
use rustutils::system_properties;
+#[cfg(target_arch = "aarch64")]
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::IHwCryptoKey::BpHwCryptoKey;
use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::IHwCryptoKey::IHwCryptoKey;
+#[cfg(target_arch = "x86_64")]
const HWCRYPTO_SERVICE_PORT: u32 = 4;
/// Local function to connect to service
+#[cfg(target_arch = "x86_64")]
pub fn connect_service<T: FromIBinder + ?Sized>(
cid: u32,
port: u32,
@@ -44,7 +57,8 @@
})
}
-/// Get a HwCryptoKey binder service object
+/// Get a HwCryptoKey binder service object using a direct vsock connection
+#[cfg(target_arch = "x86_64")]
pub fn get_hwcryptokey() -> Result<binder::Strong<dyn IHwCryptoKey>, binder::Status> {
let cid = system_properties::read("trusty.test_vm.vm_cid")
.context("couldn't get vm cid")
@@ -55,3 +69,10 @@
.or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT)?;
Ok(connect_service(cid, HWCRYPTO_SERVICE_PORT)?)
}
+
+/// Get a HwCryptoKey binder service object using the service manager
+#[cfg(target_arch = "aarch64")]
+pub fn get_hwcryptokey() -> Result<binder::Strong<dyn IHwCryptoKey>, binder::Status> {
+ let interface_name = <BpHwCryptoKey as IHwCryptoKey>::get_descriptor().to_owned() + "/default";
+ Ok(binder::get_interface(&interface_name)?)
+}
diff --git a/security/see/hwcrypto/aidl/vts/functional/wait_service.rs b/security/see/hwcrypto/aidl/vts/functional/wait_service.rs
deleted file mode 100644
index 13cbcb1..0000000
--- a/security/see/hwcrypto/aidl/vts/functional/wait_service.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2025, 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.
-
-//! Small utility to wait for hwcrypto service to be up
-
-use anyhow::{/*Context,*/ Result};
-use clap::Parser;
-use log::info;
-use std::{thread, time};
-
-#[derive(Parser)]
-/// Collection of CLI for trusty_security_vm_launcher
-pub struct Args {
- /// Number of repetitions for the wait
- #[arg(long, default_value_t = 20)]
- number_repetitions: u32,
-
- /// Delay between repetitiond
- #[arg(long, default_value_t = 2)]
- delay_between_repetitions: u32,
-}
-
-fn main() -> Result<()> {
- let args = Args::parse();
-
- info!("Waiting for hwcrypto service");
- let delay = time::Duration::new(args.delay_between_repetitions.into(), 0);
- for _ in 0..args.number_repetitions {
- let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey();
- if hw_crypto_key.is_ok() {
- break;
- }
- thread::sleep(delay);
- }
- Ok(())
-}
diff --git a/security/see/hwcrypto/default/Android.bp b/security/see/hwcrypto/default/Android.bp
new file mode 100644
index 0000000..ab23cfd
--- /dev/null
+++ b/security/see/hwcrypto/default/Android.bp
@@ -0,0 +1,140 @@
+// Copyright (C) 2025 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_library {
+ name: "hwcryptohallib",
+ enabled: false,
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libbinder",
+ "libbinder_ndk",
+ "libbinder_trusty",
+ "libtrusty",
+ "libutils",
+
+ // AIDL interface deps versions, please refer to below link
+ // https://source.android.com/docs/core/architecture/aidl/stable-aidl#module-naming-rules
+ "android.hardware.security.see.hwcrypto-V1-ndk",
+ "android.hardware.security.see.hwcrypto-V1-cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ srcs: ["hwcryptolib.cpp"],
+ proprietary: true,
+ arch: {
+ arm64: {
+ enabled: true,
+ },
+ },
+}
+
+cc_binary {
+ name: "android.hardware.trusty.hwcryptohal-service",
+ enabled: false,
+ relative_install_path: "hw",
+ srcs: [
+ "hwcrypto_delegator.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libbinder",
+ "libbinder_ndk",
+ "libbinder_trusty",
+ "libtrusty",
+ "libutils",
+ "hwcryptohallib",
+
+ // AIDL interface deps versions, please refer to below link
+ // https://source.android.com/docs/core/architecture/aidl/stable-aidl#module-naming-rules
+ "android.hardware.security.see.hwcrypto-V1-ndk",
+ "android.hardware.security.see.hwcrypto-V1-cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ proprietary: true,
+ vintf_fragments: ["android.hardware.security.see.hwcrypto-service.trusty.xml"],
+ init_rc: ["android.hardware.security.see.hwcrypto-service.trusty.rc"],
+ arch: {
+ arm64: {
+ enabled: true,
+ },
+ },
+}
+
+cc_fuzz {
+ name: "android.hardware.trusty.hwcryptohal-service_fuzzer",
+ enabled: false,
+ defaults: ["service_fuzzer_defaults"],
+ static_libs: [
+ "android.hardware.security.see.hwcrypto-V1-ndk",
+ "android.hardware.security.see.hwcrypto-V1-cpp",
+ "liblog",
+ "hwcryptohallib",
+ ],
+ shared_libs: [
+ "libbinder_trusty",
+ "libtrusty",
+ ],
+ srcs: ["fuzzer.cpp"],
+ fuzz_config: {
+ cc: [
+ "oarbildo@google.com",
+ ],
+ },
+ arch: {
+ arm64: {
+ enabled: true,
+ },
+ },
+}
+
+cc_test {
+ name: "HwCryptoHalDelegatorTests",
+ enabled: false,
+ srcs: [
+ "delegatorTest.cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libbinder",
+ "libbinder_ndk",
+ ],
+ static_libs: [
+ "android.hardware.security.see.hwcrypto-V1-ndk",
+ "android.hardware.security.see.hwcrypto-V1-cpp",
+ ],
+
+ arch: {
+ arm64: {
+ enabled: true,
+ },
+ },
+}
diff --git a/security/see/hwcrypto/default/android.hardware.security.see.hwcrypto-service.trusty.rc b/security/see/hwcrypto/default/android.hardware.security.see.hwcrypto-service.trusty.rc
new file mode 100644
index 0000000..8665755
--- /dev/null
+++ b/security/see/hwcrypto/default/android.hardware.security.see.hwcrypto-service.trusty.rc
@@ -0,0 +1,5 @@
+service trusty-hwcryptohal /vendor/bin/hw/android.hardware.trusty.hwcryptohal-service \
+-d ${ro.hardware.trusty_ipc_dev:-/dev/trusty-ipc-dev0}
+ class hal
+ user system
+ group system
diff --git a/security/see/hwcrypto/default/android.hardware.security.see.hwcrypto-service.trusty.xml b/security/see/hwcrypto/default/android.hardware.security.see.hwcrypto-service.trusty.xml
new file mode 100644
index 0000000..8ac0942
--- /dev/null
+++ b/security/see/hwcrypto/default/android.hardware.security.see.hwcrypto-service.trusty.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.security.see.hwcrypto</name>
+ <version>1</version>
+ <interface>
+ <name>IHwCryptoKey</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
\ No newline at end of file
diff --git a/security/see/hwcrypto/default/delegatorTest.cpp b/security/see/hwcrypto/default/delegatorTest.cpp
new file mode 100644
index 0000000..a80d6fd
--- /dev/null
+++ b/security/see/hwcrypto/default/delegatorTest.cpp
@@ -0,0 +1,49 @@
+#include <gtest/gtest.h>
+#include "hwcryptokeyimpl.h"
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
+TEST(HwCryptoHalDelegator, keyPolicyCppToNdk) {
+ cpp_hwcrypto::KeyPolicy cppPolicy = cpp_hwcrypto::KeyPolicy();
+ cppPolicy.keyType = cpp_hwcrypto::types::KeyType::AES_128_CBC_PKCS7_PADDING;
+ cppPolicy.usage = cpp_hwcrypto::types::KeyUse::DECRYPT;
+ cppPolicy.keyLifetime = cpp_hwcrypto::types::KeyLifetime::PORTABLE;
+ cppPolicy.keyManagementKey = false;
+ cppPolicy.keyPermissions.push_back(
+ cpp_hwcrypto::types::KeyPermissions::ALLOW_PORTABLE_KEY_WRAPPING);
+ ndk_hwcrypto::KeyPolicy ndkPolicy = android::trusty::hwcryptohalservice::convertKeyPolicy<
+ ndk_hwcrypto::KeyPolicy, cpp_hwcrypto::KeyPolicy>(cppPolicy);
+ EXPECT_EQ(ndkPolicy.keyType, ndk_hwcrypto::types::KeyType::AES_128_CBC_PKCS7_PADDING);
+ EXPECT_EQ(ndkPolicy.usage, ndk_hwcrypto::types::KeyUse::DECRYPT);
+ EXPECT_EQ(ndkPolicy.keyLifetime, ndk_hwcrypto::types::KeyLifetime::PORTABLE);
+ EXPECT_EQ(ndkPolicy.keyManagementKey, false);
+ EXPECT_EQ(ndkPolicy.keyPermissions.size(), 1ul);
+ EXPECT_EQ(ndkPolicy.keyPermissions[0],
+ ndk_hwcrypto::types::KeyPermissions::ALLOW_PORTABLE_KEY_WRAPPING);
+}
+
+TEST(HwCryptoHalDelegator, keyPolicyNdkToCpp) {
+ ndk_hwcrypto::KeyPolicy ndkPolicy = ndk_hwcrypto::KeyPolicy();
+ ndkPolicy.keyType = ndk_hwcrypto::types::KeyType::AES_128_CTR;
+ ndkPolicy.usage = ndk_hwcrypto::types::KeyUse::ENCRYPT_DECRYPT;
+ ndkPolicy.keyLifetime = ndk_hwcrypto::types::KeyLifetime::HARDWARE;
+ ndkPolicy.keyManagementKey = true;
+ ndkPolicy.keyPermissions.push_back(
+ ndk_hwcrypto::types::KeyPermissions::ALLOW_EPHEMERAL_KEY_WRAPPING);
+ ndkPolicy.keyPermissions.push_back(
+ ndk_hwcrypto::types::KeyPermissions::ALLOW_HARDWARE_KEY_WRAPPING);
+ cpp_hwcrypto::KeyPolicy cppPolicy = android::trusty::hwcryptohalservice::convertKeyPolicy<
+ cpp_hwcrypto::KeyPolicy, ndk_hwcrypto::KeyPolicy>(ndkPolicy);
+ EXPECT_EQ(cppPolicy.keyType, cpp_hwcrypto::types::KeyType::AES_128_CTR);
+ EXPECT_EQ(cppPolicy.usage, cpp_hwcrypto::types::KeyUse::ENCRYPT_DECRYPT);
+ EXPECT_EQ(cppPolicy.keyLifetime, cpp_hwcrypto::types::KeyLifetime::HARDWARE);
+ EXPECT_EQ(cppPolicy.keyManagementKey, true);
+ EXPECT_EQ(cppPolicy.keyPermissions.size(), 2ul);
+ EXPECT_EQ(cppPolicy.keyPermissions[0],
+ cpp_hwcrypto::types::KeyPermissions::ALLOW_EPHEMERAL_KEY_WRAPPING);
+ EXPECT_EQ(cppPolicy.keyPermissions[1],
+ cpp_hwcrypto::types::KeyPermissions::ALLOW_HARDWARE_KEY_WRAPPING);
+}
\ No newline at end of file
diff --git a/security/see/hwcrypto/default/fuzzer.cpp b/security/see/hwcrypto/default/fuzzer.cpp
new file mode 100644
index 0000000..4673066
--- /dev/null
+++ b/security/see/hwcrypto/default/fuzzer.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include "hwcryptokeyimpl.h"
+
+using android::fuzzService;
+using ndk::SharedRefBase;
+
+static const char* TIPC_DEFAULT_DEVNAME = "/dev/trusty-ipc-dev0";
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ auto hwCryptoServer =
+ android::trusty::hwcryptohalservice::HwCryptoKey::Create(TIPC_DEFAULT_DEVNAME);
+
+ fuzzService(hwCryptoServer->asBinder().get(), FuzzedDataProvider(data, size));
+
+ return 0;
+}
diff --git a/security/see/hwcrypto/default/hwcrypto_delegator.cpp b/security/see/hwcrypto/default/hwcrypto_delegator.cpp
new file mode 100644
index 0000000..1c3528c
--- /dev/null
+++ b/security/see/hwcrypto/default/hwcrypto_delegator.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2025 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 <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <getopt.h>
+#include <string>
+#include "hwcryptokeyimpl.h"
+
+static void showUsageAndExit(int code) {
+ LOG(ERROR) << "usage: android.hardware.trusty.hwcryptohal-service -d <trusty_dev>";
+ exit(code);
+}
+
+static void parseDeviceName(int argc, char* argv[], char*& device_name) {
+ static const char* _sopts = "h:d:";
+ static const struct option _lopts[] = {{"help", no_argument, nullptr, 'h'},
+ {"trusty_dev", required_argument, nullptr, 'd'},
+ {0, 0, 0, 0}};
+ int opt;
+ int oidx = 0;
+
+ while ((opt = getopt_long(argc, argv, _sopts, _lopts, &oidx)) != -1) {
+ switch (opt) {
+ case 'd':
+ device_name = strdup(optarg);
+ break;
+ case 'h':
+ showUsageAndExit(EXIT_SUCCESS);
+ break;
+ default:
+ LOG(ERROR) << "unrecognized option: " << opt;
+ showUsageAndExit(EXIT_FAILURE);
+ }
+ }
+
+ if (device_name == nullptr) {
+ LOG(ERROR) << "missing required argument(s)";
+ showUsageAndExit(EXIT_FAILURE);
+ }
+
+ LOG(INFO) << "starting android.hardware.trusty.hwcryptohal-service";
+ LOG(INFO) << "trusty dev: " << device_name;
+}
+
+int main(int argc, char* argv[]) {
+ char* device_name;
+ parseDeviceName(argc, argv, device_name);
+
+ auto hwCryptoServer = android::trusty::hwcryptohalservice::HwCryptoKey::Create(device_name);
+ if (hwCryptoServer == nullptr) {
+ LOG(ERROR) << "couldn't create hwcrypto service";
+ exit(EXIT_FAILURE);
+ }
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ const std::string instance =
+ std::string() + ndk_hwcrypto::IHwCryptoKey::descriptor + "/default";
+ binder_status_t status =
+ AServiceManager_addService(hwCryptoServer->asBinder().get(), instance.c_str());
+ if (status != STATUS_OK) {
+ LOG(ERROR) << "couldn't register hwcrypto service";
+ }
+ CHECK_EQ(status, STATUS_OK);
+ ABinderProcess_joinThreadPool();
+
+ return 0;
+}
diff --git a/security/see/hwcrypto/default/hwcryptokeyimpl.h b/security/see/hwcrypto/default/hwcryptokeyimpl.h
new file mode 100644
index 0000000..19be8b4
--- /dev/null
+++ b/security/see/hwcrypto/default/hwcryptokeyimpl.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/security/see/hwcrypto/BnHwCryptoKey.h>
+#include <aidl/android/hardware/security/see/hwcrypto/IHwCryptoKey.h>
+#include <aidl/android/hardware/security/see/hwcrypto/types/HalErrorCode.h>
+#include <android-base/logging.h>
+#include <android-base/result.h>
+#include <android/hardware/security/see/hwcrypto/IHwCryptoKey.h>
+#include <binder/RpcSession.h>
+
+// We use cpp interfaces to talk to Trusty, and ndk interfaces for the platform
+namespace cpp_hwcrypto = android::hardware::security::see::hwcrypto;
+namespace ndk_hwcrypto = aidl::android::hardware::security::see::hwcrypto;
+
+namespace android {
+namespace trusty {
+namespace hwcryptohalservice {
+
+class HwCryptoKey : public ndk_hwcrypto::BnHwCryptoKey {
+ private:
+ sp<cpp_hwcrypto::IHwCryptoKey> mHwCryptoServer;
+ sp<IBinder> mRoot;
+ sp<RpcSession> mSession;
+ android::base::Result<void> connectToTrusty(const char* tipcDev);
+
+ public:
+ HwCryptoKey();
+
+ static std::shared_ptr<HwCryptoKey> Create(const char* tipcDev);
+
+ ndk::ScopedAStatus deriveCurrentDicePolicyBoundKey(
+ const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& derivationKey,
+ ndk_hwcrypto::IHwCryptoKey::DiceCurrentBoundKeyResult* aidl_return);
+
+ ndk::ScopedAStatus deriveDicePolicyBoundKey(
+ const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& derivationKey,
+ const ::std::vector<uint8_t>& dicePolicyForKeyVersion,
+ ndk_hwcrypto::IHwCryptoKey::DiceBoundKeyResult* aidl_return);
+ ndk::ScopedAStatus deriveKey(const ndk_hwcrypto::IHwCryptoKey::DerivedKeyParameters& parameters,
+ ndk_hwcrypto::IHwCryptoKey::DerivedKey* aidl_return);
+
+ ndk::ScopedAStatus getHwCryptoOperations(
+ std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations>* aidl_return);
+
+ ndk::ScopedAStatus importClearKey(const ndk_hwcrypto::types::ExplicitKeyMaterial& keyMaterial,
+ const ndk_hwcrypto::KeyPolicy& newKeyPolicy,
+ std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return);
+
+ ndk::ScopedAStatus getCurrentDicePolicy(std::vector<uint8_t>* aidl_return);
+
+ ndk::ScopedAStatus keyTokenImport(const ndk_hwcrypto::types::OpaqueKeyToken& requestedKey,
+ const ::std::vector<uint8_t>& sealingDicePolicy,
+ std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return);
+
+ ndk::ScopedAStatus getKeyslotData(ndk_hwcrypto::IHwCryptoKey::KeySlot slotId,
+ std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return);
+};
+
+template <typename LHP, typename RHP>
+LHP convertKeyPolicy(const RHP& policyToConvert) {
+ LHP policy = LHP();
+ policy.usage = static_cast<decltype(policy.usage)>(policyToConvert.usage);
+ policy.keyLifetime = static_cast<decltype(policy.keyLifetime)>(policyToConvert.keyLifetime);
+ policy.keyType = static_cast<decltype(policy.keyType)>(policyToConvert.keyType);
+ policy.keyManagementKey = policyToConvert.keyManagementKey;
+ for (auto permission : policyToConvert.keyPermissions) {
+ policy.keyPermissions.push_back(
+ std::move(reinterpret_cast<decltype(policy.keyPermissions[0])>(permission)));
+ }
+ return policy;
+}
+
+template <typename CPP, typename NDK,
+ std::map<std::weak_ptr<NDK>, wp<CPP>, std::owner_less<>>& mapping>
+sp<CPP> retrieveCppBinder(const std::shared_ptr<NDK>& ndkBinder) {
+ if (ndkBinder == nullptr) {
+ return nullptr;
+ }
+ if (mapping.find(ndkBinder) == mapping.end()) {
+ LOG(ERROR) << "couldn't find wrapped key";
+ return nullptr;
+ }
+ auto cppBbinder = mapping[ndkBinder];
+ return cppBbinder.promote();
+}
+
+template <typename CPP_BINDER, typename NDK_BINDER, typename NDK_BASE,
+ std::map<std::weak_ptr<NDK_BINDER>, wp<CPP_BINDER>, std::owner_less<>>& mapping>
+void insertBinderMapping(const sp<CPP_BINDER>& cppBinder, std::shared_ptr<NDK_BINDER>* ndkBinder) {
+ std::shared_ptr<NDK_BINDER> spNdkBinder = NDK_BASE::Create(cppBinder);
+ std::weak_ptr<NDK_BINDER> wptrNdkBinder = spNdkBinder;
+ wp<CPP_BINDER> wpCppBinder = cppBinder;
+ mapping.insert({wptrNdkBinder, wpCppBinder});
+ *ndkBinder = spNdkBinder;
+}
+
+} // namespace hwcryptohalservice
+} // namespace trusty
+} // namespace android
diff --git a/security/see/hwcrypto/default/hwcryptolib.cpp b/security/see/hwcrypto/default/hwcryptolib.cpp
new file mode 100644
index 0000000..0e15883
--- /dev/null
+++ b/security/see/hwcrypto/default/hwcryptolib.cpp
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2025 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/security/see/hwcrypto/BnCryptoOperationContext.h>
+#include <aidl/android/hardware/security/see/hwcrypto/BnHwCryptoOperations.h>
+#include <aidl/android/hardware/security/see/hwcrypto/BnOpaqueKey.h>
+#include <aidl/android/hardware/security/see/hwcrypto/IOpaqueKey.h>
+#include <android-base/logging.h>
+#include <android/hardware/security/see/hwcrypto/BnHwCryptoKey.h>
+#include <binder/RpcTrusty.h>
+#include <trusty/tipc.h>
+#include <optional>
+#include <string>
+#include "hwcryptokeyimpl.h"
+
+using android::IBinder;
+using android::IInterface;
+using android::RpcSession;
+using android::RpcTrustyConnectWithSessionInitializer;
+using android::sp;
+using android::wp;
+using android::base::ErrnoError;
+using android::base::Error;
+using android::base::Result;
+using android::binder::Status;
+
+namespace android {
+namespace trusty {
+namespace hwcryptohalservice {
+
+#define HWCRYPTO_KEY_PORT "com.android.trusty.rust.hwcryptohal.V1"
+
+// Even though we get the cpp_hwcrypto::IOpaqueKey and cpp_hwcrypto::ICryptoOperationContext and
+// create the ndk_hwcrypto wrappers on this library we cannot cast them back when we need them
+// because they are received on the function calls as binder objects and there is no reliable
+// we to do this cast yet. Because of that we are creating maps to hold the wrapped objects
+// and translate them on function calls.
+// TODO: Add cleanup of both keyMapping and contextMapping once we have more test infrastructure in
+// place.
+std::map<std::weak_ptr<ndk_hwcrypto::IOpaqueKey>, wp<cpp_hwcrypto::IOpaqueKey>, std::owner_less<>>
+ keyMapping;
+std::map<std::weak_ptr<ndk_hwcrypto::ICryptoOperationContext>,
+ wp<cpp_hwcrypto::ICryptoOperationContext>, std::owner_less<>>
+ contextMapping;
+
+static ndk::ScopedAStatus convertStatus(Status status) {
+ if (status.isOk()) {
+ return ndk::ScopedAStatus::ok();
+ } else {
+ auto exCode = status.exceptionCode();
+ if (exCode == Status::Exception::EX_SERVICE_SPECIFIC) {
+ return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ status.serviceSpecificErrorCode(), status.exceptionMessage());
+ } else {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(exCode,
+ status.exceptionMessage());
+ }
+ }
+}
+
+static std::optional<cpp_hwcrypto::types::ExplicitKeyMaterial> convertExplicitKeyMaterial(
+ const ndk_hwcrypto::types::ExplicitKeyMaterial& keyMaterial) {
+ auto explicitKeyCpp = cpp_hwcrypto::types::ExplicitKeyMaterial();
+
+ if (keyMaterial.getTag() == ndk_hwcrypto::types::ExplicitKeyMaterial::aes) {
+ auto aesKey = keyMaterial.get<ndk_hwcrypto::types::ExplicitKeyMaterial::aes>();
+ auto aesKeyCpp = cpp_hwcrypto::types::AesKey();
+ if (aesKey.getTag() == ndk_hwcrypto::types::AesKey::aes128) {
+ aesKeyCpp.set<cpp_hwcrypto::types::AesKey::aes128>(
+ aesKey.get<ndk_hwcrypto::types::AesKey::aes128>());
+ explicitKeyCpp.set<cpp_hwcrypto::types::ExplicitKeyMaterial::aes>(aesKeyCpp);
+ } else if (aesKey.getTag() == ndk_hwcrypto::types::AesKey::aes256) {
+ aesKeyCpp.set<cpp_hwcrypto::types::AesKey::aes256>(
+ aesKey.get<ndk_hwcrypto::types::AesKey::aes256>());
+ explicitKeyCpp.set<cpp_hwcrypto::types::ExplicitKeyMaterial::aes>(aesKeyCpp);
+ } else {
+ LOG(ERROR) << "unknown AesKey type";
+ return std::nullopt;
+ }
+ } else if (keyMaterial.getTag() == ndk_hwcrypto::types::ExplicitKeyMaterial::hmac) {
+ auto hmacKey = keyMaterial.get<ndk_hwcrypto::types::ExplicitKeyMaterial::hmac>();
+ auto hmacKeyCpp = cpp_hwcrypto::types::HmacKey();
+ if (hmacKey.getTag() == ndk_hwcrypto::types::HmacKey::sha256) {
+ hmacKeyCpp.set<cpp_hwcrypto::types::HmacKey::sha256>(
+ hmacKey.get<ndk_hwcrypto::types::HmacKey::sha256>());
+ explicitKeyCpp.set<cpp_hwcrypto::types::ExplicitKeyMaterial::hmac>(hmacKeyCpp);
+ } else if (hmacKey.getTag() == ndk_hwcrypto::types::HmacKey::sha512) {
+ hmacKeyCpp.set<cpp_hwcrypto::types::HmacKey::sha512>(
+ hmacKey.get<ndk_hwcrypto::types::HmacKey::sha512>());
+ explicitKeyCpp.set<cpp_hwcrypto::types::ExplicitKeyMaterial::hmac>(hmacKeyCpp);
+ } else {
+ LOG(ERROR) << "unknown HmacKey type";
+ return std::nullopt;
+ }
+ } else {
+ LOG(ERROR) << "unknown Key type";
+ return std::nullopt;
+ }
+ return explicitKeyCpp;
+}
+
+class HwCryptoOperationContextNdk : public ndk_hwcrypto::BnCryptoOperationContext {
+ private:
+ sp<cpp_hwcrypto::ICryptoOperationContext> mContext;
+
+ public:
+ HwCryptoOperationContextNdk(sp<cpp_hwcrypto::ICryptoOperationContext> operations)
+ : mContext(std::move(operations)) {}
+
+ static std::shared_ptr<HwCryptoOperationContextNdk> Create(
+ sp<cpp_hwcrypto::ICryptoOperationContext> operations) {
+ if (operations == nullptr) {
+ return nullptr;
+ }
+ std::shared_ptr<HwCryptoOperationContextNdk> contextNdk =
+ ndk::SharedRefBase::make<HwCryptoOperationContextNdk>(std::move(operations));
+
+ if (!contextNdk) {
+ LOG(ERROR) << "failed to allocate HwCryptoOperationContext";
+ return nullptr;
+ }
+ return contextNdk;
+ }
+};
+
+// TODO: Check refactoring opportunities like returning a Result<cpp_hwcrypto::types::OperationData>
+// once we add the code that uses this function.
+Result<void> setOperationData(const ndk_hwcrypto::types::OperationData& ndkOperationData,
+ cpp_hwcrypto::types::OperationData* cppOperationData) {
+ cpp_hwcrypto::types::MemoryBufferReference cppMemBuffRef;
+ switch (ndkOperationData.getTag()) {
+ case ndk_hwcrypto::types::OperationData::dataBuffer:
+ cppOperationData->set<cpp_hwcrypto::types::OperationData::dataBuffer>(
+ ndkOperationData.get<ndk_hwcrypto::types::OperationData::dataBuffer>());
+ break;
+ case ndk_hwcrypto::types::OperationData::memoryBufferReference:
+ cppMemBuffRef.startOffset =
+ ndkOperationData
+ .get<ndk_hwcrypto::types::OperationData::memoryBufferReference>()
+ .startOffset;
+ cppMemBuffRef.sizeBytes =
+ ndkOperationData
+ .get<ndk_hwcrypto::types::OperationData::memoryBufferReference>()
+ .sizeBytes;
+ cppOperationData->set<cpp_hwcrypto::types::OperationData::memoryBufferReference>(
+ std::move(cppMemBuffRef));
+ break;
+ default:
+ // This shouldn't happen with the current definitions
+ return ErrnoError() << "received unknown operation data type";
+ }
+ return {};
+}
+
+class HwCryptoOperationsNdk : public ndk_hwcrypto::BnHwCryptoOperations {
+ private:
+ sp<cpp_hwcrypto::IHwCryptoOperations> mHwCryptoOperations;
+
+ public:
+ HwCryptoOperationsNdk(sp<cpp_hwcrypto::IHwCryptoOperations> operations)
+ : mHwCryptoOperations(std::move(operations)) {}
+
+ static std::shared_ptr<HwCryptoOperationsNdk> Create(
+ sp<cpp_hwcrypto::IHwCryptoOperations> operations) {
+ if (operations == nullptr) {
+ return nullptr;
+ }
+ std::shared_ptr<HwCryptoOperationsNdk> operationsNdk =
+ ndk::SharedRefBase::make<HwCryptoOperationsNdk>(std::move(operations));
+
+ if (!operationsNdk) {
+ LOG(ERROR) << "failed to allocate HwCryptoOperations";
+ return nullptr;
+ }
+ return operationsNdk;
+ }
+
+ ndk::ScopedAStatus processCommandList(
+ std::vector<ndk_hwcrypto::CryptoOperationSet>* /*operationSets*/,
+ std::vector<ndk_hwcrypto::CryptoOperationResult>* /*aidl_return*/) {
+ return ndk::ScopedAStatus::ok();
+ }
+};
+
+class OpaqueKeyNdk : public ndk_hwcrypto::BnOpaqueKey {
+ private:
+ sp<cpp_hwcrypto::IOpaqueKey> mOpaqueKey;
+
+ public:
+ OpaqueKeyNdk(sp<cpp_hwcrypto::IOpaqueKey> opaqueKey) : mOpaqueKey(std::move(opaqueKey)) {}
+
+ static std::shared_ptr<OpaqueKeyNdk> Create(sp<cpp_hwcrypto::IOpaqueKey> opaqueKey) {
+ if (opaqueKey == nullptr) {
+ return nullptr;
+ }
+ std::shared_ptr<OpaqueKeyNdk> opaqueKeyNdk =
+ ndk::SharedRefBase::make<OpaqueKeyNdk>(std::move(opaqueKey));
+
+ if (!opaqueKeyNdk) {
+ LOG(ERROR) << "failed to allocate HwCryptoKey";
+ return nullptr;
+ }
+ return opaqueKeyNdk;
+ }
+
+ ndk::ScopedAStatus exportWrappedKey(
+ const std::shared_ptr<ndk_hwcrypto::IOpaqueKey>& wrappingKey,
+ ::std::vector<uint8_t>* aidl_return) {
+ Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+ auto wrappingKeyNdk =
+ retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey, keyMapping>(
+ wrappingKey);
+ if (wrappingKeyNdk == nullptr) {
+ LOG(ERROR) << "couldn't get wrapped key";
+ return convertStatus(status);
+ }
+ status = mOpaqueKey->exportWrappedKey(wrappingKeyNdk, aidl_return);
+ return convertStatus(status);
+ }
+
+ ndk::ScopedAStatus getKeyPolicy(ndk_hwcrypto::KeyPolicy* aidl_return) {
+ Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+ if (aidl_return == nullptr) {
+ LOG(ERROR) << "return value passed to getKeyPolicy is nullptr";
+ return convertStatus(status);
+ }
+ cpp_hwcrypto::KeyPolicy cppPolicy = cpp_hwcrypto::KeyPolicy();
+
+ status = mOpaqueKey->getKeyPolicy(&cppPolicy);
+ if (status.isOk()) {
+ auto ndkPolicy =
+ convertKeyPolicy<ndk_hwcrypto::KeyPolicy, cpp_hwcrypto::KeyPolicy>(cppPolicy);
+ *aidl_return = std::move(ndkPolicy);
+ }
+ return convertStatus(status);
+ }
+
+ ndk::ScopedAStatus getPublicKey(::std::vector<uint8_t>* aidl_return) {
+ auto status = mOpaqueKey->getPublicKey(aidl_return);
+ return convertStatus(status);
+ }
+
+ ndk::ScopedAStatus getShareableToken(const ::std::vector<uint8_t>& sealingDicePolicy,
+ ndk_hwcrypto::types::OpaqueKeyToken* aidl_return) {
+ Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+ if (aidl_return == nullptr) {
+ LOG(ERROR) << "return value passed to getShareableToken is nullptr";
+ return convertStatus(status);
+ }
+ cpp_hwcrypto::types::OpaqueKeyToken binder_return;
+ status = mOpaqueKey->getShareableToken(sealingDicePolicy, &binder_return);
+ if (status.isOk()) {
+ aidl_return->keyToken = std::move(binder_return.keyToken);
+ }
+ return convertStatus(status);
+ }
+
+ ndk::ScopedAStatus setProtectionId(
+ const ndk_hwcrypto::types::ProtectionId /*protectionId*/,
+ const ::std::vector<ndk_hwcrypto::types::OperationType>& /*allowedOperations*/) {
+ return ndk::ScopedAStatus::ok();
+ }
+};
+
+Result<void> HwCryptoKey::connectToTrusty(const char* tipcDev) {
+ assert(!mSession);
+ mSession = RpcTrustyConnectWithSessionInitializer(tipcDev, HWCRYPTO_KEY_PORT, [](auto) {});
+ if (!mSession) {
+ return ErrnoError() << "failed to connect to hwcrypto";
+ }
+ mRoot = mSession->getRootObject();
+ mHwCryptoServer = cpp_hwcrypto::IHwCryptoKey::asInterface(mRoot);
+ return {};
+}
+
+HwCryptoKey::HwCryptoKey() {}
+
+std::shared_ptr<HwCryptoKey> HwCryptoKey::Create(const char* tipcDev) {
+ std::shared_ptr<HwCryptoKey> hwCrypto = ndk::SharedRefBase::make<HwCryptoKey>();
+
+ if (!hwCrypto) {
+ LOG(ERROR) << "failed to allocate HwCryptoKey";
+ return nullptr;
+ }
+
+ auto ret = hwCrypto->connectToTrusty(tipcDev);
+ if (!ret.ok()) {
+ LOG(ERROR) << "failed to connect HwCryptoKey to Trusty: " << ret.error();
+ return nullptr;
+ }
+
+ return hwCrypto;
+}
+
+ndk::ScopedAStatus HwCryptoKey::deriveCurrentDicePolicyBoundKey(
+ const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& /*derivationKey*/,
+ ndk_hwcrypto::IHwCryptoKey::DiceCurrentBoundKeyResult* /*aidl_return*/) {
+ // return mHwCryptoServer->deriveCurrentDicePolicyBoundKey(derivationKey, aidl_return);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus HwCryptoKey::deriveDicePolicyBoundKey(
+ const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& /*derivationKey*/,
+ const ::std::vector<uint8_t>& /*dicePolicyForKeyVersion*/,
+ ndk_hwcrypto::IHwCryptoKey::DiceBoundKeyResult* /*aidl_return*/) {
+ // return mHwCryptoServer->deriveDicePolicyBoundKey(derivationKey, dicePolicyForKeyVersion,
+ // aidl_return);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus HwCryptoKey::deriveKey(
+ const ndk_hwcrypto::IHwCryptoKey::DerivedKeyParameters& /*parameters*/,
+ ndk_hwcrypto::IHwCryptoKey::DerivedKey* /*aidl_return*/) {
+ // return mHwCryptoServer->deriveKey(parameters, aidl_return);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus HwCryptoKey::getHwCryptoOperations(
+ std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations>* aidl_return) {
+ Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+ if (aidl_return == nullptr) {
+ LOG(ERROR) << "return value passed to getHwCryptoOperations is nullptr";
+ return convertStatus(status);
+ }
+ sp<cpp_hwcrypto::IHwCryptoOperations> binder_return;
+ status = mHwCryptoServer->getHwCryptoOperations(&binder_return);
+ if (status.isOk()) {
+ std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations> operations =
+ HwCryptoOperationsNdk::Create(binder_return);
+ *aidl_return = operations;
+ }
+ return convertStatus(status);
+}
+
+ndk::ScopedAStatus HwCryptoKey::importClearKey(
+ const ndk_hwcrypto::types::ExplicitKeyMaterial& keyMaterial,
+ const ndk_hwcrypto::KeyPolicy& newKeyPolicy,
+ std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) {
+ sp<cpp_hwcrypto::IOpaqueKey> binder_return = nullptr;
+ Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+ if (aidl_return == nullptr) {
+ LOG(ERROR) << "return value passed to importClearKey is nullptr";
+ return convertStatus(status);
+ }
+ auto cppKeyPolicy =
+ convertKeyPolicy<cpp_hwcrypto::KeyPolicy, ndk_hwcrypto::KeyPolicy>(newKeyPolicy);
+ auto explicitKeyCpp = convertExplicitKeyMaterial(keyMaterial);
+ if (!explicitKeyCpp.has_value()) {
+ LOG(ERROR) << "couldn't convert key material";
+ return convertStatus(status);
+ }
+ status = mHwCryptoServer->importClearKey(explicitKeyCpp.value(), cppKeyPolicy, &binder_return);
+ if (status.isOk()) {
+ if ((binder_return != nullptr)) {
+ insertBinderMapping<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey, OpaqueKeyNdk,
+ keyMapping>(binder_return, aidl_return);
+ } else {
+ *aidl_return = nullptr;
+ }
+ }
+ return convertStatus(status);
+}
+
+ndk::ScopedAStatus HwCryptoKey::getCurrentDicePolicy(std::vector<uint8_t>* aidl_return) {
+ auto status = mHwCryptoServer->getCurrentDicePolicy(aidl_return);
+ return convertStatus(status);
+}
+
+ndk::ScopedAStatus HwCryptoKey::keyTokenImport(
+ const ndk_hwcrypto::types::OpaqueKeyToken& requestedKey,
+ const ::std::vector<uint8_t>& sealingDicePolicy,
+ std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) {
+ Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+ if (aidl_return == nullptr) {
+ LOG(ERROR) << "return value passed to keyTokenImport is nullptr";
+ return convertStatus(status);
+ }
+ sp<cpp_hwcrypto::IOpaqueKey> binder_return;
+ cpp_hwcrypto::types::OpaqueKeyToken requestedKeyCpp;
+ // trying first a shallow copy of the vector
+ requestedKeyCpp.keyToken = requestedKey.keyToken;
+ status = mHwCryptoServer->keyTokenImport(requestedKeyCpp, sealingDicePolicy, &binder_return);
+ if (status.isOk()) {
+ std::shared_ptr<ndk_hwcrypto::IOpaqueKey> opaqueKey = OpaqueKeyNdk::Create(binder_return);
+ *aidl_return = opaqueKey;
+ }
+ return convertStatus(status);
+}
+
+ndk::ScopedAStatus HwCryptoKey::getKeyslotData(
+ ndk_hwcrypto::IHwCryptoKey::KeySlot /*slotId*/,
+ std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* /*aidl_return*/) {
+ return ndk::ScopedAStatus::fromServiceSpecificError(
+ ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED);
+}
+
+} // namespace hwcryptohalservice
+} // namespace trusty
+} // namespace android
diff --git a/threadnetwork/aidl/default/Android.bp b/threadnetwork/aidl/default/Android.bp
index a840fa3..481f027 100644
--- a/threadnetwork/aidl/default/Android.bp
+++ b/threadnetwork/aidl/default/Android.bp
@@ -45,6 +45,41 @@
],
}
+cc_library_static {
+ name: "android.hardware.threadnetwork.lib",
+
+ vendor: true,
+ export_include_dirs: ["."],
+
+ defaults: ["android.hardware.threadnetwork-service.defaults"],
+
+ srcs: [
+ "service.cpp",
+ "thread_chip.cpp",
+ "utils.cpp",
+ ],
+
+ shared_libs: [
+ "libbinder_ndk",
+ "liblog",
+ ],
+
+ static_libs: [
+ "android.hardware.threadnetwork-V1-ndk",
+ "libbase",
+ "libcutils",
+ "libutils",
+ "openthread-common",
+ "openthread-hdlc",
+ "openthread-platform",
+ "openthread-posix",
+ "openthread-spi",
+ "openthread-url",
+ ],
+
+ stl: "c++_static",
+}
+
cc_defaults {
name: "android.hardware.threadnetwork-service.defaults",
product_variables: {
diff --git a/threadnetwork/aidl/default/thread_chip.cpp b/threadnetwork/aidl/default/thread_chip.cpp
index e312728..ba0baf2 100644
--- a/threadnetwork/aidl/default/thread_chip.cpp
+++ b/threadnetwork/aidl/default/thread_chip.cpp
@@ -83,6 +83,11 @@
mRxFrameBuffer.GetFrame(), mRxFrameBuffer.GetFrame() + mRxFrameBuffer.GetLength()));
}
+ if (mVendorCallback != nullptr) {
+ mVendorCallback->onReceiveSpinelFrame(std::vector<uint8_t>(
+ mRxFrameBuffer.GetFrame(), mRxFrameBuffer.GetFrame() + mRxFrameBuffer.GetLength()));
+ }
+
mRxFrameBuffer.DiscardFrame();
}
@@ -193,6 +198,10 @@
}
}
+void ThreadChip::setVendorCallback(const std::shared_ptr<IThreadChipCallback>& vendorCallback) {
+ mVendorCallback = vendorCallback;
+}
+
ndk::ScopedAStatus ThreadChip::errorStatus(int32_t error, const char* message) {
return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(error, message));
}
diff --git a/threadnetwork/aidl/default/thread_chip.hpp b/threadnetwork/aidl/default/thread_chip.hpp
index d07d049..6f23efe 100644
--- a/threadnetwork/aidl/default/thread_chip.hpp
+++ b/threadnetwork/aidl/default/thread_chip.hpp
@@ -43,6 +43,7 @@
ndk::ScopedAStatus hardwareReset() override;
void Update(otSysMainloopContext& context) override;
void Process(const otSysMainloopContext& context) override;
+ void setVendorCallback(const std::shared_ptr<IThreadChipCallback>& vendorCallback);
private:
static void onBinderDiedJump(void* context);
@@ -59,6 +60,7 @@
std::shared_ptr<ot::Spinel::SpinelInterface> mSpinelInterface;
ot::Spinel::SpinelInterface::RxFrameBuffer mRxFrameBuffer;
std::shared_ptr<IThreadChipCallback> mCallback;
+ std::shared_ptr<IThreadChipCallback> mVendorCallback;
::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
};
diff --git a/wifi/OWNERS b/wifi/OWNERS
index c10bbab..ec21f2e 100644
--- a/wifi/OWNERS
+++ b/wifi/OWNERS
@@ -7,4 +7,3 @@
# This will get them auto-assigned to the on-call triage engineer, ensuring quickest response.
#
arabawy@google.com
-etancohen@google.com