Merge "Skip testing of deprecated getDeviceIdentity on new interfaces" into main
diff --git a/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl b/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
index cfe001e..9b7fea2 100644
--- a/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
+++ b/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
@@ -188,6 +188,14 @@
* In the 'DRAINING' state the producer is inactive, the consumer is
* finishing up on the buffer contents, emptying it up. As soon as it
* gets empty, the stream transfers itself into the next state.
+ *
+ * Note that "early notify" draining is a more complex procedure
+ * intended for transitioning between two clips. Both 'DRAINING' and
+ * 'DRAIN_PAUSED' states have "sub-states" not visible via the API. See
+ * the details in the 'stream-out-async-sm.gv' state machine
+ * description. In the HAL API V3 this behavior is enabled when the
+ * HAL exposes "aosp.clipTransitionSupport" property, and in the HAL
+ * API V4 it is the default behavior.
*/
DRAINING = 5,
/**
@@ -234,9 +242,15 @@
/**
* Used with output streams only, the HAL module indicates drain
* completion shortly before all audio data has been consumed in order
- * to give the client an opportunity to provide data for the next track
+ * to give the client an opportunity to provide data for the next clip
* for gapless playback. The exact amount of provided time is specific
* to the HAL implementation.
+ *
+ * In the HAL API V3, the HAL sends two 'onDrainReady' notifications:
+ * one to indicate readiness to receive next clip data, and another when
+ * the previous clip has finished playing. This behavior is enabled when
+ * the HAL exposes "aosp.clipTransitionSupport" property, and in the HAL
+ * API V4 it is the default behavior.
*/
DRAIN_EARLY_NOTIFY = 2,
}
diff --git a/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv b/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv
index e2da90d..bf75594 100644
--- a/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv
+++ b/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv
@@ -32,27 +32,78 @@
IDLE -> TRANSFERRING [label="burst"]; // producer -> active
IDLE -> ACTIVE [label="burst"]; // full write
ACTIVE -> PAUSED [label="pause"]; // consumer -> passive (not consuming)
- ACTIVE -> DRAINING [label="drain"]; // producer -> passive
+ ACTIVE -> DRAINING [label="drain(ALL)"]; // producer -> passive
+ ACTIVE -> DRAINING_en [label="drain(EARLY_NOTIFY)"]; // prepare for clip transition
ACTIVE -> TRANSFERRING [label="burst"]; // early unblocking
ACTIVE -> ACTIVE [label="burst"]; // full write
TRANSFERRING -> ACTIVE [label="←IStreamCallback.onTransferReady"];
TRANSFERRING -> TRANSFER_PAUSED [label="pause"]; // consumer -> passive (not consuming)
- TRANSFERRING -> DRAINING [label="drain"]; // producer -> passive
+ TRANSFERRING -> DRAINING [label="drain(ALL)"]; // producer -> passive
+ TRANSFERRING -> DRAINING_en [label="drain(EARLY_NOTIFY)"]; // prepare for clip transition
TRANSFER_PAUSED -> TRANSFERRING [label="start"]; // consumer -> active
- TRANSFER_PAUSED -> DRAIN_PAUSED [label="drain"]; // producer -> passive
+ TRANSFER_PAUSED -> DRAIN_PAUSED [label="drain(ALL)"]; // producer -> passive
TRANSFER_PAUSED -> IDLE [label="flush"]; // buffer is cleared
PAUSED -> PAUSED [label="burst"];
PAUSED -> ACTIVE [label="start"]; // consumer -> active
PAUSED -> IDLE [label="flush"]; // producer -> passive, buffer is cleared
DRAINING -> IDLE [label="←IStreamCallback.onDrainReady"];
- DRAINING -> DRAINING [label="←IStreamCallback.onDrainReady"]; // allowed for `DRAIN_EARLY_NOTIFY`
- DRAINING -> IDLE [label="<empty buffer>"]; // allowed for `DRAIN_EARLY_NOTIFY`
DRAINING -> TRANSFERRING [label="burst"]; // producer -> active
DRAINING -> ACTIVE [label="burst"]; // full write
DRAINING -> DRAIN_PAUSED [label="pause"]; // consumer -> passive (not consuming)
DRAIN_PAUSED -> DRAINING [label="start"]; // consumer -> active
DRAIN_PAUSED -> TRANSFER_PAUSED [label="burst"]; // producer -> active
DRAIN_PAUSED -> IDLE [label="flush"]; // buffer is cleared
+ // Note that the states in both clusters are combined with 'DRAINING' and 'DRAIN_PAUSED'
+ // state at the API level. The 'en' and 'en_sent' attributes only belong to the internal
+ // state of the stream and are not observable outside.
+ subgraph cluster_early_notify_entering {
+ // The stream is preparing for a transition between two clips. After
+ // receiving 'drain(EARLY_NOTIFY)' command, the stream continues playing
+ // the current clip, and at some point notifies the client that it is
+ // ready for the next clip data by issuing the first 'onDrainReady'
+ // callback.
+ label="EARLY_NOTIFY (entering)";
+ color=gray;
+ // Getting 'burst' or 'flush' command in these states resets the "clip
+ // transition" mode.
+ DRAINING_en;
+ DRAIN_PAUSED_en;
+ }
+ subgraph cluster_early_notify_notification_sent {
+ // After the stream has sent "onDrainReady", the client can now send
+ // 'burst' commands with the data of the next clip. These 'bursts' are
+ // always "early unblocking" because the previous clip is still playing
+ // thus the stream is unable to play any of the received data
+ // synchronously (in other words, it can not do a "full write"). To
+ // indicate readiness to accept the next burst the stream uses the usual
+ // 'onTransferReady' callback.
+ label="EARLY_NOTIFY (notification sent)";
+ color=gray;
+ // The state machine remains in these states until the current clip ends
+ // playing. When it ends, the stream sends 'onDrainReady' (note that
+ // it's the second 'onDrainReady' for the same 'drain(EARLY_NOTIFY)'),
+ // and transitions either to 'IDLE' if there is no data for the next
+ // clip, or to 'TRANSFERRING' otherwise. Note that it can not transition
+ // to 'ACTIVE' because that transition is associated with
+ // 'onTransferReady' callback.
+ DRAINING_en_sent;
+ DRAIN_PAUSED_en_sent;
+ }
+ DRAINING_en -> TRANSFERRING [label="burst"]; // producer -> active
+ DRAINING_en -> ACTIVE [label="burst"]; // full write
+ DRAINING_en -> DRAIN_PAUSED_en [label="pause"]; // consumer -> passive (not consuming)
+ DRAINING_en -> DRAINING_en_sent [label="←IStreamCallback.onDrainReady"];
+ DRAIN_PAUSED_en -> DRAINING_en [label="start"]; // consumer -> active
+ DRAIN_PAUSED_en -> TRANSFER_PAUSED [label="burst"]; // producer -> active
+ DRAIN_PAUSED_en -> IDLE [label="flush"]; // buffer is cleared
+ DRAINING_en_sent -> DRAINING_en_sent [label="burst"];
+ DRAINING_en_sent -> DRAINING_en_sent [label="←IStreamCallback.onTransferReady"];
+ DRAINING_en_sent -> DRAIN_PAUSED_en_sent [label="pause"]; // consumer -> passive (not consuming)
+ DRAINING_en_sent -> TRANSFERRING [label="←IStreamCallback.onDrainReady"];
+ DRAINING_en_sent -> IDLE [label="←IStreamCallback.onDrainReady"];
+ DRAIN_PAUSED_en_sent -> DRAINING_en_sent [label="start"]; // consumer -> active
+ DRAIN_PAUSED_en_sent -> DRAIN_PAUSED_en_sent [label="burst"]; // producer -> active
+ DRAIN_PAUSED_en_sent -> IDLE [label="flush"]; // buffer is cleared
ANY_STATE -> ERROR [label="←IStreamCallback.onError"];
ANY_STATE -> CLOSED [label="→IStream*.close"];
CLOSED -> F;
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 077d80b..123a5ec 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -612,6 +612,15 @@
return ndk::ScopedAStatus::ok();
}
+binder_status_t Module::dump(int fd, const char** args, uint32_t numArgs) {
+ for (const auto& portConfig : getConfig().portConfigs) {
+ if (portConfig.ext.getTag() == AudioPortExt::Tag::mix) {
+ getStreams().dump(portConfig.id, fd, args, numArgs);
+ }
+ }
+ return STATUS_OK;
+}
+
ndk::ScopedAStatus Module::setModuleDebug(
const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) {
LOG(DEBUG) << __func__ << ": " << mType << ": old flags:" << mDebug.toString()
@@ -1546,6 +1555,7 @@
const std::string Module::VendorDebug::kForceTransientBurstName = "aosp.forceTransientBurst";
const std::string Module::VendorDebug::kForceSynchronousDrainName = "aosp.forceSynchronousDrain";
+const std::string Module::kClipTransitionSupportName = "aosp.clipTransitionSupport";
ndk::ScopedAStatus Module::getVendorParameters(const std::vector<std::string>& in_ids,
std::vector<VendorParameter>* _aidl_return) {
@@ -1560,6 +1570,10 @@
VendorParameter forceSynchronousDrain{.id = id};
forceSynchronousDrain.ext.setParcelable(Boolean{mVendorDebug.forceSynchronousDrain});
_aidl_return->push_back(std::move(forceSynchronousDrain));
+ } else if (id == kClipTransitionSupportName) {
+ VendorParameter clipTransitionSupport{.id = id};
+ clipTransitionSupport.ext.setParcelable(Boolean{true});
+ _aidl_return->push_back(std::move(clipTransitionSupport));
} else {
allParametersKnown = false;
LOG(VERBOSE) << __func__ << ": " << mType << ": unrecognized parameter \"" << id << "\"";
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index c6c1b5d..2800bed 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,16 +384,38 @@
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) {
const StreamDescriptor::State state = mState;
- LOG(DEBUG) << __func__ << ": state: " << toString(state)
+ const DrainState drainState = mDrainState;
+ LOG(DEBUG) << __func__ << ": state: " << toString(state) << ", drainState: " << drainState
<< ", bufferFramesLeft: " << bufferFramesLeft;
- if (state == StreamDescriptor::State::TRANSFERRING) {
- mState = StreamDescriptor::State::ACTIVE;
+ if (state == StreamDescriptor::State::TRANSFERRING || drainState == DrainState::EN_SENT) {
+ if (state == StreamDescriptor::State::TRANSFERRING) {
+ mState = StreamDescriptor::State::ACTIVE;
+ }
std::shared_ptr<IStreamCallback> asyncCallback = mContext->getAsyncCallback();
if (asyncCallback != nullptr) {
+ LOG(VERBOSE) << __func__ << ": sending onTransferReady";
ndk::ScopedAStatus status = asyncCallback->onTransferReady();
if (!status.isOk()) {
LOG(ERROR) << __func__ << ": error from onTransferReady: " << status;
@@ -411,8 +434,10 @@
mState =
hasNextClip ? StreamDescriptor::State::TRANSFERRING : StreamDescriptor::State::IDLE;
mDrainState = DrainState::NONE;
- if (drainState == DrainState::ALL && asyncCallback != nullptr) {
+ if ((drainState == DrainState::ALL || drainState == DrainState::EN_SENT) &&
+ asyncCallback != nullptr) {
LOG(DEBUG) << __func__ << ": sending onDrainReady";
+ // For EN_SENT, this is the second onDrainReady which notifies about clip transition.
ndk::ScopedAStatus status = asyncCallback->onDrainReady();
if (!status.isOk()) {
LOG(ERROR) << __func__ << ": error from onDrainReady: " << status;
@@ -523,9 +548,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();
@@ -539,13 +565,17 @@
mState = StreamDescriptor::State::TRANSFER_PAUSED;
}
} else if (mState == StreamDescriptor::State::IDLE ||
- mState == StreamDescriptor::State::DRAINING ||
- mState == StreamDescriptor::State::ACTIVE) {
+ mState == StreamDescriptor::State::ACTIVE ||
+ (mState == StreamDescriptor::State::DRAINING &&
+ mDrainState != DrainState::EN_SENT)) {
if (asyncCallback == nullptr || reply.fmqByteCount == fmqByteCount) {
mState = StreamDescriptor::State::ACTIVE;
} else {
switchToTransientState(StreamDescriptor::State::TRANSFERRING);
}
+ } else if (mState == StreamDescriptor::State::DRAINING &&
+ mDrainState == DrainState::EN_SENT) {
+ // keep mState
}
} else {
populateReplyWrongState(&reply, command);
@@ -700,6 +730,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/Module.h b/audio/aidl/default/include/core-impl/Module.h
index 6a43102..0661015 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -61,6 +61,8 @@
// The vendor extension done via inheritance can override interface methods and augment
// a call to the base implementation.
+ binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
ndk::ScopedAStatus setModuleDebug(
const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) override;
ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
@@ -159,6 +161,7 @@
// Multimap because both ports and configs can be used by multiple patches.
using Patches = std::multimap<int32_t, int32_t>;
+ static const std::string kClipTransitionSupportName;
const Type mType;
std::unique_ptr<Configuration> mConfig;
ModuleDebug mDebug;
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index f0139b4..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;
@@ -651,6 +653,12 @@
return ndk::ScopedAStatus::ok();
}
+ void dump(int fd, const char** args, uint32_t numArgs) const {
+ auto s = ::ndk::ICInterface::asInterface(mStreamBinder.get());
+ if (s) s->dump(fd, args, numArgs);
+ return;
+ }
+
private:
std::weak_ptr<StreamCommonInterface> mStream;
ndk::SpAIBinder mStreamBinder;
@@ -692,6 +700,12 @@
}
return ndk::ScopedAStatus::ok();
}
+ void dump(int32_t portConfigId, int fd, const char** args, uint32_t numArgs) const {
+ if (auto it = mStreams.find(portConfigId); it != mStreams.end()) {
+ it->second.dump(fd, args, numArgs);
+ }
+ return;
+ }
private:
// Maps port ids and port config ids to streams. Multimap because a port
diff --git a/audio/aidl/default/include/core-impl/StreamOffloadStub.h b/audio/aidl/default/include/core-impl/StreamOffloadStub.h
index 67abe95..24e98c2 100644
--- a/audio/aidl/default/include/core-impl/StreamOffloadStub.h
+++ b/audio/aidl/default/include/core-impl/StreamOffloadStub.h
@@ -26,14 +26,16 @@
namespace aidl::android::hardware::audio::core {
struct DspSimulatorState {
+ static constexpr int64_t kSkipBufferNotifyFrames = -1;
+
const std::string formatEncoding;
const int sampleRate;
const int64_t earlyNotifyFrames;
- const int64_t bufferNotifyFrames;
DriverCallbackInterface* callback = nullptr; // set before starting DSP worker
std::mutex lock;
std::vector<int64_t> clipFramesLeft GUARDED_BY(lock);
- int64_t bufferFramesLeft GUARDED_BY(lock);
+ int64_t bufferFramesLeft GUARDED_BY(lock) = 0;
+ int64_t bufferNotifyFrames GUARDED_BY(lock) = kSkipBufferNotifyFrames;
};
class DspSimulatorLogic : public ::android::hardware::audio::common::StreamLogic {
@@ -68,6 +70,7 @@
private:
::android::status_t startWorkerIfNeeded();
+ const int64_t mBufferNotifyFrames;
DspSimulatorState mState;
DspSimulatorWorker mDspWorker;
bool mDspWorkerStarted = false;
diff --git a/audio/aidl/default/stub/StreamOffloadStub.cpp b/audio/aidl/default/stub/StreamOffloadStub.cpp
index 95cef35..155f76d 100644
--- a/audio/aidl/default/stub/StreamOffloadStub.cpp
+++ b/audio/aidl/default/stub/StreamOffloadStub.cpp
@@ -42,14 +42,13 @@
const int64_t clipFramesPlayed =
(::android::uptimeNanos() - timeBeginNs) * mSharedState.sampleRate / NANOS_PER_SECOND;
const int64_t bufferFramesConsumed = clipFramesPlayed / 2; // assume 1:2 compression ratio
- int64_t bufferFramesLeft = 0;
+ int64_t bufferFramesLeft = 0, bufferNotifyFrames = DspSimulatorState::kSkipBufferNotifyFrames;
{
std::lock_guard l(mSharedState.lock);
mSharedState.bufferFramesLeft =
mSharedState.bufferFramesLeft > bufferFramesConsumed
? mSharedState.bufferFramesLeft - bufferFramesConsumed
: 0;
- bufferFramesLeft = mSharedState.bufferFramesLeft;
int64_t framesPlayed = clipFramesPlayed;
while (framesPlayed > 0 && !mSharedState.clipFramesLeft.empty()) {
LOG(VERBOSE) << __func__ << ": clips: "
@@ -65,10 +64,21 @@
clipNotifies.emplace_back(0 /*clipFramesLeft*/, hasNextClip);
framesPlayed -= mSharedState.clipFramesLeft[0];
mSharedState.clipFramesLeft.erase(mSharedState.clipFramesLeft.begin());
+ if (!hasNextClip) {
+ // Since it's a simulation, the buffer consumption rate it not real,
+ // thus 'bufferFramesLeft' might still have something, need to erase it.
+ mSharedState.bufferFramesLeft = 0;
+ }
}
}
+ bufferFramesLeft = mSharedState.bufferFramesLeft;
+ bufferNotifyFrames = mSharedState.bufferNotifyFrames;
+ if (bufferFramesLeft <= bufferNotifyFrames) {
+ // Suppress further notifications.
+ mSharedState.bufferNotifyFrames = DspSimulatorState::kSkipBufferNotifyFrames;
+ }
}
- if (bufferFramesLeft <= mSharedState.bufferNotifyFrames) {
+ if (bufferFramesLeft <= bufferNotifyFrames) {
LOG(DEBUG) << __func__ << ": sending onBufferStateChange: " << bufferFramesLeft;
mSharedState.callback->onBufferStateChange(bufferFramesLeft);
}
@@ -82,9 +92,9 @@
DriverOffloadStubImpl::DriverOffloadStubImpl(const StreamContext& context)
: DriverStubImpl(context, 0 /*asyncSleepTimeUs*/),
+ mBufferNotifyFrames(static_cast<int64_t>(context.getBufferSizeInFrames()) / 2),
mState{context.getFormat().encoding, context.getSampleRate(),
- 250 /*earlyNotifyMs*/ * context.getSampleRate() / MILLIS_PER_SECOND,
- static_cast<int64_t>(context.getBufferSizeInFrames()) / 2},
+ 250 /*earlyNotifyMs*/ * context.getSampleRate() / MILLIS_PER_SECOND},
mDspWorker(mState) {
LOG_IF(FATAL, !mIsAsynchronous) << "The steam must be used in asynchronous mode";
}
@@ -111,6 +121,7 @@
mState.clipFramesLeft.resize(1);
}
}
+ mState.bufferNotifyFrames = DspSimulatorState::kSkipBufferNotifyFrames;
return ::android::OK;
}
@@ -121,6 +132,7 @@
std::lock_guard l(mState.lock);
mState.clipFramesLeft.clear();
mState.bufferFramesLeft = 0;
+ mState.bufferNotifyFrames = DspSimulatorState::kSkipBufferNotifyFrames;
}
return ::android::OK;
}
@@ -128,6 +140,10 @@
::android::status_t DriverOffloadStubImpl::pause() {
RETURN_STATUS_IF_ERROR(DriverStubImpl::pause());
mDspWorker.pause();
+ {
+ std::lock_guard l(mState.lock);
+ mState.bufferNotifyFrames = DspSimulatorState::kSkipBufferNotifyFrames;
+ }
return ::android::OK;
}
@@ -140,6 +156,7 @@
hasClips = !mState.clipFramesLeft.empty();
LOG(DEBUG) << __func__
<< ": clipFramesLeft: " << ::android::internal::ToString(mState.clipFramesLeft);
+ mState.bufferNotifyFrames = DspSimulatorState::kSkipBufferNotifyFrames;
}
if (hasClips) {
mDspWorker.resume();
@@ -184,6 +201,7 @@
{
std::lock_guard l(mState.lock);
mState.bufferFramesLeft = *actualFrameCount;
+ mState.bufferNotifyFrames = mBufferNotifyFrames;
}
mDspWorker.resume();
return ::android::OK;
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 b1c5a1a..713af9a 100644
--- a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
@@ -522,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) {
@@ -597,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 21b7aff..806c93f 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -1025,6 +1025,7 @@
auto [eventSeq, event] = mEventReceiver->waitForEvent(mLastEventSeq);
mLastEventSeq = eventSeq;
if (event != *expEvent) {
+ // TODO: Make available as an error so it can be displayed by GTest
LOG(ERROR) << __func__ << ": expected event " << toString(*expEvent) << ", got "
<< toString(event);
return {};
@@ -1327,7 +1328,8 @@
public:
// To avoid timing out the whole test suite in case no event is received
// from the HAL, use a local timeout for event waiting.
- static constexpr auto kEventTimeoutMs = std::chrono::milliseconds(1000);
+ // TODO: The timeout for 'onTransferReady' should depend on the buffer size.
+ static constexpr auto kEventTimeoutMs = std::chrono::milliseconds(3000);
StreamEventReceiver* getEventReceiver() { return this; }
std::tuple<int, Event> getLastEvent() const override {
@@ -4236,15 +4238,17 @@
enum {
NAMED_CMD_NAME,
NAMED_CMD_MIN_INTERFACE_VERSION,
+ NAMED_CMD_FEATURE_PROPERTY,
NAMED_CMD_DELAY_MS,
NAMED_CMD_STREAM_TYPE,
NAMED_CMD_CMDS,
NAMED_CMD_VALIDATE_POS_INCREASE
};
-enum class StreamTypeFilter { ANY, SYNC, ASYNC };
+enum class StreamTypeFilter { ANY, SYNC, ASYNC, OFFLOAD };
using NamedCommandSequence =
- std::tuple<std::string, int /*minInterfaceVersion*/, int /*cmdDelayMs*/, StreamTypeFilter,
- std::shared_ptr<StateSequence>, bool /*validatePositionIncrease*/>;
+ std::tuple<std::string, int /*minInterfaceVersion*/, std::string /*featureProperty*/,
+ int /*cmdDelayMs*/, StreamTypeFilter, std::shared_ptr<StateSequence>,
+ bool /*validatePositionIncrease*/>;
enum { PARAM_MODULE_NAME, PARAM_CMD_SEQ, PARAM_SETUP_SEQ };
using StreamIoTestParameters =
std::tuple<std::string /*moduleName*/, NamedCommandSequence, bool /*useSetupSequence2*/>;
@@ -4255,11 +4259,24 @@
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(SetUpImpl(std::get<PARAM_MODULE_NAME>(GetParam())));
ASSERT_GE(aidlVersion, kAidlVersion1);
- if (const int minVersion =
- std::get<NAMED_CMD_MIN_INTERFACE_VERSION>(std::get<PARAM_CMD_SEQ>(GetParam()));
- aidlVersion < minVersion) {
+ const int minVersion =
+ std::get<NAMED_CMD_MIN_INTERFACE_VERSION>(std::get<PARAM_CMD_SEQ>(GetParam()));
+ if (aidlVersion < minVersion) {
GTEST_SKIP() << "Skip for audio HAL version lower than " << minVersion;
}
+ // When an associated feature property is defined, need to check that either that the HAL
+ // exposes this property, or it's of the version 'NAMED_CMD_MIN_INTERFACE_VERSION' + 1
+ // which must have this functionality implemented by default.
+ if (const std::string featureProperty =
+ std::get<NAMED_CMD_FEATURE_PROPERTY>(std::get<PARAM_CMD_SEQ>(GetParam()));
+ !featureProperty.empty() && aidlVersion < (minVersion + 1)) {
+ std::vector<VendorParameter> parameters;
+ ScopedAStatus result = module->getVendorParameters({featureProperty}, ¶meters);
+ if (!result.isOk() || parameters.size() != 1) {
+ GTEST_SKIP() << "Skip as audio HAL does not support feature \"" << featureProperty
+ << "\"";
+ }
+ }
ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
}
@@ -4300,10 +4317,18 @@
isBitPositionFlagSet(portConfig.flags.value()
.template get<AudioIoFlags::Tag::output>(),
AudioOutputFlags::NON_BLOCKING);
+ const bool isOffload =
+ IOTraits<Stream>::is_input
+ ? false
+ : isBitPositionFlagSet(
+ portConfig.flags.value()
+ .template get<AudioIoFlags::Tag::output>(),
+ AudioOutputFlags::COMPRESS_OFFLOAD);
if (auto streamType =
std::get<NAMED_CMD_STREAM_TYPE>(std::get<PARAM_CMD_SEQ>(GetParam()));
(isNonBlocking && streamType == StreamTypeFilter::SYNC) ||
- (!isNonBlocking && streamType == StreamTypeFilter::ASYNC)) {
+ (!isNonBlocking && streamType == StreamTypeFilter::ASYNC) ||
+ (!isOffload && streamType == StreamTypeFilter::OFFLOAD)) {
continue;
}
WithDebugFlags delayTransientStates = WithDebugFlags::createNested(*debug);
@@ -4760,6 +4785,18 @@
// TODO: Add async test cases for input once it is implemented.
+// Allow optional routing via the TRANSFERRING state on bursts.
+StateDag::Node makeAsyncBurstCommands(StateDag* d, size_t burstCount, StateDag::Node last) {
+ using State = StreamDescriptor::State;
+ std::reference_wrapper<std::remove_reference_t<StateDag::Node>> prev = last;
+ for (size_t i = 0; i < burstCount; ++i) {
+ StateDag::Node active = d->makeNode(State::ACTIVE, kBurstCommand, prev);
+ active.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, prev));
+ prev = active;
+ }
+ return prev;
+}
+
std::shared_ptr<StateSequence> makeBurstCommands(bool isSync, size_t burstCount,
bool standbyInputWhenDone) {
using State = StreamDescriptor::State;
@@ -4776,25 +4813,21 @@
d->makeNodes(State::ACTIVE, kBurstCommand, burstCount, last));
d->makeNode(State::STANDBY, kStartCommand, idle);
} else {
- StateDag::Node active2 = d->makeNode(State::ACTIVE, kBurstCommand, last);
- StateDag::Node active = d->makeNode(State::ACTIVE, kBurstCommand, active2);
+ StateDag::Node active = makeAsyncBurstCommands(d.get(), burstCount, last);
StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
- // Allow optional routing via the TRANSFERRING state on bursts.
- active2.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, last));
- active.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, active2));
idle.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, active));
d->makeNode(State::STANDBY, kStartCommand, idle);
}
return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kReadSeq =
- std::make_tuple(std::string("Read"), kAidlVersion1, 0, StreamTypeFilter::ANY,
+ std::make_tuple(std::string("Read"), kAidlVersion1, "", 0, StreamTypeFilter::ANY,
makeBurstCommands(true), true /*validatePositionIncrease*/);
static const NamedCommandSequence kWriteSyncSeq =
- std::make_tuple(std::string("Write"), kAidlVersion1, 0, StreamTypeFilter::SYNC,
+ std::make_tuple(std::string("Write"), kAidlVersion1, "", 0, StreamTypeFilter::SYNC,
makeBurstCommands(true), true /*validatePositionIncrease*/);
static const NamedCommandSequence kWriteAsyncSeq =
- std::make_tuple(std::string("Write"), kAidlVersion1, 0, StreamTypeFilter::ASYNC,
+ std::make_tuple(std::string("Write"), kAidlVersion1, "", 0, StreamTypeFilter::ASYNC,
makeBurstCommands(false), true /*validatePositionIncrease*/);
std::shared_ptr<StateSequence> makeAsyncDrainCommands(bool isInput) {
@@ -4824,10 +4857,10 @@
return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kWriteDrainAsyncSeq = std::make_tuple(
- std::string("WriteDrain"), kAidlVersion1, kStreamTransientStateTransitionDelayMs,
+ std::string("WriteDrain"), kAidlVersion1, "", kStreamTransientStateTransitionDelayMs,
StreamTypeFilter::ASYNC, makeAsyncDrainCommands(false), false /*validatePositionIncrease*/);
static const NamedCommandSequence kDrainInSeq =
- std::make_tuple(std::string("Drain"), kAidlVersion1, 0, StreamTypeFilter::ANY,
+ std::make_tuple(std::string("Drain"), kAidlVersion1, "", 0, StreamTypeFilter::ANY,
makeAsyncDrainCommands(true), false /*validatePositionIncrease*/);
std::shared_ptr<StateSequence> makeDrainOutCommands(bool isSync) {
@@ -4849,10 +4882,10 @@
return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kDrainOutSyncSeq =
- std::make_tuple(std::string("Drain"), kAidlVersion1, 0, StreamTypeFilter::SYNC,
+ std::make_tuple(std::string("Drain"), kAidlVersion1, "", 0, StreamTypeFilter::SYNC,
makeDrainOutCommands(true), false /*validatePositionIncrease*/);
static const NamedCommandSequence kDrainOutAsyncSeq =
- std::make_tuple(std::string("Drain"), kAidlVersion3, 0, StreamTypeFilter::ASYNC,
+ std::make_tuple(std::string("Drain"), kAidlVersion3, "", 0, StreamTypeFilter::ASYNC,
makeDrainOutCommands(false), false /*validatePositionIncrease*/);
std::shared_ptr<StateSequence> makeDrainEarlyOutCommands() {
@@ -4873,9 +4906,32 @@
return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kDrainEarlyOutAsyncSeq =
- std::make_tuple(std::string("DrainEarly"), kAidlVersion3, 0, StreamTypeFilter::ASYNC,
+ std::make_tuple(std::string("DrainEarly"), kAidlVersion3, "", 0, StreamTypeFilter::ASYNC,
makeDrainEarlyOutCommands(), false /*validatePositionIncrease*/);
+// DRAINING_en ->(onDrainReady) DRAINING_en_sent ->(onDrainReady) IDLE | TRANSFERRING
+std::shared_ptr<StateSequence> makeDrainEarlyOffloadCommands() {
+ using State = StreamDescriptor::State;
+ auto d = std::make_unique<StateDag>();
+ StateDag::Node lastIdle = d->makeFinalNode(State::IDLE);
+ StateDag::Node lastTransferring = d->makeFinalNode(State::TRANSFERRING);
+ // The second onDrainReady event.
+ StateDag::Node continueDraining =
+ d->makeNode(State::DRAINING, kDrainReadyEvent, lastIdle, lastTransferring);
+ // The first onDrainReady event.
+ StateDag::Node draining = d->makeNode(State::DRAINING, kDrainReadyEvent, continueDraining);
+ StateDag::Node drain = d->makeNode(State::ACTIVE, kDrainOutEarlyCommand, draining);
+ StateDag::Node active = makeAsyncBurstCommands(d.get(), 10, drain);
+ StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
+ idle.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, active));
+ d->makeNode(State::STANDBY, kStartCommand, idle);
+ return std::make_shared<StateSequenceFollower>(std::move(d));
+}
+static const NamedCommandSequence kDrainEarlyOffloadSeq =
+ std::make_tuple(std::string("DrainEarly"), kAidlVersion3, "aosp.clipTransitionSupport", 0,
+ StreamTypeFilter::OFFLOAD, makeDrainEarlyOffloadCommands(),
+ true /*validatePositionIncrease*/);
+
std::shared_ptr<StateSequence> makeDrainPauseOutCommands(bool isSync) {
using State = StreamDescriptor::State;
auto d = std::make_unique<StateDag>();
@@ -4896,11 +4952,11 @@
return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kDrainPauseOutSyncSeq =
- std::make_tuple(std::string("DrainPause"), kAidlVersion1,
+ std::make_tuple(std::string("DrainPause"), kAidlVersion1, "",
kStreamTransientStateTransitionDelayMs, StreamTypeFilter::SYNC,
makeDrainPauseOutCommands(true), false /*validatePositionIncrease*/);
static const NamedCommandSequence kDrainPauseOutAsyncSeq =
- std::make_tuple(std::string("DrainPause"), kAidlVersion1,
+ std::make_tuple(std::string("DrainPause"), kAidlVersion1, "",
kStreamTransientStateTransitionDelayMs, StreamTypeFilter::ASYNC,
makeDrainPauseOutCommands(false), false /*validatePositionIncrease*/);
@@ -4919,7 +4975,7 @@
return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kDrainEarlyPauseOutAsyncSeq =
- std::make_tuple(std::string("DrainEarlyPause"), kAidlVersion3,
+ std::make_tuple(std::string("DrainEarlyPause"), kAidlVersion3, "",
kStreamTransientStateTransitionDelayMs, StreamTypeFilter::ASYNC,
makeDrainEarlyPauseOutCommands(), false /*validatePositionIncrease*/);
@@ -4963,13 +5019,13 @@
return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kStandbyInSeq =
- std::make_tuple(std::string("Standby"), kAidlVersion1, 0, StreamTypeFilter::ANY,
+ std::make_tuple(std::string("Standby"), kAidlVersion1, "", 0, StreamTypeFilter::ANY,
makeStandbyCommands(true, false), false /*validatePositionIncrease*/);
static const NamedCommandSequence kStandbyOutSyncSeq =
- std::make_tuple(std::string("Standby"), kAidlVersion1, 0, StreamTypeFilter::SYNC,
+ std::make_tuple(std::string("Standby"), kAidlVersion1, "", 0, StreamTypeFilter::SYNC,
makeStandbyCommands(false, true), false /*validatePositionIncrease*/);
static const NamedCommandSequence kStandbyOutAsyncSeq =
- std::make_tuple(std::string("Standby"), kAidlVersion1,
+ std::make_tuple(std::string("Standby"), kAidlVersion1, "",
kStreamTransientStateTransitionDelayMs, StreamTypeFilter::ASYNC,
makeStandbyCommands(false, false), false /*validatePositionIncrease*/);
@@ -5006,15 +5062,15 @@
return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kPauseInSeq =
- std::make_tuple(std::string("Pause"), kAidlVersion1, 0, StreamTypeFilter::ANY,
+ std::make_tuple(std::string("Pause"), kAidlVersion1, "", 0, StreamTypeFilter::ANY,
makePauseCommands(true, false), false /*validatePositionIncrease*/);
static const NamedCommandSequence kPauseOutSyncSeq =
- std::make_tuple(std::string("Pause"), kAidlVersion1, 0, StreamTypeFilter::SYNC,
+ 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"), kAidlVersion3, kStreamTransientStateTransitionDelayMs,
- StreamTypeFilter::ASYNC, makePauseCommands(false, false),
- false /*validatePositionIncrease*/);
+ std::make_tuple(std::string("Pause"), kAidlVersion3, "",
+ kStreamTransientStateTransitionDelayMs, StreamTypeFilter::ASYNC,
+ makePauseCommands(false, false), false /*validatePositionIncrease*/);
std::shared_ptr<StateSequence> makeFlushCommands(bool isInput, bool isSync) {
using State = StreamDescriptor::State;
@@ -5042,15 +5098,15 @@
return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kFlushInSeq =
- std::make_tuple(std::string("Flush"), kAidlVersion1, 0, StreamTypeFilter::ANY,
+ std::make_tuple(std::string("Flush"), kAidlVersion1, "", 0, StreamTypeFilter::ANY,
makeFlushCommands(true, false), false /*validatePositionIncrease*/);
static const NamedCommandSequence kFlushOutSyncSeq =
- std::make_tuple(std::string("Flush"), kAidlVersion1, 0, StreamTypeFilter::SYNC,
+ std::make_tuple(std::string("Flush"), kAidlVersion1, "", 0, StreamTypeFilter::SYNC,
makeFlushCommands(false, true), false /*validatePositionIncrease*/);
static const NamedCommandSequence kFlushOutAsyncSeq =
- std::make_tuple(std::string("Flush"), kAidlVersion1, kStreamTransientStateTransitionDelayMs,
- StreamTypeFilter::ASYNC, makeFlushCommands(false, false),
- false /*validatePositionIncrease*/);
+ std::make_tuple(std::string("Flush"), kAidlVersion1, "",
+ kStreamTransientStateTransitionDelayMs, StreamTypeFilter::ASYNC,
+ makeFlushCommands(false, false), false /*validatePositionIncrease*/);
std::shared_ptr<StateSequence> makeDrainPauseFlushOutCommands(bool isSync) {
using State = StreamDescriptor::State;
@@ -5070,11 +5126,11 @@
return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kDrainPauseFlushOutSyncSeq =
- std::make_tuple(std::string("DrainPauseFlush"), kAidlVersion1,
+ std::make_tuple(std::string("DrainPauseFlush"), kAidlVersion1, "",
kStreamTransientStateTransitionDelayMs, StreamTypeFilter::SYNC,
makeDrainPauseFlushOutCommands(true), false /*validatePositionIncrease*/);
static const NamedCommandSequence kDrainPauseFlushOutAsyncSeq =
- std::make_tuple(std::string("DrainPauseFlush"), kAidlVersion1,
+ std::make_tuple(std::string("DrainPauseFlush"), kAidlVersion1, "",
kStreamTransientStateTransitionDelayMs, StreamTypeFilter::ASYNC,
makeDrainPauseFlushOutCommands(false), false /*validatePositionIncrease*/);
@@ -5087,6 +5143,8 @@
return "Sync";
case StreamTypeFilter::ASYNC:
return "Async";
+ case StreamTypeFilter::OFFLOAD:
+ return "Offload";
}
return std::string("Unknown").append(std::to_string(static_cast<int32_t>(filter)));
}
@@ -5119,7 +5177,8 @@
kDrainPauseOutAsyncSeq, kDrainEarlyPauseOutAsyncSeq,
kStandbyOutSyncSeq, kStandbyOutAsyncSeq, kPauseOutSyncSeq,
kPauseOutAsyncSeq, kFlushOutSyncSeq, kFlushOutAsyncSeq,
- kDrainPauseFlushOutSyncSeq, kDrainPauseFlushOutAsyncSeq),
+ kDrainPauseFlushOutSyncSeq, kDrainPauseFlushOutAsyncSeq,
+ kDrainEarlyOffloadSeq),
testing::Values(false, true)),
GetStreamIoTestName);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioStreamIoOut);
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 2bb0a72..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.
@@ -139,6 +141,8 @@
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;
@@ -548,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) {
@@ -585,10 +596,10 @@
}
DynamicsProcessing::EqBandConfig creatEqBandConfig(int channel, int band, float cutOffFreqHz,
- float gainDb) {
+ float gainDb, bool enable) {
return DynamicsProcessing::EqBandConfig{.channel = channel,
.band = band,
- .enable = true,
+ .enable = enable,
.cutoffFrequencyHz = cutOffFreqHz,
.gainDb = gainDb};
}
@@ -624,7 +635,7 @@
fillEngineArchConfig(mCfg, GetParam());
};
- void SetUp() override { SetUpDynamicsProcessingEffect(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -676,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(); }
@@ -715,7 +726,10 @@
mInput.resize(kFrameCount * mChannelCount);
}
- void SetUp() override { setUpDataTest({static_cast<int>(kInputFrequency)}, kSineFullScaleDb); }
+ void SetUp() override {
+ ASSERT_NO_FATAL_FAILURE(
+ setUpDataTest({static_cast<int>(kInputFrequency)}, kSineFullScaleDb));
+ }
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -793,7 +807,7 @@
fillLimiterConfig(mLimiterConfigList, GetParam());
}
- void SetUp() override { SetUpDynamicsProcessingEffect(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -843,7 +857,10 @@
mInput.resize(mBufferSize);
}
- void SetUp() override { setUpDataTest({static_cast<int>(kInputFrequency)}, kSineFullScaleDb); }
+ void SetUp() override {
+ ASSERT_NO_FATAL_FAILURE(
+ setUpDataTest({static_cast<int>(kInputFrequency)}, kSineFullScaleDb));
+ }
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -1011,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(); }
@@ -1075,7 +1092,8 @@
int bandCount = cutOffFreqs.size();
for (int i = 0; i < bandCount; i++) {
cfgs.push_back(creatEqBandConfig(std::get<EQ_BAND_CHANNEL>(params), cutOffFreqs[i].first,
- cutOffFreqs[i].second, std::get<EQ_BAND_GAIN>(params)));
+ cutOffFreqs[i].second, std::get<EQ_BAND_GAIN>(params),
+ true));
}
}
@@ -1087,7 +1105,7 @@
fillEqBandConfig(mCfgs, GetParam());
}
- void SetUp() override { SetUpDynamicsProcessingEffect(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -1223,15 +1241,16 @@
}
void fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig>& cfgs, int channelIndex,
- int bandIndex, int cutOffFreqHz, float gainDb) {
+ int bandIndex, int cutOffFreqHz, float gainDb, bool enable) {
cfgs.push_back(creatEqBandConfig(channelIndex, bandIndex, static_cast<float>(cutOffFreqHz),
- gainDb));
+ gainDb, enable));
}
- void validateOutput(const std::vector<float>& output, float gainDb, size_t bandIndex) {
+ 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) {
+ 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
@@ -1243,19 +1262,19 @@
}
}
- void analyseMultiBandOutput(float gainDb, bool isPreEq) {
+ 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);
- fillEqBandConfig(mCfgs, channelIndex, i ^ 1, kCutoffFreqHz[i ^ 1], 0);
+ 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));
+ ASSERT_NO_FATAL_FAILURE(validateOutput(output, gainDb, i, enable));
}
cleanUpEqConfig();
}
@@ -1291,6 +1310,16 @@
}
}
+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())),
@@ -1368,7 +1397,7 @@
fillMbcBandConfig(mCfgs, GetParam());
}
- void SetUp() override { SetUpDynamicsProcessingEffect(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -1541,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/VtsHalEqualizerTargetTest.cpp b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
index 0c931ff..86177fc 100644
--- a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
@@ -18,10 +18,10 @@
#include <string>
#include <vector>
+#define LOG_TAG "VtsHalEqualizerTest"
#include <aidl/Gtest.h>
#include <aidl/android/hardware/audio/effect/IEffect.h>
#include <aidl/android/hardware/audio/effect/IFactory.h>
-#define LOG_TAG "VtsHalEqualizerTest"
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android/binder_interface_utils.h>
@@ -48,8 +48,8 @@
*/
enum ParamName { PARAM_INSTANCE_NAME, PARAM_PRESET, PARAM_BAND_LEVEL };
-using EqualizerParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int,
- std::vector<Equalizer::BandLevel>>;
+using EqualizerTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int,
+ std::vector<Equalizer::BandLevel>>;
/*
Testing parameter range, assuming the parameter supported by effect is in this range.
@@ -58,38 +58,34 @@
*/
const std::vector<int> kBandLevels = {0, -10, 10}; // needs update with implementation
-class EqualizerTest : public ::testing::TestWithParam<EqualizerParamTestParam>,
- public EffectHelper {
+class EqualizerTestHelper : public EffectHelper {
public:
- EqualizerTest()
- : mPresetIndex(std::get<PARAM_PRESET>(GetParam())),
- mBandLevel(std::get<PARAM_BAND_LEVEL>(GetParam())) {
- std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+ EqualizerTestHelper(std::pair<std::shared_ptr<IFactory>, Descriptor> descPair,
+ int presetIndex = 0,
+ std::vector<Equalizer::BandLevel> bandLevel =
+ std::vector<Equalizer::BandLevel>{
+ Equalizer::BandLevel({.index = 0, .levelMb = 0})})
+ : mFactory(descPair.first), mPresetIndex(presetIndex), mBandLevel(bandLevel) {
+ mDescriptor = descPair.second;
}
- void SetUp() override {
+ void SetUpEqualizer() {
ASSERT_NE(nullptr, mFactory);
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
Parameter::Common common = createParamCommon(
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
- IEffect::OpenEffectReturn ret;
- ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &mOpenEffectReturn, EX_NONE));
ASSERT_NE(nullptr, mEffect);
}
- void TearDown() override {
+
+ void TearDownEqualizer() {
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+ mOpenEffectReturn = IEffect::OpenEffectReturn{};
}
- static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
- std::shared_ptr<IFactory> mFactory;
- std::shared_ptr<IEffect> mEffect;
- Descriptor mDescriptor;
- int mPresetIndex;
- std::vector<Equalizer::BandLevel> mBandLevel;
-
void SetAndGetEqualizerParameters() {
ASSERT_NE(nullptr, mEffect);
for (auto& it : mTags) {
@@ -167,26 +163,45 @@
mTags.push_back({Equalizer::preset, Equalizer::make<Equalizer::preset>(preset)});
}
- void addBandLevelsParam(std::vector<Equalizer::BandLevel>& bandLevels) {
+ void addBandLevelsParam(const std::vector<Equalizer::BandLevel>& bandLevels) {
mTags.push_back(
{Equalizer::bandLevels, Equalizer::make<Equalizer::bandLevels>(bandLevels)});
}
+ static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+ const std::shared_ptr<IFactory> mFactory;
+ const int mPresetIndex;
+ const std::vector<Equalizer::BandLevel> mBandLevel;
+ std::shared_ptr<IEffect> mEffect;
+ IEffect::OpenEffectReturn mOpenEffectReturn;
+
private:
std::vector<std::pair<Equalizer::Tag, Equalizer>> mTags;
-
void CleanUp() { mTags.clear(); }
};
-TEST_P(EqualizerTest, SetAndGetParams) {
+class EqualizerParamTest : public ::testing::TestWithParam<EqualizerTestParam>,
+ public EqualizerTestHelper {
+ public:
+ EqualizerParamTest()
+ : EqualizerTestHelper(std::get<PARAM_INSTANCE_NAME>(GetParam()),
+ std::get<PARAM_PRESET>(GetParam()),
+ std::get<PARAM_BAND_LEVEL>(GetParam())) {}
+
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpEqualizer()); }
+
+ void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownEqualizer()); }
+};
+
+TEST_P(EqualizerParamTest, SetAndGetParams) {
addBandLevelsParam(mBandLevel);
addPresetParam(mPresetIndex);
- EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+ ASSERT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
}
std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
INSTANTIATE_TEST_SUITE_P(
- EqualizerTest, EqualizerTest,
+ EqualizerParamTest, EqualizerParamTest,
::testing::Combine(
testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, getEffectTypeUuidEqualizer())),
@@ -200,7 +215,7 @@
[](std::set<std::vector<Equalizer::BandLevel>>& bandLevels) {
return bandLevels;
}))),
- [](const testing::TestParamInfo<EqualizerTest::ParamType>& info) {
+ [](const testing::TestParamInfo<EqualizerParamTest::ParamType>& info) {
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
std::string bandLevel =
::android::internal::ToString(std::get<PARAM_BAND_LEVEL>(info.param));
@@ -211,7 +226,7 @@
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
return name;
});
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EqualizerTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EqualizerParamTest);
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index 255d2f0..a263bff 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -135,7 +135,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;
};
@@ -166,7 +166,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);
@@ -261,13 +261,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/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index 9ca4366..cb1b94b 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -40,7 +40,8 @@
* Note that this property only represents the minimum value at boot time
* and may not represent the current actual minimum value.
*
- * Only applicable for {@code INT32} type property. Ignored for other types.
+ * Only applicable for {@code INT32} type property. For other types, must be
+ * 0.
*
* For certain properties, this field must be specified, see
* {@code VehicleProperty} documentation.
@@ -60,10 +61,13 @@
* boot time, both {@code minInt32Value} and {@code maxInt32Value} must be
* set to 0.
*
- * Note that this property only represents the minimum value at boot time
- * and may not represent the current actual minimum value.
+ * Note that this property only represents the maximum value at boot time
+ * and may not represent the current actual maximum value.
*
- * Only applicable for {@code INT32} type property. Ignored for other types.
+ * Only applicable for {@code INT32} type property. For other types, must be
+ * 0.
+ *
+ * Must be larger or equal to {@code minInt32Value}.
*
* For certain properties, this field must be specified, see
* {@code VehicleProperty} documentation.
@@ -86,7 +90,8 @@
* Note that this property only represents the minimum value at boot time
* and may not represent the current actual minimum value.
*
- * Only applicable for {@code INT64} type property. Ignored for other types.
+ * Only applicable for {@code INT64} type property. For other types, must be
+ * 0.
*
* For certain properties, this field must be specified, see
* {@code VehicleProperty} documentation.
@@ -106,10 +111,13 @@
* boot time, both {@code minInt64Value} and {@code maxInt64Value} must be
* set to 0.
*
- * Note that this property only represents the minimum value at boot time
- * and may not represent the current actual minimum value.
+ * Note that this property only represents the maximum value at boot time
+ * and may not represent the current actual maximum value.
*
- * Only applicable for {@code INT64} type property. Ignored for other types.
+ * Only applicable for {@code INT64} type property. For other types, must be
+ * 0.
+ *
+ * Must be larger or equal to {@code minInt64Value}.
*
* For certain properties, this field must be specified, see
* {@code VehicleProperty} documentation.
@@ -132,7 +140,8 @@
* Note that this property only represents the minimum value at boot time
* and may not represent the current actual minimum value.
*
- * Only applicable for {@code FLOAT} type property. Ignored for other types.
+ * Only applicable for {@code FLOAT} type property. For other types, must be
+ * 0.
*
* For certain properties, this field must be specified, see
* {@code VehicleProperty} documentation.
@@ -152,10 +161,13 @@
* boot time, both {@code minFloatValue} and {@code maxFloatValue} must be
* set to 0.
*
- * Note that this property only represents the minimum value at boot time
- * and may not represent the current actual minimum value.
+ * Note that this property only represents the maximum value at boot time
+ * and may not represent the current actual maximum value.
*
- * Only applicable for {@code FLOAT} type property. Ignored for other types.
+ * Only applicable for {@code FLOAT} type property. For other types, must be
+ * 0.
+ *
+ * Must be larger or equal to {@code minFloatValue}.
*
* For certain properties, this field must be specified, see
* {@code VehicleProperty} documentation.
diff --git a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
index 92681de..e7c03ad 100644
--- a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
+++ b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
@@ -1215,7 +1215,7 @@
{
"name": "REMOVE_USER",
"value": 299896586,
- "description": "Called by the Android System after an Android user was removed.\nThe HAL can use this property to remove its equivalent user.\nThis is write-only call - the Android System is not expecting a reply from the HAL. Hence, this request should not fail - if the equivalent HAL user cannot be removed, then HAL should mark it as inactive or recover in some other way.\nThe request is made by setting the VehiclePropValue with the contents defined by RemoveUserRequest.\nFor example, if system had 3 users (0, 10, and 11) and user 11 was removed, the request would be:\nint32[0]: 42 \/\/ request id int32[1]: 11 \/\/ (Android user id of the removed user) int32[2]: 0 \/\/ (Android user flags of the removed user) int32[3]: 10 \/\/ current user int32[4]: 0 \/\/ current user flags (none) int32[5]: 2 \/\/ number of users int32[6]: 0 \/\/ 1st user (user 0) int32[7]: 0 \/\/ 1st user flags (none) int32[8]: 10 \/\/ 2nd user (user 10) int32[9]: 0 \/\/ 2nd user flags (none)"
+ "description": "Called by the Android System after an Android user was removed.\nThe HAL can use this property to remove its equivalent user.\nThis is write-only call - the Android System is not expecting a reply from the HAL. Hence, this request should not fail - if the equivalent HAL user cannot be removed, then HAL should mark it as inactive or recover in some other way.\nThe request is made by setting the VehiclePropValue with the contents defined by RemoveUserRequest.\nFor example, if system had 3 users (0, 10, and 11) and user 11 was removed, the request would be:\nint32[0]: 42 \/\/ request id int32[1]: 11 \/\/ (Android user id of the removed user) int32[2]: 0 \/\/ (Android user flags of the removed user) int32[3]: 10 \/\/ current user int32[4]: 0 \/\/ current user flags (none) int32[5]: 2 \/\/ number of users int32[6]: 0 \/\/ 1st user (user 0) int32[7]: 0 \/\/ 1st user flags (none) int32[8]: 10 \/\/ 2nd user (user 10) int32[9]: 0 \/\/ 2nd user flags (none)\nBefore Android B, this property's change mode was defined as STATIC although the property value may be updated from Android side. For backward compatibility, we still allow STATIC as change mode, but for new implementations, ON_CHANGE should be used instead."
},
{
"name": "USER_IDENTIFICATION_ASSOCIATION",
diff --git a/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h
index ca07ecf..685b010 100644
--- a/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h
@@ -235,7 +235,7 @@
{VehicleProperty::INITIAL_USER_INFO, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SWITCH_USER, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::CREATE_USER, VehiclePropertyChangeMode::ON_CHANGE},
- {VehicleProperty::REMOVE_USER, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::REMOVE_USER, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::EVS_SERVICE_REQUEST, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::POWER_POLICY_REQ, VehiclePropertyChangeMode::ON_CHANGE},
diff --git a/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java
index cf44887..39a9c42 100644
--- a/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java
@@ -233,7 +233,7 @@
Map.entry(VehicleProperty.INITIAL_USER_INFO, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SWITCH_USER, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.CREATE_USER, VehiclePropertyChangeMode.ON_CHANGE),
- Map.entry(VehicleProperty.REMOVE_USER, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.REMOVE_USER, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.EVS_SERVICE_REQUEST, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.POWER_POLICY_REQ, VehiclePropertyChangeMode.ON_CHANGE),
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
index 2f1b277..cf9ea10 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -5716,7 +5716,11 @@
* int32[8]: 10 // 2nd user (user 10)
* int32[9]: 0 // 2nd user flags (none)
*
- * @change_mode VehiclePropertyChangeMode.STATIC
+ * Before Android B, this property's change mode was defined as STATIC although the property
+ * value may be updated from Android side. For backward compatibility, we still allow STATIC
+ * as change mode, but for new implementations, ON_CHANGE should be used instead.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
* @access VehiclePropertyAccess.WRITE
* @version 2
*/
diff --git a/automotive/vehicle/tools/generate_annotation_enums.py b/automotive/vehicle/tools/generate_annotation_enums.py
index 44a810e..592cadd 100755
--- a/automotive/vehicle/tools/generate_annotation_enums.py
+++ b/automotive/vehicle/tools/generate_annotation_enums.py
@@ -51,17 +51,17 @@
SCRIPT_PATH = 'hardware/interfaces/automotive/vehicle/tools/generate_annotation_enums.py'
TAB = ' '
-RE_ENUM_START = re.compile('\s*enum VehicleProperty \{')
-RE_ENUM_END = re.compile('\s*\}\;')
-RE_COMMENT_BEGIN = re.compile('\s*\/\*\*?')
-RE_COMMENT_END = re.compile('\s*\*\/')
-RE_CHANGE_MODE = re.compile('\s*\* @change_mode (\S+)\s*')
-RE_VERSION = re.compile('\s*\* @version (\S+)\s*')
-RE_ACCESS = re.compile('\s*\* @access (\S+)\s*')
-RE_DATA_ENUM = re.compile('\s*\* @data_enum (\S+)\s*')
-RE_UNIT = re.compile('\s*\* @unit (\S+)\s+')
-RE_VALUE = re.compile('\s*(\w+)\s*=(.*)')
-RE_ANNOTATION = re.compile('\s*\* @(\S+)\s*')
+RE_ENUM_START = re.compile(r'\s*enum VehicleProperty \{')
+RE_ENUM_END = re.compile(r'\s*\}\;')
+RE_COMMENT_BEGIN = re.compile(r'\s*\/\*\*?')
+RE_COMMENT_END = re.compile(r'\s*\*\/')
+RE_CHANGE_MODE = re.compile(r'\s*\* @change_mode (\S+)\s*')
+RE_VERSION = re.compile(r'\s*\* @version (\S+)\s*')
+RE_ACCESS = re.compile(r'\s*\* @access (\S+)\s*')
+RE_DATA_ENUM = re.compile(r'\s*\* @data_enum (\S+)\s*')
+RE_UNIT = re.compile(r'\s*\* @unit (\S+)\s+')
+RE_VALUE = re.compile(r'\s*(\w+)\s*=(.*)')
+RE_ANNOTATION = re.compile(r'\s*\* @(\S+)\s*')
SUPPORTED_ANNOTATIONS = ['change_mode', 'access', 'unit', 'data_enum', 'data_enum_bit_flags',
'version', 'require_min_max_supported_value', 'require_supported_values_list',
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index 7f5e06d..f249cf6 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -1248,9 +1248,21 @@
}
}
- EXPECT_EQ(actualChangeMode, expectedChangeMode)
- << StringPrintf("Expect to get VehiclePropertyChangeMode: %i, got %i",
- expectedChangeMode, actualChangeMode);
+ if (actualPropId != toInt(VehicleProperty::REMOVE_USER)) {
+ EXPECT_EQ(actualChangeMode, expectedChangeMode)
+ << StringPrintf("Expect to get VehiclePropertyChangeMode: %i, got %i",
+ expectedChangeMode, actualChangeMode);
+ } else {
+ // Special logic for REMOVE_USER property. We allow both STATIC and ON_CHANGE change mode
+ // because historically we define the change mode to be STATIC which is incorrect, it should
+ // be on_change. For backward compatibility, we have to allow both.
+ EXPECT_THAT(actualChangeMode, ::testing::AnyOf(toInt(VehiclePropertyChangeMode::STATIC),
+ toInt(VehiclePropertyChangeMode::ON_CHANGE)))
+ << StringPrintf(
+ "Expect to get VehiclePropertyChangeMode as one of: "
+ "[STATIC, ON_CHANGE], got %i",
+ actualChangeMode);
+ }
std::unordered_set<std::string> annotations;
auto it = AnnotationsForVehicleProperty.find(param.propId);
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 4f2ed2f..7810213 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -58,12 +58,6 @@
for (const auto& display : mAllDisplays) {
// explicitly disable vsync
EXPECT_TRUE(mComposerClient->setVsync(display.getDisplayId(), /*enable*/ false).isOk());
-
- DisplayProperties& displayProperties = mDisplayProperties.at(display.getDisplayId());
- if (ReadbackHelper::readbackSupported(displayProperties.pixelFormat,
- displayProperties.dataspace)) {
- mDisplaysWithReadbackBuffers.push_back(&display);
- }
}
mComposerClient->setVsyncAllowed(/*isAllowed*/ false);
@@ -150,12 +144,35 @@
DisplayProperties displayProperties(displayId, testColorModes,
std::move(testRenderEngine),
std::move(clientCompositionDisplaySettings),
- std::move(readBackBufferAttributes));
+ std::move(readBackBufferAttributes.format));
mDisplayProperties.emplace(displayId, std::move(displayProperties));
}
}
+ // Get the dataspace and check if readback is supported given the default pixel format and the
+ // current dataspace. Dataspace can get updated after calls to
+ // ComposerClientWrapper::setColorMode so it's essential to get the latest dataspace.
+ std::pair<common::Dataspace, bool> GetDataspaceAndIfReadBackSupported(int64_t displayId) {
+ auto [status, readBackBufferAttributes] =
+ mComposerClient->getReadbackBufferAttributes(displayId);
+ if (status.isOk()) {
+ auto dataspace = readBackBufferAttributes.dataspace;
+
+ // We are making an assumption that Pixel Format never changes, so assert for this
+ // assumption. If this is not the case on any display, then we should stop caching it.
+ // The cached format is used in initializing TestRenderEngine.
+ assertPixelFormatConsistency(displayId, readBackBufferAttributes.format);
+
+ return std::make_pair(std::move(dataspace),
+ ReadbackHelper::readbackSupported(
+ mDisplayProperties.at(displayId).pixelFormat, dataspace));
+ }
+ EXPECT_NO_FATAL_FAILURE(
+ assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
+ return {common::Dataspace::UNKNOWN, false};
+ }
+
int64_t getInvalidDisplayId() const { return mComposerClient->getInvalidDisplayId(); }
void assertServiceSpecificError(const ScopedAStatus& status, int32_t serviceSpecificError) {
@@ -163,6 +180,10 @@
ASSERT_EQ(status.getServiceSpecificError(), serviceSpecificError);
}
+ void assertPixelFormatConsistency(int64_t displayId, common::PixelFormat currentPixelFormat) {
+ ASSERT_EQ(mDisplayProperties.at(displayId).pixelFormat, currentPixelFormat);
+ }
+
std::pair<bool, ::android::sp<::android::GraphicBuffer>> allocateBuffer(
const DisplayWrapper& display, uint32_t usage) {
const auto width = static_cast<uint32_t>(display.getDisplayWidth());
@@ -201,10 +222,9 @@
DisplayProperties(int64_t displayId, std::vector<ColorMode> testColorModes,
std::unique_ptr<TestRenderEngine> testRenderEngine,
::android::renderengine::DisplaySettings clientCompositionDisplaySettings,
- ReadbackBufferAttributes readBackBufferAttributes)
+ common::PixelFormat pixelFormat)
: testColorModes(testColorModes),
- pixelFormat(readBackBufferAttributes.format),
- dataspace(readBackBufferAttributes.dataspace),
+ pixelFormat(pixelFormat),
testRenderEngine(std::move(testRenderEngine)),
clientCompositionDisplaySettings(std::move(clientCompositionDisplaySettings)),
writer(displayId),
@@ -212,7 +232,6 @@
std::vector<ColorMode> testColorModes = {};
common::PixelFormat pixelFormat = common::PixelFormat::UNSPECIFIED;
- common::Dataspace dataspace = common::Dataspace::UNKNOWN;
std::unique_ptr<TestRenderEngine> testRenderEngine = nullptr;
::android::renderengine::DisplaySettings clientCompositionDisplaySettings = {};
ComposerClientWriter writer;
@@ -221,7 +240,6 @@
std::shared_ptr<ComposerClientWrapper> mComposerClient;
std::vector<DisplayWrapper> mAllDisplays;
- std::vector<const DisplayWrapper*> mDisplaysWithReadbackBuffers;
std::unordered_map<int64_t, DisplayProperties> mDisplayProperties;
static constexpr uint32_t kClientTargetSlotCount = 64;
@@ -234,19 +252,25 @@
};
TEST_P(GraphicsCompositionTest, SingleSolidColorLayer) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- auto& testColorModes = mDisplayProperties.at(display->getDisplayId()).testColorModes;
+ for (const DisplayWrapper display : mAllDisplays) {
+ auto& testColorModes = mDisplayProperties.at(display.getDisplayId()).testColorModes;
for (ColorMode mode : testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
+
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
auto layer = std::make_shared<TestColorLayer>(
- mComposerClient, display->getDisplayId(),
- mDisplayProperties.at(display->getDisplayId()).writer);
+ mComposerClient, display.getDisplayId(),
+ mDisplayProperties.at(display.getDisplayId()).writer);
common::Rect coloredSquare(
- {0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+ {0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
layer->setColor(BLUE);
layer->setDisplayFrame(coloredSquare);
layer->setZOrder(10);
@@ -255,40 +279,38 @@
// expected color for each pixel
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
- coloredSquare, BLUE);
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), coloredSquare,
+ BLUE);
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
+ execute(display.getDisplayId());
// if hwc cannot handle and asks for composition change, just skip the test on this
// display->
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
- auto& testRenderEngine =
- mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+ auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
testRenderEngine->setRenderLayers(layers);
ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -297,71 +319,74 @@
}
TEST_P(GraphicsCompositionTest, SetLayerBuffer) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- auto& testColorModes = mDisplayProperties.at(display->getDisplayId()).testColorModes;
+ for (const DisplayWrapper display : mAllDisplays) {
+ auto& testColorModes = mDisplayProperties.at(display.getDisplayId()).testColorModes;
for (ColorMode mode : testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
+
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
ReadbackHelper::fillColorsArea(
- expectedColors, display->getDisplayWidth(),
- {0, 0, display->getDisplayWidth(), display->getDisplayHeight() / 4}, RED);
+ expectedColors, display.getDisplayWidth(),
+ {0, 0, display.getDisplayWidth(), display.getDisplayHeight() / 4}, RED);
ReadbackHelper::fillColorsArea(
- expectedColors, display->getDisplayWidth(),
- {0, display->getDisplayHeight() / 4, display->getDisplayWidth(),
- display->getDisplayHeight() / 2},
+ expectedColors, display.getDisplayWidth(),
+ {0, display.getDisplayHeight() / 4, display.getDisplayWidth(),
+ display.getDisplayHeight() / 2},
GREEN);
- ReadbackHelper::fillColorsArea(
- expectedColors, display->getDisplayWidth(),
- {0, display->getDisplayHeight() / 2, display->getDisplayWidth(),
- display->getDisplayHeight()},
- BLUE);
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
+ {0, display.getDisplayHeight() / 2,
+ display.getDisplayWidth(), display.getDisplayHeight()},
+ BLUE);
auto layer = std::make_shared<TestBufferLayer>(
mComposerClient,
- *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
- display->getDisplayId(), display->getDisplayWidth(),
- display->getDisplayHeight(), common::PixelFormat::RGBA_8888,
- mDisplayProperties.at(display->getDisplayId()).writer);
- layer->setDisplayFrame({0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+ *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+ display.getDisplayId(), display.getDisplayWidth(), display.getDisplayHeight(),
+ common::PixelFormat::RGBA_8888,
+ mDisplayProperties.at(display.getDisplayId()).writer);
+ layer->setDisplayFrame({0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
layer->setZOrder(10);
layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
+ execute(display.getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
- auto& testRenderEngine =
- mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+ auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
testRenderEngine->setRenderLayers(layers);
ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -370,64 +395,69 @@
}
TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- auto& testColorModes = mDisplayProperties.at(display->getDisplayId()).testColorModes;
+ for (const DisplayWrapper display : mAllDisplays) {
+ auto& testColorModes = mDisplayProperties.at(display.getDisplayId()).testColorModes;
for (ColorMode mode : testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
- auto& writer = mDisplayProperties.at(display->getDisplayId()).writer;
- auto layer = std::make_shared<TestColorLayer>(mComposerClient, display->getDisplayId(),
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
+
+ auto& writer = mDisplayProperties.at(display.getDisplayId()).writer;
+ auto layer = std::make_shared<TestColorLayer>(mComposerClient, display.getDisplayId(),
writer);
common::Rect coloredSquare(
- {0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+ {0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
layer->setColor(BLUE);
layer->setDisplayFrame(coloredSquare);
layer->setZOrder(10);
- layer->write(mDisplayProperties.at(display->getDisplayId()).writer);
+ layer->write(mDisplayProperties.at(display.getDisplayId()).writer);
// This following buffer call should have no effect
const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
- const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(*display, usage);
+ const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(display, usage);
ASSERT_TRUE(graphicBufferStatus);
const auto& buffer = graphicBuffer->handle;
- mDisplayProperties.at(display->getDisplayId())
- .writer.setLayerBuffer(display->getDisplayId(), layer->getLayer(), /*slot*/ 0,
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.setLayerBuffer(display.getDisplayId(), layer->getLayer(), /*slot*/ 0,
buffer,
/*acquireFence*/ -1);
// expected color for each pixel
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
- coloredSquare, BLUE);
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), coloredSquare,
+ BLUE);
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
+ execute(display.getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
@@ -435,20 +465,31 @@
}
TEST_P(GraphicsCompositionTest, SetReadbackBuffer) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- ReadbackBuffer readbackBuffer(display->getDisplayId(), mComposerClient,
- display->getDisplayWidth(), display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ for (const DisplayWrapper display : mAllDisplays) {
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
+
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
}
}
TEST_P(GraphicsCompositionTest, SetReadbackBuffer_BadDisplay) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+ for (const DisplayWrapper display : mAllDisplays) {
+ auto [_, readbackSupported] = GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
+
const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
- const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(*display, usage);
+ const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(display, usage);
ASSERT_TRUE(graphicBufferStatus);
const auto& bufferHandle = graphicBuffer->handle;
::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
@@ -463,10 +504,15 @@
}
TEST_P(GraphicsCompositionTest, SetReadbackBuffer_BadParameter) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+ for (const DisplayWrapper display : mAllDisplays) {
+ auto [_, readbackSupported] = GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
+
const native_handle_t bufferHandle{};
ndk::ScopedFileDescriptor releaseFence = ndk::ScopedFileDescriptor(-1);
- const auto status = mComposerClient->setReadbackBuffer(display->getDisplayId(),
+ const auto status = mComposerClient->setReadbackBuffer(display.getDisplayId(),
&bufferHandle, releaseFence);
EXPECT_FALSE(status.isOk());
@@ -476,9 +522,13 @@
}
TEST_P(GraphicsCompositionTest, GetReadbackBufferFenceInactive) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+ for (const DisplayWrapper display : mAllDisplays) {
+ auto [_, readbackSupported] = GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
const auto& [status, releaseFence] =
- mComposerClient->getReadbackBufferFence(display->getDisplayId());
+ mComposerClient->getReadbackBufferFence(display.getDisplayId());
EXPECT_FALSE(status.isOk());
EXPECT_NO_FATAL_FAILURE(
@@ -488,64 +538,67 @@
}
TEST_P(GraphicsCompositionTest, ClientComposition) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+ for (const DisplayWrapper display : mAllDisplays) {
EXPECT_TRUE(
mComposerClient
- ->setClientTargetSlotCount(display->getDisplayId(), kClientTargetSlotCount)
+ ->setClientTargetSlotCount(display.getDisplayId(), kClientTargetSlotCount)
.isOk());
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
+
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
ReadbackHelper::fillColorsArea(
- expectedColors, display->getDisplayWidth(),
- {0, 0, display->getDisplayWidth(), display->getDisplayHeight() / 4}, RED);
+ expectedColors, display.getDisplayWidth(),
+ {0, 0, display.getDisplayWidth(), display.getDisplayHeight() / 4}, RED);
ReadbackHelper::fillColorsArea(
- expectedColors, display->getDisplayWidth(),
- {0, display->getDisplayHeight() / 4, display->getDisplayWidth(),
- display->getDisplayHeight() / 2},
+ expectedColors, display.getDisplayWidth(),
+ {0, display.getDisplayHeight() / 4, display.getDisplayWidth(),
+ display.getDisplayHeight() / 2},
GREEN);
- ReadbackHelper::fillColorsArea(
- expectedColors, display->getDisplayWidth(),
- {0, display->getDisplayHeight() / 2, display->getDisplayWidth(),
- display->getDisplayHeight()},
- BLUE);
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
+ {0, display.getDisplayHeight() / 2,
+ display.getDisplayWidth(), display.getDisplayHeight()},
+ BLUE);
auto layer = std::make_shared<TestBufferLayer>(
mComposerClient,
- *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
- display->getDisplayId(), display->getDisplayWidth(),
- display->getDisplayHeight(), PixelFormat::RGBA_8888,
- mDisplayProperties.at(display->getDisplayId()).writer);
- layer->setDisplayFrame({0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+ *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+ display.getDisplayId(), display.getDisplayWidth(), display.getDisplayHeight(),
+ PixelFormat::RGBA_8888, mDisplayProperties.at(display.getDisplayId()).writer);
+ layer->setDisplayFrame({0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
layer->setZOrder(10);
layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
+ execute(display.getDisplayId());
auto changedCompositionTypes =
- mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId());
+ mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId());
if (!changedCompositionTypes.empty()) {
ASSERT_EQ(1, changedCompositionTypes.size());
ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0].composition);
@@ -556,11 +609,11 @@
static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
- common::Rect damage{0, 0, display->getDisplayWidth(), display->getDisplayHeight()};
+ common::Rect damage{0, 0, display.getDisplayWidth(), display.getDisplayHeight()};
// create client target buffer
const auto& [graphicBufferStatus, graphicBuffer] =
- allocateBuffer(*display, clientUsage);
+ allocateBuffer(display, clientUsage);
ASSERT_TRUE(graphicBufferStatus);
const auto& buffer = graphicBuffer->handle;
void* clientBufData;
@@ -576,29 +629,28 @@
int32_t clientFence;
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
ASSERT_EQ(::android::OK, unlockStatus);
- mDisplayProperties.at(display->getDisplayId())
- .writer.setClientTarget(display->getDisplayId(), /*slot*/ 0, buffer,
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.setClientTarget(display.getDisplayId(), /*slot*/ 0, buffer,
clientFence, clientDataspace,
std::vector<common::Rect>(1, damage), 1.f);
- layer->setToClientComposition(
- mDisplayProperties.at(display->getDisplayId()).writer);
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ layer->setToClientComposition(mDisplayProperties.at(display.getDisplayId()).writer);
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
+ execute(display.getDisplayId());
changedCompositionTypes =
- mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId());
+ mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId());
ASSERT_TRUE(changedCompositionTypes.empty());
}
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
@@ -634,12 +686,12 @@
GTEST_SKIP();
}
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+ for (const DisplayWrapper display : mAllDisplays) {
ASSERT_TRUE(
mComposerClient
- ->setClientTargetSlotCount(display->getDisplayId(), kClientTargetSlotCount)
+ ->setClientTargetSlotCount(display.getDisplayId(), kClientTargetSlotCount)
.isOk());
- auto& testColorModes = mDisplayProperties.at(display->getDisplayId()).testColorModes;
+ auto& testColorModes = mDisplayProperties.at(display.getDisplayId()).testColorModes;
for (const auto& lutProperties : *properties.lutProperties) {
if (!lutProperties) {
@@ -650,25 +702,31 @@
for (const auto& key : l.samplingKeys) {
for (ColorMode mode : testColorModes) {
EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
+ ->setColorMode(display.getDisplayId(), mode,
RenderIntent::COLORIMETRIC)
.isOk());
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
+
common::Rect coloredSquare(
- {0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+ {0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
// expected color for each pixel
std::vector<Color> expectedColors(static_cast<size_t>(
- display->getDisplayWidth() * display->getDisplayHeight()));
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+ display.getDisplayWidth() * display.getDisplayHeight()));
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
coloredSquare, WHITE);
auto layer = std::make_shared<TestBufferLayer>(
mComposerClient,
- *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
- display->getDisplayId(), display->getDisplayWidth(),
- display->getDisplayHeight(), PixelFormat::RGBA_8888,
- mDisplayProperties.at(display->getDisplayId()).writer);
+ *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+ display.getDisplayId(), display.getDisplayWidth(),
+ display.getDisplayHeight(), PixelFormat::RGBA_8888,
+ mDisplayProperties.at(display.getDisplayId()).writer);
layer->setDisplayFrame(coloredSquare);
layer->setZOrder(10);
layer->setDataspace(Dataspace::SRGB);
@@ -682,46 +740,45 @@
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ display.getDisplayId(), mComposerClient, display.getDisplayWidth(),
+ display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat, dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId())
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId())
.reader.takeErrors()
.empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
auto changedCompositionTypes =
- mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId());
+ mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId());
ASSERT_TRUE(changedCompositionTypes.empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId())
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId())
.reader.takeErrors()
.empty());
ReadbackHelper::fillColorsArea(
- expectedColors, display->getDisplayWidth(), coloredSquare,
+ expectedColors, display.getDisplayWidth(), coloredSquare,
{188.f / 255.f, 188.f / 255.f, 188.f / 255.f, 1.0f});
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
auto& testRenderEngine =
- mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+ mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
testRenderEngine->setRenderLayers(layers);
ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -744,27 +801,33 @@
GTEST_SKIP();
}
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+ for (const DisplayWrapper display : mAllDisplays) {
ASSERT_TRUE(
mComposerClient
- ->setClientTargetSlotCount(display->getDisplayId(), kClientTargetSlotCount)
+ ->setClientTargetSlotCount(display.getDisplayId(), kClientTargetSlotCount)
.isOk());
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
+
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
// sRGB layer
auto srgbLayer = std::make_shared<TestBufferLayer>(
mComposerClient,
- *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
- display->getDisplayId(), display->getDisplayWidth(),
- display->getDisplayHeight() / 2, PixelFormat::RGBA_8888,
- mDisplayProperties.at(display->getDisplayId()).writer);
+ *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+ display.getDisplayId(), display.getDisplayWidth(),
+ display.getDisplayHeight() / 2, PixelFormat::RGBA_8888,
+ mDisplayProperties.at(display.getDisplayId()).writer);
std::vector<Color> sRgbDeviceColors(srgbLayer->getWidth() * srgbLayer->getHeight());
- ReadbackHelper::fillColorsArea(sRgbDeviceColors, display->getDisplayWidth(),
+ ReadbackHelper::fillColorsArea(sRgbDeviceColors, display.getDisplayWidth(),
{0, 0, static_cast<int32_t>(srgbLayer->getWidth()),
static_cast<int32_t>(srgbLayer->getHeight())},
GREEN);
@@ -777,86 +840,90 @@
// display P3 layer
auto displayP3Layer = std::make_shared<TestBufferLayer>(
mComposerClient,
- *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
- display->getDisplayId(), display->getDisplayWidth(),
- display->getDisplayHeight() / 2, PixelFormat::RGBA_8888,
- mDisplayProperties.at(display->getDisplayId()).writer);
+ *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+ display.getDisplayId(), display.getDisplayWidth(),
+ display.getDisplayHeight() / 2, PixelFormat::RGBA_8888,
+ mDisplayProperties.at(display.getDisplayId()).writer);
std::vector<Color> displayP3DeviceColors(
static_cast<size_t>(displayP3Layer->getWidth() * displayP3Layer->getHeight()));
- ReadbackHelper::fillColorsArea(displayP3DeviceColors, display->getDisplayWidth(),
+ ReadbackHelper::fillColorsArea(displayP3DeviceColors, display.getDisplayWidth(),
{0, 0, static_cast<int32_t>(displayP3Layer->getWidth()),
static_cast<int32_t>(displayP3Layer->getHeight())},
RED);
- displayP3Layer->setDisplayFrame({0, display->getDisplayHeight() / 2,
- display->getDisplayWidth(),
- display->getDisplayHeight()});
+ displayP3Layer->setDisplayFrame({0, display.getDisplayHeight() / 2,
+ display.getDisplayWidth(),
+ display.getDisplayHeight()});
displayP3Layer->setZOrder(10);
displayP3Layer->setDataspace(Dataspace::DISPLAY_P3);
ASSERT_NO_FATAL_FAILURE(displayP3Layer->setBuffer(displayP3DeviceColors));
- writeLayers({srgbLayer, displayP3Layer}, display->getDisplayId());
+ writeLayers({srgbLayer, displayP3Layer}, display.getDisplayId());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
+ execute(display.getDisplayId());
auto changedCompositionTypes =
- mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId());
+ mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId());
ASSERT_TRUE(changedCompositionTypes.empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
changedCompositionTypes =
- mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId());
+ mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId());
ASSERT_TRUE(changedCompositionTypes.empty());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
}
}
}
TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+ for (const DisplayWrapper display : mAllDisplays) {
ASSERT_TRUE(
mComposerClient
- ->setClientTargetSlotCount(display->getDisplayId(), kClientTargetSlotCount)
+ ->setClientTargetSlotCount(display.getDisplayId(), kClientTargetSlotCount)
.isOk());
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
+
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
ReadbackHelper::fillColorsArea(
- expectedColors, display->getDisplayWidth(),
- {0, 0, display->getDisplayWidth(), display->getDisplayHeight() / 2}, GREEN);
- ReadbackHelper::fillColorsArea(
- expectedColors, display->getDisplayWidth(),
- {0, display->getDisplayHeight() / 2, display->getDisplayWidth(),
- display->getDisplayHeight()},
- RED);
+ expectedColors, display.getDisplayWidth(),
+ {0, 0, display.getDisplayWidth(), display.getDisplayHeight() / 2}, GREEN);
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
+ {0, display.getDisplayHeight() / 2,
+ display.getDisplayWidth(), display.getDisplayHeight()},
+ RED);
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
auto deviceLayer = std::make_shared<TestBufferLayer>(
mComposerClient,
- *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
- display->getDisplayId(), display->getDisplayWidth(),
- display->getDisplayHeight() / 2, PixelFormat::RGBA_8888,
- mDisplayProperties.at(display->getDisplayId()).writer);
+ *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+ display.getDisplayId(), display.getDisplayWidth(),
+ display.getDisplayHeight() / 2, PixelFormat::RGBA_8888,
+ mDisplayProperties.at(display.getDisplayId()).writer);
std::vector<Color> deviceColors(deviceLayer->getWidth() * deviceLayer->getHeight());
ReadbackHelper::fillColorsArea(deviceColors,
static_cast<int32_t>(deviceLayer->getWidth()),
@@ -868,7 +935,7 @@
deviceLayer->setZOrder(10);
deviceLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
- deviceLayer->write(mDisplayProperties.at(display->getDisplayId()).writer);
+ deviceLayer->write(mDisplayProperties.at(display.getDisplayId()).writer);
PixelFormat clientFormat = PixelFormat::RGBA_8888;
auto clientUsage = static_cast<uint32_t>(
@@ -876,35 +943,34 @@
static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
- int32_t clientWidth = display->getDisplayWidth();
- int32_t clientHeight = display->getDisplayHeight() / 2;
+ int32_t clientWidth = display.getDisplayWidth();
+ int32_t clientHeight = display.getDisplayHeight() / 2;
auto clientLayer = std::make_shared<TestBufferLayer>(
mComposerClient,
- *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
- display->getDisplayId(), clientWidth, clientHeight, PixelFormat::RGBA_FP16,
- mDisplayProperties.at(display->getDisplayId()).writer, Composition::DEVICE);
- common::Rect clientFrame = {0, display->getDisplayHeight() / 2,
- display->getDisplayWidth(), display->getDisplayHeight()};
+ *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+ display.getDisplayId(), clientWidth, clientHeight, PixelFormat::RGBA_FP16,
+ mDisplayProperties.at(display.getDisplayId()).writer, Composition::DEVICE);
+ common::Rect clientFrame = {0, display.getDisplayHeight() / 2,
+ display.getDisplayWidth(), display.getDisplayHeight()};
clientLayer->setDisplayFrame(clientFrame);
clientLayer->setZOrder(0);
- clientLayer->write(mDisplayProperties.at(display->getDisplayId()).writer);
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ clientLayer->write(mDisplayProperties.at(display.getDisplayId()).writer);
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
+ execute(display.getDisplayId());
auto changedCompositionTypes =
- mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId());
+ mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId());
if (changedCompositionTypes.size() != 1) {
continue;
}
// create client target buffer
ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0].composition);
- const auto& [graphicBufferStatus, graphicBuffer] =
- allocateBuffer(*display, clientUsage);
+ const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(display, clientUsage);
ASSERT_TRUE(graphicBufferStatus);
const auto& buffer = graphicBuffer->handle;
@@ -912,131 +978,133 @@
int bytesPerPixel = -1;
int bytesPerStride = -1;
graphicBuffer->lock(clientUsage,
- {0, 0, display->getDisplayWidth(), display->getDisplayHeight()},
+ {0, 0, display.getDisplayWidth(), display.getDisplayHeight()},
&clientBufData, &bytesPerPixel, &bytesPerStride);
std::vector<Color> clientColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
- ReadbackHelper::fillColorsArea(clientColors, display->getDisplayWidth(), clientFrame,
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+ ReadbackHelper::fillColorsArea(clientColors, display.getDisplayWidth(), clientFrame,
RED);
ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(
- static_cast<uint32_t>(display->getDisplayWidth()),
- static_cast<uint32_t>(display->getDisplayHeight()), graphicBuffer->getStride(),
+ static_cast<uint32_t>(display.getDisplayWidth()),
+ static_cast<uint32_t>(display.getDisplayHeight()), graphicBuffer->getStride(),
bytesPerPixel, clientBufData, clientFormat, clientColors));
int32_t clientFence;
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
ASSERT_EQ(::android::OK, unlockStatus);
- mDisplayProperties.at(display->getDisplayId())
- .writer.setClientTarget(display->getDisplayId(), /*slot*/ 0, buffer,
- clientFence, clientDataspace,
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.setClientTarget(display.getDisplayId(), /*slot*/ 0, buffer, clientFence,
+ clientDataspace,
std::vector<common::Rect>(1, clientFrame), 1.f);
clientLayer->setToClientComposition(
- mDisplayProperties.at(display->getDisplayId()).writer);
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ mDisplayProperties.at(display.getDisplayId()).writer);
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
+ execute(display.getDisplayId());
changedCompositionTypes =
- mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId());
+ mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId());
ASSERT_TRUE(changedCompositionTypes.empty());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
}
}
TEST_P(GraphicsCompositionTest, SetLayerDamage) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (const DisplayWrapper display : mAllDisplays) {
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
- common::Rect redRect = {0, 0, display->getDisplayWidth() / 4,
- display->getDisplayHeight() / 4};
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
+
+ common::Rect redRect = {0, 0, display.getDisplayWidth() / 4,
+ display.getDisplayHeight() / 4};
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), redRect,
- RED);
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), redRect, RED);
auto layer = std::make_shared<TestBufferLayer>(
mComposerClient,
- *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
- display->getDisplayId(), display->getDisplayWidth(),
- display->getDisplayHeight(), PixelFormat::RGBA_8888,
- mDisplayProperties.at(display->getDisplayId()).writer);
- layer->setDisplayFrame({0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+ *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+ display.getDisplayId(), display.getDisplayWidth(), display.getDisplayHeight(),
+ PixelFormat::RGBA_8888, mDisplayProperties.at(display.getDisplayId()).writer);
+ layer->setDisplayFrame({0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
layer->setZOrder(10);
layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
// update surface damage and recheck
- redRect = {display->getDisplayWidth() / 4, display->getDisplayHeight() / 4,
- display->getDisplayWidth() / 2, display->getDisplayHeight() / 2};
- ReadbackHelper::clearColors(expectedColors, display->getDisplayWidth(),
- display->getDisplayHeight(), display->getDisplayWidth());
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), redRect,
- RED);
+ redRect = {display.getDisplayWidth() / 4, display.getDisplayHeight() / 4,
+ display.getDisplayWidth() / 2, display.getDisplayHeight() / 2};
+ ReadbackHelper::clearColors(expectedColors, display.getDisplayWidth(),
+ display.getDisplayHeight(), display.getDisplayWidth());
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), redRect, RED);
ASSERT_NO_FATAL_FAILURE(layer->fillBuffer(expectedColors));
layer->setSurfaceDamage(std::vector<common::Rect>(
- 1, {0, 0, display->getDisplayWidth() / 2, display->getDisplayWidth() / 2}));
+ 1, {0, 0, display.getDisplayWidth() / 2, display.getDisplayWidth() / 2}));
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
@@ -1044,56 +1112,60 @@
}
TEST_P(GraphicsCompositionTest, SetLayerPlaneAlpha) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (const DisplayWrapper display : mAllDisplays) {
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
+
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
auto layer = std::make_shared<TestColorLayer>(
- mComposerClient, display->getDisplayId(),
- mDisplayProperties.at(display->getDisplayId()).writer);
+ mComposerClient, display.getDisplayId(),
+ mDisplayProperties.at(display.getDisplayId()).writer);
layer->setColor(RED);
- layer->setDisplayFrame({0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+ layer->setDisplayFrame({0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
layer->setZOrder(10);
layer->setAlpha(0);
layer->setBlendMode(BlendMode::PREMULTIPLIED);
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
- auto& testRenderEngine =
- mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+ auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
testRenderEngine->setRenderLayers(layers);
ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1102,70 +1174,72 @@
}
TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (const DisplayWrapper display : mAllDisplays) {
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
+
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
ReadbackHelper::fillColorsArea(
- expectedColors, display->getDisplayWidth(),
- {0, 0, display->getDisplayWidth(), display->getDisplayHeight() / 4}, RED);
- ReadbackHelper::fillColorsArea(
- expectedColors, display->getDisplayWidth(),
- {0, display->getDisplayHeight() / 2, display->getDisplayWidth(),
- display->getDisplayHeight()},
- BLUE);
+ expectedColors, display.getDisplayWidth(),
+ {0, 0, display.getDisplayWidth(), display.getDisplayHeight() / 4}, RED);
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
+ {0, display.getDisplayHeight() / 2,
+ display.getDisplayWidth(), display.getDisplayHeight()},
+ BLUE);
auto layer = std::make_shared<TestBufferLayer>(
mComposerClient,
- *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
- display->getDisplayId(), display->getDisplayWidth(),
- display->getDisplayHeight(), PixelFormat::RGBA_8888,
- mDisplayProperties.at(display->getDisplayId()).writer);
- layer->setDisplayFrame({0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+ *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+ display.getDisplayId(), display.getDisplayWidth(), display.getDisplayHeight(),
+ PixelFormat::RGBA_8888, mDisplayProperties.at(display.getDisplayId()).writer);
+ layer->setDisplayFrame({0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
layer->setZOrder(10);
layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
- layer->setSourceCrop({0, static_cast<float>(display->getDisplayHeight() / 2),
- static_cast<float>(display->getDisplayWidth()),
- static_cast<float>(display->getDisplayHeight())});
+ layer->setSourceCrop({0, static_cast<float>(display.getDisplayHeight() / 2),
+ static_cast<float>(display.getDisplayWidth()),
+ static_cast<float>(display.getDisplayHeight())});
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
// update expected colors to match crop
ReadbackHelper::fillColorsArea(
- expectedColors, display->getDisplayWidth(),
- {0, 0, display->getDisplayWidth(), display->getDisplayHeight()}, BLUE);
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ expectedColors, display.getDisplayWidth(),
+ {0, 0, display.getDisplayWidth(), display.getDisplayHeight()}, BLUE);
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
- auto& testRenderEngine =
- mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+ auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
testRenderEngine->setRenderLayers(layers);
ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1174,98 +1248,100 @@
}
TEST_P(GraphicsCompositionTest, SetLayerZOrder) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (const DisplayWrapper display : mAllDisplays) {
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
- common::Rect redRect = {0, 0, display->getDisplayWidth(),
- display->getDisplayHeight() / 2};
- common::Rect blueRect = {0, display->getDisplayHeight() / 4, display->getDisplayWidth(),
- display->getDisplayHeight()};
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
+
+ common::Rect redRect = {0, 0, display.getDisplayWidth(),
+ display.getDisplayHeight() / 2};
+ common::Rect blueRect = {0, display.getDisplayHeight() / 4, display.getDisplayWidth(),
+ display.getDisplayHeight()};
auto redLayer = std::make_shared<TestColorLayer>(
- mComposerClient, display->getDisplayId(),
- mDisplayProperties.at(display->getDisplayId()).writer);
+ mComposerClient, display.getDisplayId(),
+ mDisplayProperties.at(display.getDisplayId()).writer);
redLayer->setColor(RED);
redLayer->setDisplayFrame(redRect);
auto blueLayer = std::make_shared<TestColorLayer>(
- mComposerClient, display->getDisplayId(),
- mDisplayProperties.at(display->getDisplayId()).writer);
+ mComposerClient, display.getDisplayId(),
+ mDisplayProperties.at(display.getDisplayId()).writer);
blueLayer->setColor(BLUE);
blueLayer->setDisplayFrame(blueRect);
blueLayer->setZOrder(5);
std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, blueLayer};
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
// red in front of blue
redLayer->setZOrder(10);
// fill blue first so that red will overwrite on overlap
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), blueRect,
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), blueRect,
BLUE);
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), redRect,
- RED);
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), redRect, RED);
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
redLayer->setZOrder(1);
- ReadbackHelper::clearColors(expectedColors, display->getDisplayWidth(),
- display->getDisplayHeight(), display->getDisplayWidth());
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), redRect,
- RED);
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), blueRect,
+ ReadbackHelper::clearColors(expectedColors, display.getDisplayWidth(),
+ display.getDisplayHeight(), display.getDisplayWidth());
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), redRect, RED);
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), blueRect,
BLUE);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
- auto& testRenderEngine =
- mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+ auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
testRenderEngine->setRenderLayers(layers);
ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1274,32 +1350,38 @@
}
TEST_P(GraphicsCompositionTest, SetLayerBrightnessDims) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (const DisplayWrapper display : mAllDisplays) {
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
- const common::Rect redRect = {0, 0, display->getDisplayWidth(),
- display->getDisplayHeight() / 2};
- const common::Rect dimmerRedRect = {0, display->getDisplayHeight() / 2,
- display->getDisplayWidth(),
- display->getDisplayHeight()};
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
+
+ const common::Rect redRect = {0, 0, display.getDisplayWidth(),
+ display.getDisplayHeight() / 2};
+ const common::Rect dimmerRedRect = {0, display.getDisplayHeight() / 2,
+ display.getDisplayWidth(),
+ display.getDisplayHeight()};
static constexpr float kMaxBrightnessNits = 300.f;
const auto redLayer = std::make_shared<TestColorLayer>(
- mComposerClient, display->getDisplayId(),
- mDisplayProperties.at(display->getDisplayId()).writer);
+ mComposerClient, display.getDisplayId(),
+ mDisplayProperties.at(display.getDisplayId()).writer);
redLayer->setColor(RED);
redLayer->setDisplayFrame(redRect);
redLayer->setWhitePointNits(kMaxBrightnessNits);
redLayer->setBrightness(1.f);
const auto dimmerRedLayer = std::make_shared<TestColorLayer>(
- mComposerClient, display->getDisplayId(),
- mDisplayProperties.at(display->getDisplayId()).writer);
+ mComposerClient, display.getDisplayId(),
+ mDisplayProperties.at(display.getDisplayId()).writer);
dimmerRedLayer->setColor(RED);
dimmerRedLayer->setDisplayFrame(dimmerRedRect);
// Intentionally use a small dimming ratio as some implementations may be more likely
@@ -1310,42 +1392,39 @@
const std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, dimmerRedLayer};
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), redRect,
- RED);
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
- dimmerRedRect, DIM_RED);
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), redRect, RED);
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), dimmerRedRect,
+ DIM_RED);
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
ALOGI(" Readback verification not supported for GPU composition for color mode %d",
mode);
continue;
}
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
- auto& testRenderEngine =
- mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+ auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
testRenderEngine->setRenderLayers(layers);
ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1462,49 +1541,53 @@
};
TEST_P(GraphicsBlendModeCompositionTest, None) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (const DisplayWrapper display : mAllDisplays) {
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
+
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
- setBackgroundColor(display->getDisplayId(), BLACK);
- setTopLayerColor(display->getDisplayId(), TRANSLUCENT_RED);
- setUpLayers(*display, BlendMode::NONE);
- setExpectedColors(*display, expectedColors);
+ setBackgroundColor(display.getDisplayId(), BLACK);
+ setTopLayerColor(display.getDisplayId(), TRANSLUCENT_RED);
+ setUpLayers(display, BlendMode::NONE);
+ setExpectedColors(display, expectedColors);
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- auto& layers = mDisplayGfx[display->getDisplayId()].layers;
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ auto& layers = mDisplayGfx[display.getDisplayId()].layers;
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
- auto& testRenderEngine =
- mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+ auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
testRenderEngine->setRenderLayers(layers);
ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1513,94 +1596,103 @@
}
TEST_P(GraphicsBlendModeCompositionTest, Coverage) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (const DisplayWrapper display : mAllDisplays) {
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
+
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
- setBackgroundColor(display->getDisplayId(), BLACK);
- setTopLayerColor(display->getDisplayId(), TRANSLUCENT_RED);
+ setBackgroundColor(display.getDisplayId(), BLACK);
+ setTopLayerColor(display.getDisplayId(), TRANSLUCENT_RED);
- setUpLayers(*display, BlendMode::COVERAGE);
- setExpectedColors(*display, expectedColors);
+ setUpLayers(display, BlendMode::COVERAGE);
+ setExpectedColors(display, expectedColors);
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- auto& layers = mDisplayGfx[display->getDisplayId()].layers;
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ auto& layers = mDisplayGfx[display.getDisplayId()].layers;
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
}
}
}
TEST_P(GraphicsBlendModeCompositionTest, Premultiplied) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (const DisplayWrapper display : mAllDisplays) {
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
+
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
- setBackgroundColor(display->getDisplayId(), BLACK);
- setTopLayerColor(display->getDisplayId(), TRANSLUCENT_RED);
- setUpLayers(*display, BlendMode::PREMULTIPLIED);
- setExpectedColors(*display, expectedColors);
+ setBackgroundColor(display.getDisplayId(), BLACK);
+ setTopLayerColor(display.getDisplayId(), TRANSLUCENT_RED);
+ setUpLayers(display, BlendMode::PREMULTIPLIED);
+ setExpectedColors(display, expectedColors);
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- auto& layers = mDisplayGfx[display->getDisplayId()].layers;
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ auto& layers = mDisplayGfx[display.getDisplayId()].layers;
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
- auto& testRenderEngine =
- mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+ auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
testRenderEngine->setRenderLayers(layers);
ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1658,58 +1750,63 @@
};
TEST_P(GraphicsTransformCompositionTest, FLIP_H) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- auto status = mComposerClient->setColorMode(display->getDisplayId(), mode,
+ for (const DisplayWrapper display : mAllDisplays) {
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ auto status = mComposerClient->setColorMode(display.getDisplayId(), mode,
RenderIntent::COLORIMETRIC);
+
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
+
if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
(status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED ||
status.getServiceSpecificError() == IComposerClient::EX_BAD_PARAMETER)) {
ALOGI("ColorMode not supported on Display %" PRId64 " for ColorMode %d",
- display->getDisplayId(), mode);
+ display.getDisplayId(), mode);
continue;
}
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- auto& bufferLayer = mDisplayGfx[display->getDisplayId()].bufferLayer;
+ auto& bufferLayer = mDisplayGfx[display.getDisplayId()].bufferLayer;
bufferLayer->setTransform(Transform::FLIP_H);
bufferLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
- int& sideLength = mDisplayGfx[display->getDisplayId()].sideLength;
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+ int& sideLength = mDisplayGfx[display.getDisplayId()].sideLength;
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
{sideLength / 2, 0, sideLength, sideLength / 2}, RED);
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
{0, sideLength / 2, sideLength / 2, sideLength}, BLUE);
- auto& layers = mDisplayGfx[display->getDisplayId()].layers;
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ auto& layers = mDisplayGfx[display.getDisplayId()].layers;
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
- auto& testRenderEngine =
- mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+ auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
testRenderEngine->setRenderLayers(layers);
ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1718,53 +1815,57 @@
}
TEST_P(GraphicsTransformCompositionTest, FLIP_V) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (const DisplayWrapper display : mAllDisplays) {
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
+
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- auto& bufferLayer = mDisplayGfx[display->getDisplayId()].bufferLayer;
+ auto& bufferLayer = mDisplayGfx[display.getDisplayId()].bufferLayer;
bufferLayer->setTransform(Transform::FLIP_V);
bufferLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
- int& sideLength = mDisplayGfx[display->getDisplayId()].sideLength;
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+ int& sideLength = mDisplayGfx[display.getDisplayId()].sideLength;
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
{0, sideLength / 2, sideLength / 2, sideLength}, RED);
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
{sideLength / 2, 0, sideLength, sideLength / 2}, BLUE);
- auto& layers = mDisplayGfx[display->getDisplayId()].layers;
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ auto& layers = mDisplayGfx[display.getDisplayId()].layers;
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
- auto& testRenderEngine =
- mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+ auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
testRenderEngine->setRenderLayers(layers);
ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1773,55 +1874,59 @@
}
TEST_P(GraphicsTransformCompositionTest, ROT_180) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (const DisplayWrapper display : mAllDisplays) {
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
- ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
+
+ ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+ display.getDisplayWidth(), display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+ dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- auto& bufferLayer = mDisplayGfx[display->getDisplayId()].bufferLayer;
+ auto& bufferLayer = mDisplayGfx[display.getDisplayId()].bufferLayer;
bufferLayer->setTransform(Transform::ROT_180);
bufferLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
std::vector<Color> expectedColors(
- static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
- int& sideLength = mDisplayGfx[display->getDisplayId()].sideLength;
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+ static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+ int& sideLength = mDisplayGfx[display.getDisplayId()].sideLength;
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
{sideLength / 2, sideLength / 2, sideLength, sideLength},
RED);
- ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+ ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
{0, 0, sideLength / 2, sideLength / 2}, BLUE);
- auto& layers = mDisplayGfx[display->getDisplayId()].layers;
- writeLayers(layers, display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ auto& layers = mDisplayGfx[display.getDisplayId()].layers;
+ writeLayers(layers, display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
- ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
+ ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
- auto& testRenderEngine =
- mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+ auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
testRenderEngine->setRenderLayers(layers);
ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1888,59 +1993,63 @@
// @VsrTest = 4.4-015
TEST_P(GraphicsColorManagementCompositionTest, ColorConversion) {
- for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
- for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
- EXPECT_TRUE(mComposerClient
- ->setColorMode(display->getDisplayId(), mode,
- RenderIntent::COLORIMETRIC)
- .isOk());
+ for (const DisplayWrapper display : mAllDisplays) {
+ for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+ .isOk());
+
+ auto [dataspace, readbackSupported] =
+ GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+ if (!readbackSupported) {
+ continue;
+ }
auto& clientCompositionDisplaySettings =
- mDisplayProperties.at(display->getDisplayId()).clientCompositionDisplaySettings;
+ mDisplayProperties.at(display.getDisplayId()).clientCompositionDisplaySettings;
clientCompositionDisplaySettings.outputDataspace =
- static_cast<::android::ui::Dataspace>(
- mDisplayProperties.at(display->getDisplayId()).dataspace);
- mDisplayProperties.at(display->getDisplayId())
+ static_cast<::android::ui::Dataspace>(dataspace);
+ mDisplayProperties.at(display.getDisplayId())
.testRenderEngine->setDisplaySettings(clientCompositionDisplaySettings);
- makeLayer(*display);
+ makeLayer(display);
for (auto color : {LIGHT_RED, LIGHT_GREEN, LIGHT_BLUE}) {
ALOGD("Testing color: %f, %f, %f, %f with color mode: %d", color.r, color.g,
color.b, color.a, mode);
ReadbackBuffer readbackBuffer(
- display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
- display->getDisplayHeight(),
- mDisplayProperties.at(display->getDisplayId()).pixelFormat,
- mDisplayProperties.at(display->getDisplayId()).dataspace);
+ display.getDisplayId(), mComposerClient, display.getDisplayWidth(),
+ display.getDisplayHeight(),
+ mDisplayProperties.at(display.getDisplayId()).pixelFormat, dataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- fillColor(*display, color);
- auto& layer = mDisplayGfx[display->getDisplayId()].layer;
- writeLayers({layer}, display->getDisplayId());
- EXPECT_TRUE(mComposerClient->setPowerMode(display->getDisplayId(), PowerMode::ON)
+ fillColor(display, color);
+ auto& layer = mDisplayGfx[display.getDisplayId()].layer;
+ writeLayers({layer}, display.getDisplayId());
+ EXPECT_TRUE(mComposerClient->setPowerMode(display.getDisplayId(), PowerMode::ON)
.isOk());
ASSERT_TRUE(
- mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.validateDisplay(display->getDisplayId(),
+ mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.validateDisplay(display.getDisplayId(),
ComposerClientWriter::kNoTimestamp,
ComposerClientWrapper::kNoFrameIntervalNs);
- execute(display->getDisplayId());
- if (!mDisplayProperties.at(display->getDisplayId())
- .reader.takeChangedCompositionTypes(display->getDisplayId())
+ execute(display.getDisplayId());
+ if (!mDisplayProperties.at(display.getDisplayId())
+ .reader.takeChangedCompositionTypes(display.getDisplayId())
.empty()) {
continue;
}
ASSERT_TRUE(
- mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
- mDisplayProperties.at(display->getDisplayId())
- .writer.presentDisplay(display->getDisplayId());
- execute(display->getDisplayId());
+ mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId())
+ .writer.presentDisplay(display.getDisplayId());
+ execute(display.getDisplayId());
ASSERT_TRUE(
- mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+ mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
auto& testRenderEngine =
- mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+ mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
testRenderEngine->setRenderLayers({layer});
ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
ASSERT_NO_FATAL_FAILURE(
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl
index 3c812c0..fe59ee7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl
@@ -33,7 +33,7 @@
package android.hardware.radio.network;
/* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
parcelable BarringInfo {
int serviceType;
int barringType;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellularIdentifierDisclosure.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellularIdentifierDisclosure.aidl
index 540dc1e..109bacf 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellularIdentifierDisclosure.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellularIdentifierDisclosure.aidl
@@ -33,7 +33,7 @@
package android.hardware.radio.network;
/* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
parcelable CellularIdentifierDisclosure {
String plmn;
android.hardware.radio.network.CellularIdentifier identifier = android.hardware.radio.network.CellularIdentifier.UNKNOWN;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl
index cdac0be..5c5dcd2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl
@@ -33,7 +33,7 @@
package android.hardware.radio.network;
/* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
parcelable NetworkScanRequest {
int type;
int interval;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl
index 518a378..c827fd4 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl
@@ -33,7 +33,7 @@
package android.hardware.radio.network;
/* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
parcelable NetworkScanResult {
int status;
android.hardware.radio.RadioError error = android.hardware.radio.RadioError.NONE;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl
index 8613f19..4b55c45 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl
@@ -33,7 +33,7 @@
package android.hardware.radio.network;
/* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
parcelable SecurityAlgorithmUpdate {
android.hardware.radio.network.ConnectionEvent connectionEvent = android.hardware.radio.network.ConnectionEvent.CS_SIGNALLING_GSM;
android.hardware.radio.network.SecurityAlgorithm encryption = android.hardware.radio.network.SecurityAlgorithm.A50;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
index 2041bad..46769e9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
@@ -33,7 +33,7 @@
package android.hardware.radio.network;
/* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
parcelable SignalThresholdInfo {
int signalMeasurement;
int hysteresisMs;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl
index c546565..25f8372 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl
@@ -33,7 +33,7 @@
package android.hardware.radio.sim;
/* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
parcelable SimRefreshResult {
int type;
int efId;
diff --git a/radio/aidl/android/hardware/radio/network/BarringInfo.aidl b/radio/aidl/android/hardware/radio/network/BarringInfo.aidl
index 7be3987..cabe325 100644
--- a/radio/aidl/android/hardware/radio/network/BarringInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/BarringInfo.aidl
@@ -21,6 +21,7 @@
/** @hide */
@VintfStability
@JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
@SuppressWarnings(value={"redundant-name"})
parcelable BarringInfo {
/**
diff --git a/radio/aidl/android/hardware/radio/network/CellularIdentifierDisclosure.aidl b/radio/aidl/android/hardware/radio/network/CellularIdentifierDisclosure.aidl
index c851b43..3fd1d71 100644
--- a/radio/aidl/android/hardware/radio/network/CellularIdentifierDisclosure.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellularIdentifierDisclosure.aidl
@@ -26,6 +26,7 @@
* @hide
*/
@JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
@VintfStability
parcelable CellularIdentifierDisclosure {
// The PLMN-ID to which the UE transmitted the cellular identifier
diff --git a/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl b/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
index 30977f8..9c7fed0 100644
--- a/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
+++ b/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
@@ -21,6 +21,7 @@
/** @hide */
@VintfStability
@JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
@SuppressWarnings(value={"redundant-name"})
parcelable NetworkScanRequest {
const int RADIO_ACCESS_SPECIFIER_MAX_SIZE = 8;
diff --git a/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl b/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl
index 700c5e2..2010a9a 100644
--- a/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl
+++ b/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl
@@ -22,6 +22,7 @@
/** @hide */
@VintfStability
@JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
@SuppressWarnings(value={"redundant-name"})
parcelable NetworkScanResult {
/**
diff --git a/radio/aidl/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl b/radio/aidl/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl
index ab48148..59b5f6e 100644
--- a/radio/aidl/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl
+++ b/radio/aidl/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl
@@ -26,6 +26,7 @@
* @hide
*/
@JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
@VintfStability
parcelable SecurityAlgorithmUpdate {
/**
diff --git a/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
index 1305a2c..f6b7021 100644
--- a/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
@@ -24,6 +24,7 @@
*/
@VintfStability
@JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
@SuppressWarnings(value={"redundant-name"})
parcelable SignalThresholdInfo {
/**
diff --git a/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl b/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl
index 88c4552..805885f 100644
--- a/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl
@@ -19,6 +19,7 @@
/** @hide */
@VintfStability
@JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
@SuppressWarnings(value={"redundant-name"})
parcelable SimRefreshResult {
/**
diff --git a/radio/aidl/vts/radio_aidl_hal_utils.h b/radio/aidl/vts/radio_aidl_hal_utils.h
index d9c7311..3e2e633 100644
--- a/radio/aidl/vts/radio_aidl_hal_utils.h
+++ b/radio/aidl/vts/radio_aidl_hal_utils.h
@@ -65,8 +65,6 @@
static constexpr const char* FEATURE_TELEPHONY = "android.hardware.telephony";
-static constexpr const char* FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
-
static constexpr const char* FEATURE_TELEPHONY_IMS = "android.hardware.telephony.ims";
static constexpr const char* FEATURE_TELEPHONY_CALLING = "android.hardware.telephony.calling";
diff --git a/radio/aidl/vts/radio_messaging_test.cpp b/radio/aidl/vts/radio_messaging_test.cpp
index 089895f..7e4ef96 100644
--- a/radio/aidl/vts/radio_messaging_test.cpp
+++ b/radio/aidl/vts/radio_messaging_test.cpp
@@ -113,104 +113,6 @@
}
/*
- * Test IRadioMessaging.sendCdmaSms() for the response returned.
- */
-TEST_P(RadioMessagingTest, sendCdmaSms) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping sendCdmaSms "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
-
- // Create a CdmaSmsAddress
- CdmaSmsAddress cdmaSmsAddress;
- cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
- cdmaSmsAddress.isNumberModeDataNetwork = false;
- cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
- cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
- cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
-
- // Create a CdmaSmsSubAddress
- CdmaSmsSubaddress cdmaSmsSubaddress;
- cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
- cdmaSmsSubaddress.odd = false;
- cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
-
- // Create a CdmaSmsMessage
- CdmaSmsMessage cdmaSmsMessage;
- cdmaSmsMessage.teleserviceId = 4098;
- cdmaSmsMessage.isServicePresent = false;
- cdmaSmsMessage.serviceCategory = 0;
- cdmaSmsMessage.address = cdmaSmsAddress;
- cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
- cdmaSmsMessage.bearerData =
- (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
-
- radio_messaging->sendCdmaSms(serial, cdmaSmsMessage);
-
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_messaging->rspInfo.error,
- {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
- CHECK_GENERAL_ERROR));
- }
-}
-
-/*
- * Test IRadioMessaging.sendCdmaSmsExpectMore() for the response returned.
- */
-TEST_P(RadioMessagingTest, sendCdmaSmsExpectMore) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping sendCdmaSmsExpectMore "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
-
- // Create a CdmaSmsAddress
- CdmaSmsAddress cdmaSmsAddress;
- cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
- cdmaSmsAddress.isNumberModeDataNetwork = false;
- cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
- cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
- cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
-
- // Create a CdmaSmsSubAddress
- CdmaSmsSubaddress cdmaSmsSubaddress;
- cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
- cdmaSmsSubaddress.odd = false;
- cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
-
- // Create a CdmaSmsMessage
- CdmaSmsMessage cdmaSmsMessage;
- cdmaSmsMessage.teleserviceId = 4098;
- cdmaSmsMessage.isServicePresent = false;
- cdmaSmsMessage.serviceCategory = 0;
- cdmaSmsMessage.address = cdmaSmsAddress;
- cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
- cdmaSmsMessage.bearerData =
- (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
-
- radio_messaging->sendCdmaSmsExpectMore(serial, cdmaSmsMessage);
-
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_messaging->rspInfo.error,
- {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
- CHECK_GENERAL_ERROR));
- }
-}
-
-/*
* Test IRadioMessaging.setGsmBroadcastConfig() for the response returned.
*/
TEST_P(RadioMessagingTest, setGsmBroadcastConfig) {
@@ -304,85 +206,6 @@
}
/*
- * Test IRadioMessaging.setCdmaBroadcastConfig() for the response returned.
- */
-TEST_P(RadioMessagingTest, setCdmaBroadcastConfig) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping setCdmaBroadcastConfig "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
-
- CdmaBroadcastSmsConfigInfo cbSmsConfig;
- cbSmsConfig.serviceCategory = 4096;
- cbSmsConfig.language = 1;
- cbSmsConfig.selected = true;
-
- std::vector<CdmaBroadcastSmsConfigInfo> cdmaBroadcastSmsConfigInfoList = {cbSmsConfig};
-
- radio_messaging->setCdmaBroadcastConfig(serial, cdmaBroadcastSmsConfigInfoList);
-
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
- {RadioError::NONE, RadioError::INVALID_MODEM_STATE},
- CHECK_GENERAL_ERROR));
- }
-}
-
-/*
- * Test IRadioMessaging.getCdmaBroadcastConfig() for the response returned.
- */
-TEST_P(RadioMessagingTest, getCdmaBroadcastConfig) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping getCdmaBroadcastConfig "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
-
- radio_messaging->getCdmaBroadcastConfig(serial);
-
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error, {RadioError::NONE},
- CHECK_GENERAL_ERROR));
- }
-}
-
-/*
- * Test IRadioMessaging.setCdmaBroadcastActivation() for the response returned.
- */
-TEST_P(RadioMessagingTest, setCdmaBroadcastActivation) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping setCdmaBroadcastActivation "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
- bool activate = false;
-
- radio_messaging->setCdmaBroadcastActivation(serial, activate);
-
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
- {RadioError::NONE, RadioError::INVALID_ARGUMENTS},
- CHECK_GENERAL_ERROR));
- }
-}
-
-/*
* Test IRadioMessaging.setGsmBroadcastActivation() for the response returned.
*/
TEST_P(RadioMessagingTest, setGsmBroadcastActivation) {
@@ -462,35 +285,6 @@
}
/*
- * Test IRadioMessaging.acknowledgeLastIncomingCdmaSms() for the response returned.
- */
-TEST_P(RadioMessagingTest, acknowledgeLastIncomingCdmaSms) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping acknowledgeIncomingGsmSmsWithPdu "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
-
- // Create a CdmaSmsAck
- CdmaSmsAck cdmaSmsAck;
- cdmaSmsAck.errorClass = false;
- cdmaSmsAck.smsCauseCode = 1;
-
- radio_messaging->acknowledgeLastIncomingCdmaSms(serial, cdmaSmsAck);
-
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
- {RadioError::INVALID_ARGUMENTS, RadioError::NO_SMS_TO_ACK},
- CHECK_GENERAL_ERROR));
- }
-}
-
-/*
* Test IRadioMessaging.sendImsSms() for the response returned.
*/
TEST_P(RadioMessagingTest, sendImsSms) {
@@ -656,118 +450,6 @@
}
/*
- * Test IRadioMessaging.writeSmsToRuim() for the response returned.
- */
-TEST_P(RadioMessagingTest, writeSmsToRuim) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping writeSmsToRuim "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
-
- // Create a CdmaSmsAddress
- CdmaSmsAddress cdmaSmsAddress;
- cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
- cdmaSmsAddress.isNumberModeDataNetwork = false;
- cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
- cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
- cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
-
- // Create a CdmaSmsSubAddress
- CdmaSmsSubaddress cdmaSmsSubaddress;
- cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
- cdmaSmsSubaddress.odd = false;
- cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
-
- // Create a CdmaSmsMessage
- CdmaSmsMessage cdmaSmsMessage;
- cdmaSmsMessage.teleserviceId = 4098;
- cdmaSmsMessage.isServicePresent = false;
- cdmaSmsMessage.serviceCategory = 0;
- cdmaSmsMessage.address = cdmaSmsAddress;
- cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
- cdmaSmsMessage.bearerData =
- (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
-
- // Create a CdmaSmsWriteArgs
- CdmaSmsWriteArgs cdmaSmsWriteArgs;
- cdmaSmsWriteArgs.status = CdmaSmsWriteArgs::STATUS_REC_UNREAD;
- cdmaSmsWriteArgs.message = cdmaSmsMessage;
-
- radio_messaging->writeSmsToRuim(serial, cdmaSmsWriteArgs);
-
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_messaging->rspInfo.error,
- {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_SMS_FORMAT,
- RadioError::INVALID_SMSC_ADDRESS, RadioError::INVALID_STATE, RadioError::MODEM_ERR,
- RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT},
- CHECK_GENERAL_ERROR));
- }
-}
-
-/*
- * Test IRadioMessaging.deleteSmsOnRuim() for the response returned.
- */
-TEST_P(RadioMessagingTest, deleteSmsOnRuim) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping deleteSmsOnRuim "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
- int index = 1;
-
- // Create a CdmaSmsAddress
- CdmaSmsAddress cdmaSmsAddress;
- cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
- cdmaSmsAddress.isNumberModeDataNetwork = false;
- cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
- cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
- cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
-
- // Create a CdmaSmsSubAddress
- CdmaSmsSubaddress cdmaSmsSubaddress;
- cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
- cdmaSmsSubaddress.odd = false;
- cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
-
- // Create a CdmaSmsMessage
- CdmaSmsMessage cdmaSmsMessage;
- cdmaSmsMessage.teleserviceId = 4098;
- cdmaSmsMessage.isServicePresent = false;
- cdmaSmsMessage.serviceCategory = 0;
- cdmaSmsMessage.address = cdmaSmsAddress;
- cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
- cdmaSmsMessage.bearerData =
- (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
-
- // Create a CdmaSmsWriteArgs
- CdmaSmsWriteArgs cdmaSmsWriteArgs;
- cdmaSmsWriteArgs.status = CdmaSmsWriteArgs::STATUS_REC_UNREAD;
- cdmaSmsWriteArgs.message = cdmaSmsMessage;
-
- radio_messaging->deleteSmsOnRuim(serial, index);
-
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_messaging->rspInfo.error,
- {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_MODEM_STATE,
- RadioError::MODEM_ERR, RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT},
- CHECK_GENERAL_ERROR));
- }
-}
-
-/*
* Test IRadioMessaging.reportSmsMemoryStatus() for the response returned.
*/
TEST_P(RadioMessagingTest, reportSmsMemoryStatus) {
diff --git a/radio/aidl/vts/radio_modem_test.cpp b/radio/aidl/vts/radio_modem_test.cpp
index 94dfa6e..1c8a6f8 100644
--- a/radio/aidl/vts/radio_modem_test.cpp
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -292,29 +292,6 @@
}
/*
- * Test IRadioModem.nvWriteCdmaPrl() for the response returned.
- */
-TEST_P(RadioModemTest, nvWriteCdmaPrl) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping nvWriteCdmaPrl "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
- std::vector<uint8_t> prl = {1, 2, 3, 4, 5};
-
- radio_modem->nvWriteCdmaPrl(serial, std::vector<uint8_t>(prl));
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
- CHECK_GENERAL_ERROR));
- }
-}
-
-/*
* Test IRadioModem.nvResetConfig() for the response returned.
*/
TEST_P(RadioModemTest, nvResetConfig) {
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index ff231db..bdd4148 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -590,42 +590,6 @@
}
/*
- * Test IRadioNetwork.setSignalStrengthReportingCriteria() for CDMA2000
- */
-TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Cdma2000) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
- GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Cdma2000 "
- "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
- }
-
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Cdma2000 "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
-
- SignalThresholdInfo signalThresholdInfo;
- signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
- signalThresholdInfo.hysteresisMs = 5000;
- signalThresholdInfo.hysteresisDb = 2;
- signalThresholdInfo.thresholds = {-105, -90, -75, -65};
- signalThresholdInfo.isEnabled = true;
- signalThresholdInfo.ran = AccessNetwork::CDMA2000;
-
- ndk::ScopedAStatus res =
- radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
- ASSERT_OK(res);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
-
- ALOGI("setSignalStrengthReportingCriteria_Cdma2000, rspInfo.error = %s\n",
- toString(radioRsp_network->rspInfo.error).c_str());
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
-}
-
-/*
* Test IRadioNetwork.setSignalStrengthReportingCriteria() for NGRAN_SSRSRP
*/
TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_NGRAN_SSRSRP) {
@@ -790,15 +754,6 @@
signalThresholdInfoEutran.isEnabled = true;
signalThresholdInfoEutran.ran = AccessNetwork::EUTRAN;
- SignalThresholdInfo signalThresholdInfoCdma2000;
- signalThresholdInfoCdma2000.signalMeasurement =
- SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
- signalThresholdInfoCdma2000.hysteresisMs = 5000;
- signalThresholdInfoCdma2000.hysteresisDb = 2;
- signalThresholdInfoCdma2000.thresholds = {-105, -90, -75, -65};
- signalThresholdInfoCdma2000.isEnabled = true;
- signalThresholdInfoCdma2000.ran = AccessNetwork::CDMA2000;
-
SignalThresholdInfo signalThresholdInfoNgran;
signalThresholdInfoNgran.signalMeasurement =
SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_SSRSRP;
@@ -811,9 +766,6 @@
std::vector<SignalThresholdInfo> candidateSignalThresholdInfos = {
signalThresholdInfoGeran, signalThresholdInfoUtran, signalThresholdInfoEutran,
signalThresholdInfoNgran};
- if (deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- candidateSignalThresholdInfos.push_back(signalThresholdInfoCdma2000);
- }
std::vector<SignalThresholdInfo> supportedSignalThresholdInfos;
for (size_t i = 0; i < candidateSignalThresholdInfos.size(); i++) {
@@ -2015,53 +1967,6 @@
}
/*
- * Test IRadioNetwork.setCdmaRoamingPreference() for the response returned.
- */
-TEST_P(RadioNetworkTest, setCdmaRoamingPreference) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping setCdmaRoamingPreference "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
-
- radio_network->setCdmaRoamingPreference(serial, CdmaRoamingType::HOME_NETWORK);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_network->rspInfo.error,
- {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::REQUEST_NOT_SUPPORTED}));
- }
-}
-
-/*
- * Test IRadioNetwork.getCdmaRoamingPreference() for the response returned.
- */
-TEST_P(RadioNetworkTest, getCdmaRoamingPreference) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping getCdmaRoamingPreference "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
-
- radio_network->getCdmaRoamingPreference(serial);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(
- CheckAnyOfErrors(radioRsp_network->rspInfo.error,
- {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::MODEM_ERR},
- CHECK_GENERAL_ERROR));
- }
-}
-
-/*
* Test IRadioNetwork.getVoiceRadioTechnology() for the response returned.
*/
TEST_P(RadioNetworkTest, getVoiceRadioTechnology) {
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index e7c7c65..73beb57 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -1066,106 +1066,6 @@
}
/*
- * Test IRadioSim.getCdmaSubscription() for the response returned.
- */
-TEST_P(RadioSimTest, getCdmaSubscription) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping getCdmaSubscription "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
-
- radio_sim->getCdmaSubscription(serial);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_sim->rspInfo.error,
- {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
- }
-}
-
-/*
- * Test IRadioSim.getCdmaSubscriptionSource() for the response returned.
- */
-TEST_P(RadioSimTest, getCdmaSubscriptionSource) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping getCdmaSubscriptionSource "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
-
- radio_sim->getCdmaSubscriptionSource(serial);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_sim->rspInfo.error,
- {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
- }
-}
-
-/*
- * Test IRadioSim.setCdmaSubscriptionSource() for the response returned.
- */
-TEST_P(RadioSimTest, setCdmaSubscriptionSource) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping setCdmaSubscriptionSource "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
-
- radio_sim->setCdmaSubscriptionSource(serial, CdmaSubscriptionSource::RUIM_SIM);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_sim->rspInfo.error,
- {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::SUBSCRIPTION_NOT_AVAILABLE},
- CHECK_GENERAL_ERROR));
- }
-}
-
-/*
- * Test IRadioSim.setUiccSubscription() for the response returned.
- */
-TEST_P(RadioSimTest, setUiccSubscription) {
- if (!shouldTestCdma()) {
- GTEST_SKIP() << "Skipping CDMA testing (deprecated)";
- }
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
- GTEST_SKIP() << "Skipping setUiccSubscription "
- "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
- }
-
- serial = GetRandomSerialNumber();
- SelectUiccSub item;
- memset(&item, 0, sizeof(item));
-
- radio_sim->setUiccSubscription(serial, item);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(
- CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
- {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
- RadioError::MODEM_ERR, RadioError::SUBSCRIPTION_NOT_SUPPORTED},
- CHECK_GENERAL_ERROR));
- }
-}
-
-/*
* Test IRadioSim.sendEnvelope() for the response returned.
*/
TEST_P(RadioSimTest, sendEnvelope) {
diff --git a/radio/aidl/vts/radio_voice_test.cpp b/radio/aidl/vts/radio_voice_test.cpp
index 9eb5bac..3df6bfb 100644
--- a/radio/aidl/vts/radio_voice_test.cpp
+++ b/radio/aidl/vts/radio_voice_test.cpp
@@ -821,31 +821,6 @@
}
/*
- * Test IRadioVoice.sendCdmaFeatureCode() for the response returned.
- */
-TEST_P(RadioVoiceTest, sendCdmaFeatureCode) {
- if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
- GTEST_SKIP() << "Skipping sendCdmaFeatureCode "
- "due to undefined FEATURE_TELEPHONY_CDMA";
- }
-
- serial = GetRandomSerialNumber();
-
- radio_voice->sendCdmaFeatureCode(serial, std::string());
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
-
- if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
- {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
- RadioError::INVALID_CALL_ID, RadioError::INVALID_MODEM_STATE,
- RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
- CHECK_GENERAL_ERROR));
- }
-}
-
-/*
* Test IRadioVoice.sendDtmf() for the response returned.
*/
TEST_P(RadioVoiceTest, sendDtmf) {
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 52c7feb..eb2eba1 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",
@@ -28,7 +30,13 @@
"libvsock",
"librpcbinder_rs",
"librustutils",
+ "libhwcryptohal_common",
],
+ arch: {
+ arm64: {
+ enabled: true,
+ },
+ },
}
rust_library {
@@ -42,18 +50,34 @@
],
}
-rust_binary {
- name: "wait_hw_crypto",
- prefer_rlib: true,
+rust_test {
+ name: "VtsAidlHwCryptoTests",
+ srcs: ["hwcryptokey_tests.rs"],
+ require_root: true,
defaults: [
"hw_crypto_hal_aidl_rust_defaults",
],
- srcs: ["wait_service.rs"],
rustlibs: [
"libhwcryptohal_vts_test",
- "liblogger",
- "liblog_rust",
- "libanyhow",
- "libclap",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
+
+rust_test {
+ name: "VtsAidlHwCryptoOperationsTests",
+ srcs: ["hwcrypto_operations_tests.rs"],
+ require_root: true,
+ defaults: [
+ "hw_crypto_hal_aidl_rust_defaults",
+ ],
+ rustlibs: [
+ "libhwcryptohal_vts_test",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
],
}
diff --git a/security/see/hwcrypto/aidl/vts/functional/AndroidTest.xml b/security/see/hwcrypto/aidl/vts/functional/AndroidTest.xml
deleted file mode 100644
index 73290cf..0000000
--- a/security/see/hwcrypto/aidl/vts/functional/AndroidTest.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
- -->
- <configuration description="Runs {MODULE}">
- <!-- object type="module_controller" class="com.android.tradefed.testtype.suite.module.CommandSuccessModuleController" -->
- <!--Skip the test when trusty VM is not enabled. -->
- <!--option name="run-command" value="getprop trusty.test_vm.nonsecure_vm_ready | grep 1" /-->
- <!--/object-->
- <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
- <!-- Target Preparers - Run Shell Commands -->
- <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
- <option name="cleanup" value="true" />
- <option name="push-file" key="trusty-vm-launcher.sh" value="/data/local/tmp/trusty_test_vm/trusty-vm-launcher.sh" />
- <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" />
- </target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <option name="throw-if-cmd-fail" value="true" />
- <!--Note: the first run-command shall not expect the background command to have started -->
- <option name="run-bg-command" value="sh /data/local/tmp/trusty_test_vm/trusty-vm-launcher.sh" />
- <option name="run-command" value="sh /data/local/tmp/trusty_test_vm/trusty-wait-ready.sh" />
- <option name="run-bg-command" value="start trusty-hwcryptohal" />
- <option name="run-command" value="/data/local/tmp/trusty_test_vm/wait_hw_crypto" />
- <option name="run-command" value="start storageproxyd_test_system" />
- <option name="teardown-command" value="stop storageproxyd_test_system" />
- <option name="teardown-command" value="stop trusty-hwcryptohal" />
- <option name="teardown-command" value="killall storageproxyd_test_system || true" />
- <option name="teardown-command" value="stop trusty-hwcryptohal" />
- <option name="teardown-command" value="killall trusty || true" />
- </target_preparer>
-
- <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
- <option name="test-device-path" value="/data/local/tmp" />
- <option name="module-name" value="VtsAidlHwCryptoConnTest" />
- <!-- 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. -->
- <option name="native-test-flag" value="--test-threads=1" />
- </test>
- </configuration>
diff --git a/security/see/hwcrypto/aidl/vts/functional/connection_test.rs b/security/see/hwcrypto/aidl/vts/functional/connection_test.rs
deleted file mode 100644
index 338923d..0000000
--- a/security/see/hwcrypto/aidl/vts/functional/connection_test.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-//! HwCrypto Connection tests.
-
-#[test]
-fn test_hwcrypto_key_connection() {
- let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey();
- assert!(hw_crypto_key.is_ok(), "Couldn't get back a hwcryptokey binder object");
-}
diff --git a/security/see/hwcrypto/aidl/vts/functional/hwcrypto_operations_tests.rs b/security/see/hwcrypto/aidl/vts/functional/hwcrypto_operations_tests.rs
new file mode 100644
index 0000000..521fb73
--- /dev/null
+++ b/security/see/hwcrypto/aidl/vts/functional/hwcrypto_operations_tests.rs
@@ -0,0 +1,586 @@
+/*
+ * 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.
+ */
+
+//! HwCryptoOperations tests.
+
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::types::{
+ AesKey::AesKey, ExplicitKeyMaterial::ExplicitKeyMaterial, KeyType::KeyType, KeyLifetime::KeyLifetime,
+ KeyUse::KeyUse, OperationData::OperationData, HmacOperationParameters::HmacOperationParameters,
+ SymmetricOperationParameters::SymmetricOperationParameters, SymmetricOperation::SymmetricOperation,
+ HmacKey::HmacKey, CipherModeParameters::CipherModeParameters, AesCipherMode::AesCipherMode,
+ SymmetricCryptoParameters::SymmetricCryptoParameters,
+};
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::{
+ KeyPolicy::KeyPolicy,CryptoOperation::CryptoOperation,CryptoOperationSet::CryptoOperationSet,
+ OperationParameters::OperationParameters, PatternParameters::PatternParameters,
+};
+
+#[test]
+fn test_hwcrypto_key_operations_connection() {
+ let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+ .expect("Couldn't get back a hwcryptokey binder object");
+ let hw_crypto_operations = hw_crypto_key.getHwCryptoOperations();
+ assert!(hw_crypto_operations.is_ok(), "Couldn't get back a hwcrypto operations binder object");
+}
+
+#[test]
+fn test_hwcrypto_key_operations_simple_aes_test() {
+ let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+ .expect("Couldn't get back a hwcryptokey binder object");
+ let hw_crypto_operations = hw_crypto_key
+ .getHwCryptoOperations()
+ .expect("Couldn't get back a hwcryptokey operations binder object");
+ let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+ let policy = KeyPolicy {
+ usage: KeyUse::ENCRYPT_DECRYPT,
+ keyLifetime: KeyLifetime::PORTABLE,
+ keyPermissions: Vec::new(),
+ keyManagementKey: false,
+ keyType: KeyType::AES_128_CBC_PKCS7_PADDING,
+ };
+ let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+ let nonce = [0u8; 16];
+ let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+ nonce: nonce.into(),
+ }));
+ let direction = SymmetricOperation::ENCRYPT;
+ let sym_op_params =
+ SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+ let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(Vec::new());
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+ let input_data = OperationData::DataBuffer("string to be encrypted".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ let mut op_result = hw_crypto_operations
+ .processCommandList(&mut crypto_sets)
+ .expect("couldn't process commands");
+ // Extracting the vector from the command list because of ownership
+ let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+ crypto_sets.remove(0).operations.remove(0)
+ else {
+ panic!("not reachable, we created this object above on the test");
+ };
+ let context = op_result.remove(0).context;
+ // Separating the finish call on a different command set to test the returned context
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(encrypted_data);
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::Finish(None));
+ let crypto_op_set = CryptoOperationSet { context, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+ let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+ crypto_sets.remove(0).operations.remove(0)
+ else {
+ panic!("not reachable, we created this object above on the test");
+ };
+
+ // Decrypting
+ let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+ nonce: nonce.into(),
+ }));
+ let direction = SymmetricOperation::DECRYPT;
+ let sym_op_params = SymmetricOperationParameters { key: Some(key), direction, parameters };
+ let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(Vec::new());
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+ cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
+ cmd_list.push(CryptoOperation::Finish(None));
+ let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+ // Extracting the vector from the command list because of ownership
+ let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
+ crypto_sets.remove(0).operations.remove(0)
+ else {
+ panic!("not reachable, we created this object above on the test");
+ };
+ let decrypted_msg =
+ String::from_utf8(decrypted_data).expect("couldn't decode received message");
+ assert_eq!(decrypted_msg, "string to be encrypted", "couldn't retrieve original message");
+}
+
+#[test]
+fn test_hwcrypto_key_operations_simple_hmac_test() {
+ let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+ .expect("Couldn't get back a hwcryptokey binder object");
+ let hw_crypto_operations = hw_crypto_key
+ .getHwCryptoOperations()
+ .expect("Couldn't get back a hwcryptokey operations binder object");
+ let clear_key = ExplicitKeyMaterial::Hmac(HmacKey::Sha256([0; 32]));
+ let policy = KeyPolicy {
+ usage: KeyUse::SIGN,
+ keyLifetime: KeyLifetime::PORTABLE,
+ keyPermissions: Vec::new(),
+ keyManagementKey: false,
+ keyType: KeyType::HMAC_SHA256,
+ };
+ let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+ let hmac_parameters = HmacOperationParameters { key: Some(key.clone()) };
+ let op_parameters = OperationParameters::Hmac(hmac_parameters);
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(Vec::new());
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::SetOperationParameters(op_parameters));
+ let input_data = OperationData::DataBuffer("text to be mac'ed".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ cmd_list.push(CryptoOperation::Finish(None));
+ let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+ // Extracting the vector from the command list because of ownership
+ let CryptoOperation::DataOutput(OperationData::DataBuffer(mac)) =
+ crypto_sets.remove(0).operations.remove(0)
+ else {
+ panic!("not reachable, we created this object above on the test");
+ };
+
+ //Getting a second mac to compare
+ let hmac_parameters = HmacOperationParameters { key: Some(key) };
+ let op_parameters = OperationParameters::Hmac(hmac_parameters);
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(Vec::new());
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::SetOperationParameters(op_parameters));
+ let input_data = OperationData::DataBuffer("text to be mac'ed".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ cmd_list.push(CryptoOperation::Finish(None));
+ let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+ // Extracting the vector from the command list because of ownership
+ let CryptoOperation::DataOutput(OperationData::DataBuffer(mac2)) =
+ crypto_sets.remove(0).operations.remove(0)
+ else {
+ panic!("not reachable, we created this object above on the test");
+ };
+ assert_eq!(mac, mac2, "got a different mac");
+}
+
+#[test]
+fn test_hwcrypto_key_operations_aes_simple_cbcs_test_non_block_multiple() {
+ let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+ .expect("Couldn't get back a hwcryptokey binder object");
+ let hw_crypto_operations = hw_crypto_key
+ .getHwCryptoOperations()
+ .expect("Couldn't get back a hwcryptokey operations binder object");
+
+ let usage = KeyUse::ENCRYPT_DECRYPT;
+ let key_type = KeyType::AES_128_CBC_NO_PADDING;
+ let policy = KeyPolicy {
+ usage,
+ keyLifetime: KeyLifetime::PORTABLE,
+ keyPermissions: Vec::new(),
+ keyType: key_type,
+ keyManagementKey: false,
+ };
+ let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+ let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+ let nonce = [0u8; 16];
+ let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+ nonce: nonce.into(),
+ }));
+ let direction = SymmetricOperation::ENCRYPT;
+ let sym_op_params =
+ SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+ let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(Vec::new());
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+ cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+ numberBlocksProcess: 1,
+ numberBlocksCopy: 0,
+ }));
+ let input_data =
+ OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ let input_data =
+ OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ let input_data = OperationData::DataBuffer("unencrypted".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ cmd_list.push(CryptoOperation::Finish(None));
+ let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+ let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+ crypto_sets.remove(0).operations.remove(0)
+ else {
+ panic!("not reachable, we created this object above on the test");
+ };
+
+ let clear_encrypted_msg =
+ String::from_utf8(encrypted_data[encrypted_data.len() - "unencrypted".len()..].to_vec())
+ .expect("couldn't decode message");
+ assert_eq!(clear_encrypted_msg, "unencrypted");
+
+ // Decrypting
+ let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+ nonce: nonce.into(),
+ }));
+ let direction = SymmetricOperation::DECRYPT;
+ let sym_op_params =
+ SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+ let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(Vec::new());
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+ cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+ numberBlocksProcess: 1,
+ numberBlocksCopy: 0,
+ }));
+ cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
+ cmd_list.push(CryptoOperation::Finish(None));
+ let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+ let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
+ crypto_sets.remove(0).operations.remove(0)
+ else {
+ panic!("not reachable, we created this object above on the test");
+ };
+ let decrypted_msg =
+ String::from_utf8(decrypted_data).expect("couldn't decode received message");
+ assert_eq!(
+ decrypted_msg,
+ "encryption data.0123456789abcdeffedcba9876543210\
+ 0123456789abcdefunencrypted",
+ "couldn't retrieve original message"
+ );
+}
+
+#[test]
+fn test_hwcrypto_key_operations_aes_simple_all_encrypted_cbcs_test() {
+ let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+ .expect("Couldn't get back a hwcryptokey binder object");
+ let hw_crypto_operations = hw_crypto_key
+ .getHwCryptoOperations()
+ .expect("Couldn't get back a hwcryptokey operations binder object");
+
+ let usage = KeyUse::ENCRYPT_DECRYPT;
+ let key_type = KeyType::AES_128_CBC_NO_PADDING;
+ let policy = KeyPolicy {
+ usage,
+ keyLifetime: KeyLifetime::PORTABLE,
+ keyPermissions: Vec::new(),
+ keyType: key_type,
+ keyManagementKey: false,
+ };
+ let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+ let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+ let nonce = [0u8; 16];
+ let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+ nonce: nonce.into(),
+ }));
+ let direction = SymmetricOperation::ENCRYPT;
+ let sym_op_params =
+ SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+ let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(Vec::new());
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+ cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+ numberBlocksProcess: 1,
+ numberBlocksCopy: 0,
+ }));
+ let input_data =
+ OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ let input_data =
+ OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ cmd_list.push(CryptoOperation::Finish(None));
+ let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+
+ let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+ crypto_sets.remove(0).operations.remove(0)
+ else {
+ panic!("not reachable, we created this object above on the test");
+ };
+
+ // Checking that encrypting with patter 0,0 is equivalent to pattern 1,0
+ let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+ nonce: nonce.into(),
+ }));
+ let direction = SymmetricOperation::ENCRYPT;
+ let sym_op_params =
+ SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+ let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(Vec::new());
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+ cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+ numberBlocksProcess: 0,
+ numberBlocksCopy: 0,
+ }));
+ let input_data =
+ OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ let input_data =
+ OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ cmd_list.push(CryptoOperation::Finish(None));
+ let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+ let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data1)) =
+ crypto_sets.remove(0).operations.remove(0)
+ else {
+ panic!("not reachable, we created this object above on the test");
+ };
+ assert_eq!(encrypted_data, encrypted_data1, "encrypted data should match");
+
+ // Decrypting
+ let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+ nonce: nonce.into(),
+ }));
+ let direction = SymmetricOperation::DECRYPT;
+ let sym_op_params =
+ SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+ let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(Vec::new());
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+ cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
+ cmd_list.push(CryptoOperation::Finish(None));
+ let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+
+ let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
+ crypto_sets.remove(0).operations.remove(0)
+ else {
+ panic!("not reachable, we created this object above on the test");
+ };
+ let decrypted_msg =
+ String::from_utf8(decrypted_data).expect("couldn't decode received message");
+ assert_eq!(
+ decrypted_msg,
+ "encryption data.0123456789abcdeffedcba9876543210\
+ 0123456789abcdef",
+ "couldn't retrieve original message"
+ );
+}
+
+#[test]
+fn check_cbcs_wrong_key_types() {
+ let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+ .expect("Couldn't get back a hwcryptokey binder object");
+ let hw_crypto_operations = hw_crypto_key
+ .getHwCryptoOperations()
+ .expect("Couldn't get back a hwcryptokey operations binder object");
+
+ let usage = KeyUse::ENCRYPT_DECRYPT;
+ let key_type = KeyType::AES_128_CBC_PKCS7_PADDING;
+ let policy = KeyPolicy {
+ usage,
+ keyLifetime: KeyLifetime::PORTABLE,
+ keyPermissions: Vec::new(),
+ keyType: key_type,
+ keyManagementKey: false,
+ };
+ let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+ let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+ let nonce = [0u8; 16];
+ let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+ nonce: nonce.into(),
+ }));
+ let direction = SymmetricOperation::ENCRYPT;
+ let sym_op_params = SymmetricOperationParameters { key: Some(key), direction, parameters };
+ let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(Vec::new());
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+ cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+ numberBlocksProcess: 1,
+ numberBlocksCopy: 9,
+ }));
+ let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ let process_result = hw_crypto_operations.processCommandList(&mut crypto_sets);
+ assert!(process_result.is_err(), "Should not be able to use cbcs mode with this key type");
+
+ let policy = KeyPolicy {
+ usage,
+ keyLifetime: KeyLifetime::PORTABLE,
+ keyPermissions: Vec::new(),
+ keyType: KeyType::AES_256_CBC_NO_PADDING,
+ keyManagementKey: false,
+ };
+ let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes256([0; 32]));
+ let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+ let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+ nonce: nonce.into(),
+ }));
+ let sym_op_params = SymmetricOperationParameters { key: Some(key), direction, parameters };
+ let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(Vec::new());
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+ cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+ numberBlocksProcess: 1,
+ numberBlocksCopy: 9,
+ }));
+ let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ let process_result = hw_crypto_operations.processCommandList(&mut crypto_sets);
+
+ assert!(process_result.is_err(), "Should not be able to use cbcs mode with this key type");
+}
+
+#[test]
+fn aes_simple_cbcs_test() {
+ let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+ .expect("Couldn't get back a hwcryptokey binder object");
+ let hw_crypto_operations = hw_crypto_key
+ .getHwCryptoOperations()
+ .expect("Couldn't get back a hwcryptokey operations binder object");
+
+ let usage = KeyUse::ENCRYPT_DECRYPT;
+ let key_type = KeyType::AES_128_CBC_NO_PADDING;
+ let policy = KeyPolicy {
+ usage,
+ keyLifetime: KeyLifetime::PORTABLE,
+ keyPermissions: Vec::new(),
+ keyType: key_type,
+ keyManagementKey: false,
+ };
+ let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+ let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+ let nonce = [0u8; 16];
+ let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+ nonce: nonce.into(),
+ }));
+ let direction = SymmetricOperation::ENCRYPT;
+ let sym_op_params =
+ SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+ let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(Vec::new());
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+ cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+ numberBlocksProcess: 1,
+ numberBlocksCopy: 9,
+ }));
+ let input_data =
+ OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ let input_data =
+ OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ let input_data =
+ OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ let input_data =
+ OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ let input_data = OperationData::DataBuffer(
+ "fedcba98765432100123456789abcdefProtectedSection".as_bytes().to_vec(),
+ );
+ cmd_list.push(CryptoOperation::DataInput(input_data));
+ cmd_list.push(CryptoOperation::Finish(None));
+ let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+
+ let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+ crypto_sets.remove(0).operations.remove(0)
+ else {
+ panic!("not reachable, we created this object above on the test");
+ };
+ let clear_encrypted_msg =
+ String::from_utf8(encrypted_data[16..encrypted_data.len() - 16].to_vec())
+ .expect("couldn't decode received message");
+ assert_eq!(
+ clear_encrypted_msg,
+ "0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210\
+ 0123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdef",
+ "couldn't retrieve clear portion"
+ );
+
+ // Decrypting
+ let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+ nonce: nonce.into(),
+ }));
+ let direction = SymmetricOperation::DECRYPT;
+ let sym_op_params =
+ SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+ let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+ let mut cmd_list = Vec::<CryptoOperation>::new();
+ let data_output = OperationData::DataBuffer(Vec::new());
+ cmd_list.push(CryptoOperation::DataOutput(data_output));
+ cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+ cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+ numberBlocksProcess: 1,
+ numberBlocksCopy: 9,
+ }));
+ cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
+ cmd_list.push(CryptoOperation::Finish(None));
+ let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+ let mut crypto_sets = Vec::new();
+ crypto_sets.push(crypto_op_set);
+ hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+
+ let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
+ crypto_sets.remove(0).operations.remove(0)
+ else {
+ panic!("not reachable, we created this object above on the test");
+ };
+ let decrypted_msg =
+ String::from_utf8(decrypted_data).expect("couldn't decode received message");
+ assert_eq!(
+ decrypted_msg,
+ "encryption data.0123456789abcdeffedcba9876543210\
+ 0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210\
+ 0123456789abcdeffedcba98765432100123456789abcdefProtectedSection",
+ "couldn't retrieve original message"
+ );
+}
diff --git a/security/see/hwcrypto/aidl/vts/functional/hwcryptokey_tests.rs b/security/see/hwcrypto/aidl/vts/functional/hwcryptokey_tests.rs
new file mode 100644
index 0000000..fcce839
--- /dev/null
+++ b/security/see/hwcrypto/aidl/vts/functional/hwcryptokey_tests.rs
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 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.
+ */
+
+//! HwCryptoKey tests.
+
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::IHwCryptoKey::{
+ DerivedKeyParameters::DerivedKeyParameters, DerivedKeyPolicy::DerivedKeyPolicy,
+ DiceBoundDerivationKey::DiceBoundDerivationKey, KeySlot::KeySlot,
+};
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::types::{
+ HalErrorCode, AesKey::AesKey, ExplicitKeyMaterial::ExplicitKeyMaterial, KeyType::KeyType, KeyLifetime::KeyLifetime, KeyUse::KeyUse,
+ HmacKey::HmacKey, ProtectionId::ProtectionId,
+};
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::KeyPolicy::KeyPolicy;
+use hwcryptohal_common;
+
+#[test]
+fn test_hwcrypto_key_connection() {
+ let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey();
+ assert!(hw_crypto_key.is_ok(), "Couldn't get back a hwcryptokey binder object");
+}
+
+#[test]
+fn test_hwcrypto_key_get_current_dice_policy() {
+ let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+ .expect("Couldn't get back a hwcryptokey binder object");
+ let dice_policy = hw_crypto_key.getCurrentDicePolicy().expect("Couldn't get dice policy back");
+ assert!(!dice_policy.is_empty(), "received empty dice policy");
+}
+
+#[test]
+fn test_hwcrypto_get_keyslot_data() {
+ let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+ .expect("Couldn't get back a hwcryptokey binder object");
+ let key = hw_crypto_key.getKeyslotData(KeySlot::KEYMINT_SHARED_HMAC_KEY);
+ assert_eq!(
+ key.err()
+ .expect("should not be able to access this keylost from the host")
+ .service_specific_error(),
+ HalErrorCode::UNAUTHORIZED,
+ "wrong error type received"
+ );
+}
+
+#[test]
+fn test_hwcrypto_import_clear_key() {
+ let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+ .expect("Couldn't get back a hwcryptokey binder object");
+ let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+ let mut policy = KeyPolicy {
+ usage: KeyUse::ENCRYPT_DECRYPT,
+ keyLifetime: KeyLifetime::PORTABLE,
+ keyPermissions: Vec::new(),
+ keyManagementKey: false,
+ keyType: KeyType::AES_128_GCM,
+ };
+ let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import key");
+ assert!(key.getPublicKey().is_err(), "symmetric keys don't have a public key");
+ let imported_policy = key.getKeyPolicy().expect("couldn't get key policy");
+ let serialized_policy =
+ hwcryptohal_common::key_policy_to_cbor(&policy).expect("couldn't serialize policy");
+ let serialized_impoorted_policy = hwcryptohal_common::key_policy_to_cbor(&imported_policy)
+ .expect("couldn't serialize policy");
+ assert_eq!(serialized_policy, serialized_impoorted_policy, "policies should match");
+ policy.keyLifetime = KeyLifetime::EPHEMERAL;
+ let key = hw_crypto_key.importClearKey(&clear_key, &policy);
+ assert!(key.is_err(), "imported keys should be of type PORTABLE");
+ policy.keyLifetime = KeyLifetime::HARDWARE;
+ let key = hw_crypto_key.importClearKey(&clear_key, &policy);
+ assert!(key.is_err(), "imported keys should be of type PORTABLE");
+}
+
+#[test]
+fn test_hwcrypto_token_export_import() {
+ // This test is not representative of the complete flow because here the exporter and importer
+ // are the same client, which is not something we would usually do
+ let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+ .expect("Couldn't get back a hwcryptokey binder object");
+ let clear_key = ExplicitKeyMaterial::Hmac(HmacKey::Sha256([0; 32]));
+ let policy = KeyPolicy {
+ usage: KeyUse::DERIVE,
+ keyLifetime: KeyLifetime::PORTABLE,
+ keyPermissions: Vec::new(),
+ keyManagementKey: false,
+ keyType: KeyType::HMAC_SHA256,
+ };
+ let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+ let dice_policy = hw_crypto_key.getCurrentDicePolicy().expect("Couldn't get dice policy back");
+ let token =
+ key.getShareableToken(dice_policy.as_slice()).expect("Couldn't get shareable token");
+ let imported_key = hw_crypto_key
+ .keyTokenImport(&token, dice_policy.as_slice());
+ assert!(imported_key.is_ok(), "Couldn't import shareable token");
+ // TODO: Use operations to verify that the keys match
+}
+
+#[test]
+fn test_hwcrypto_android_invalid_calls() {
+ let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+ .expect("Couldn't get back a hwcryptokey binder object");
+ let clear_key = ExplicitKeyMaterial::Hmac(HmacKey::Sha256([0; 32]));
+ let policy = KeyPolicy {
+ usage: KeyUse::DERIVE,
+ keyLifetime: KeyLifetime::PORTABLE,
+ keyPermissions: Vec::new(),
+ keyManagementKey: false,
+ keyType: KeyType::HMAC_SHA256,
+ };
+ let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+ let protections = Vec::new();
+ let res = key.setProtectionId(ProtectionId::WIDEVINE_OUTPUT_BUFFER, &protections);
+ assert_eq!(
+ res.err()
+ .expect("should not be call this function from the host")
+ .service_specific_error(),
+ HalErrorCode::UNAUTHORIZED,
+ "wrong error type received"
+ );
+ let derivation_key = DiceBoundDerivationKey::OpaqueKey(Some(key));
+ let res = hw_crypto_key.deriveCurrentDicePolicyBoundKey(&derivation_key);
+ assert_eq!(
+ res.err()
+ .expect("should not be call this function from the host")
+ .service_specific_error(),
+ HalErrorCode::UNAUTHORIZED,
+ "wrong error type received"
+ );
+ let fake_policy = Vec::new();
+ let res = hw_crypto_key.deriveDicePolicyBoundKey(&derivation_key, &fake_policy);
+ assert_eq!(
+ res.err()
+ .expect("should not be call this function from the host")
+ .service_specific_error(),
+ HalErrorCode::UNAUTHORIZED,
+ "wrong error type received"
+ );
+ let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+ let derived_policy = DerivedKeyPolicy::OpaqueKey(Vec::new());
+ let derived_parameters = DerivedKeyParameters {
+ derivationKey: Some(key),
+ keyPolicy: derived_policy,
+ context: Vec::new(),
+ };
+ let res = hw_crypto_key.deriveKey(&derived_parameters);
+ assert_eq!(
+ res.err()
+ .expect("should not be call this function from the host")
+ .service_specific_error(),
+ HalErrorCode::UNAUTHORIZED,
+ "wrong error type received"
+ );
+}
diff --git a/security/see/hwcrypto/aidl/vts/functional/lib.rs b/security/see/hwcrypto/aidl/vts/functional/lib.rs
index e14ac83..465dde7 100644
--- a/security/see/hwcrypto/aidl/vts/functional/lib.rs
+++ b/security/see/hwcrypto/aidl/vts/functional/lib.rs
@@ -17,41 +17,12 @@
//! VTS test library for HwCrypto functionality.
//! It provides the base clases necessaries to write HwCrypto VTS tests
-use anyhow::{Context, Result};
-use binder::{ExceptionCode, FromIBinder, IntoBinderResult, ParcelFileDescriptor};
-use rpcbinder::RpcSession;
-use vsock::VsockStream;
-use std::os::fd::{FromRawFd, IntoRawFd};
-use std::fs::File;
-use std::io::Read;
-use rustutils::system_properties;
+use anyhow::Result;
+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;
-const HWCRYPTO_SERVICE_PORT: u32 = 4;
-
-/// Local function to connect to service
-pub fn connect_service<T: FromIBinder + ?Sized>(
- cid: u32,
- port: u32,
-) -> Result<binder::Strong<T>, binder::StatusCode> {
- RpcSession::new().setup_preconnected_client(|| {
- let mut stream = VsockStream::connect_with_cid_port(cid, port).ok()?;
- let mut buffer = [0];
- let _ = stream.read(&mut buffer);
- // SAFETY: ownership is transferred from stream to f
- let f = unsafe { File::from_raw_fd(stream.into_raw_fd()) };
- Some(ParcelFileDescriptor::new(f).into_raw_fd())
- })
-}
-
-/// Get a HwCryptoKey binder service object
+/// Get a HwCryptoKey binder service object using the service manager
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")
- .or_binder_exception(ExceptionCode::ILLEGAL_STATE)?
- .ok_or(ExceptionCode::ILLEGAL_STATE)?
- .parse::<u32>()
- .context("couldn't parse vm cid")
- .or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT)?;
- Ok(connect_service(cid, HWCRYPTO_SERVICE_PORT)?)
+ 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..7d3ade7
--- /dev/null
+++ b/security/see/hwcrypto/default/hwcryptokeyimpl.h
@@ -0,0 +1,119 @@
+/*
+ * 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) override;
+
+ ndk::ScopedAStatus deriveDicePolicyBoundKey(
+ const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& derivationKey,
+ const ::std::vector<uint8_t>& dicePolicyForKeyVersion,
+ ndk_hwcrypto::IHwCryptoKey::DiceBoundKeyResult* aidl_return) override;
+ ndk::ScopedAStatus deriveKey(const ndk_hwcrypto::IHwCryptoKey::DerivedKeyParameters& parameters,
+ ndk_hwcrypto::IHwCryptoKey::DerivedKey* aidl_return) override;
+
+ ndk::ScopedAStatus getHwCryptoOperations(
+ std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations>* aidl_return) override;
+
+ ndk::ScopedAStatus importClearKey(
+ const ndk_hwcrypto::types::ExplicitKeyMaterial& keyMaterial,
+ const ndk_hwcrypto::KeyPolicy& newKeyPolicy,
+ std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) override;
+
+ ndk::ScopedAStatus getCurrentDicePolicy(std::vector<uint8_t>* aidl_return) override;
+
+ ndk::ScopedAStatus keyTokenImport(
+ const ndk_hwcrypto::types::OpaqueKeyToken& requestedKey,
+ const ::std::vector<uint8_t>& sealingDicePolicy,
+ std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) override;
+
+ ndk::ScopedAStatus getKeyslotData(
+ ndk_hwcrypto::IHwCryptoKey::KeySlot slotId,
+ std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) override;
+};
+
+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;
+ policy.keyPermissions.reserve(policyToConvert.keyPermissions.size());
+ for (auto permission : policyToConvert.keyPermissions) {
+ policy.keyPermissions.push_back(
+ std::move(static_cast<decltype(policy.keyPermissions)::value_type>(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..5babc23
--- /dev/null
+++ b/security/see/hwcrypto/default/hwcryptolib.cpp
@@ -0,0 +1,818 @@
+/*
+ * 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;
+ std::weak_ptr<ndk_hwcrypto::ICryptoOperationContext> self;
+
+ public:
+ HwCryptoOperationContextNdk(sp<cpp_hwcrypto::ICryptoOperationContext> operations)
+ : mContext(std::move(operations)) {}
+
+ ~HwCryptoOperationContextNdk() { contextMapping.erase(self); }
+
+ 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;
+ }
+ contextNdk->self = contextNdk;
+ return contextNdk;
+ }
+};
+
+std::optional<cpp_hwcrypto::types::OperationData> convertOperationData(
+ const ndk_hwcrypto::types::OperationData& ndkOperationData) {
+ cpp_hwcrypto::types::OperationData cppOperationData = cpp_hwcrypto::types::OperationData();
+ 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:
+ LOG(ERROR) << "received unknown operation data type";
+ return std::nullopt;
+ }
+ return cppOperationData;
+}
+
+std::optional<cpp_hwcrypto::PatternParameters> convertPatternParameters(
+ const ndk_hwcrypto::PatternParameters& ndkpatternParameters) {
+ int64_t numberBlocksProcess = ndkpatternParameters.numberBlocksProcess;
+ int64_t numberBlocksCopy = ndkpatternParameters.numberBlocksCopy;
+ if ((numberBlocksProcess < 0) || (numberBlocksCopy < 0)) {
+ LOG(ERROR) << "received invalid pattern parameters";
+ return std::nullopt;
+ }
+ cpp_hwcrypto::PatternParameters patternParameters = cpp_hwcrypto::PatternParameters();
+ patternParameters.numberBlocksProcess = numberBlocksProcess;
+ patternParameters.numberBlocksCopy = numberBlocksCopy;
+ return patternParameters;
+}
+
+std::optional<cpp_hwcrypto::types::SymmetricOperation> convertSymmetricOperation(
+ const ndk_hwcrypto::types::SymmetricOperation& ndkSymmetricOperation) {
+ cpp_hwcrypto::types::SymmetricOperation symmetricOperation =
+ cpp_hwcrypto::types::SymmetricOperation();
+ switch (ndkSymmetricOperation) {
+ case ndk_hwcrypto::types::SymmetricOperation::ENCRYPT:
+ symmetricOperation = cpp_hwcrypto::types::SymmetricOperation::ENCRYPT;
+ break;
+ case ndk_hwcrypto::types::SymmetricOperation::DECRYPT:
+ symmetricOperation = cpp_hwcrypto::types::SymmetricOperation::DECRYPT;
+ break;
+ default:
+ LOG(ERROR) << "invalid symmetric operation type";
+ return std::nullopt;
+ }
+ return symmetricOperation;
+}
+
+cpp_hwcrypto::types::CipherModeParameters convertSymmetricModeParameters(
+ const ndk_hwcrypto::types::CipherModeParameters& ndkcipherModeParameters) {
+ cpp_hwcrypto::types::CipherModeParameters cipherModeParameters =
+ cpp_hwcrypto::types::CipherModeParameters();
+ cipherModeParameters.nonce = ndkcipherModeParameters.nonce;
+ return cipherModeParameters;
+}
+
+cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters convertSymmetricModeParameters(
+ const ndk_hwcrypto::types::AesGcmMode::AesGcmModeParameters& ndkgcmModeParameters) {
+ cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters gcmModeParameters =
+ cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters();
+ gcmModeParameters.nonce = ndkgcmModeParameters.nonce;
+ return gcmModeParameters;
+}
+
+std::optional<cpp_hwcrypto::OperationParameters> convertOperationParameters(
+ const ndk_hwcrypto::OperationParameters& ndkOperationParameters) {
+ cpp_hwcrypto::OperationParameters operationParameters = cpp_hwcrypto::OperationParameters();
+ sp<cpp_hwcrypto::IOpaqueKey> opaqueKey;
+ cpp_hwcrypto::types::HmacOperationParameters hmacParameters =
+ cpp_hwcrypto::types::HmacOperationParameters();
+ std::optional<cpp_hwcrypto::types::SymmetricOperation> cppSymmetricOperation;
+ cpp_hwcrypto::types::CipherModeParameters cipherModeParameters;
+ cpp_hwcrypto::types::AesCipherMode cppAesCipherMode = cpp_hwcrypto::types::AesCipherMode();
+ cpp_hwcrypto::types::SymmetricOperationParameters cppSymmetricOperationParameters =
+ cpp_hwcrypto::types::SymmetricOperationParameters();
+ cpp_hwcrypto::types::SymmetricAuthOperationParameters cppSymmetricAuthOperationParameters =
+ cpp_hwcrypto::types::SymmetricAuthOperationParameters();
+ cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters cppAesGcmModeParameters =
+ cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters();
+ cpp_hwcrypto::types::AesGcmMode cppAesGcmMode = cpp_hwcrypto::types::AesGcmMode();
+ switch (ndkOperationParameters.getTag()) {
+ case ndk_hwcrypto::OperationParameters::symmetricAuthCrypto:
+ opaqueKey = retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey,
+ keyMapping>(
+ ndkOperationParameters
+ .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
+ .key);
+ if (!opaqueKey) {
+ LOG(ERROR) << "couldn't get aes key";
+ return std::nullopt;
+ }
+ cppSymmetricAuthOperationParameters.key = std::move(opaqueKey);
+ cppSymmetricOperation = convertSymmetricOperation(
+ ndkOperationParameters
+ .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
+ .direction);
+ if (!cppSymmetricOperation.has_value()) {
+ LOG(ERROR) << "couldn't get aes direction";
+ return std::nullopt;
+ }
+ cppSymmetricAuthOperationParameters.direction =
+ std::move(cppSymmetricOperation.value());
+ switch (ndkOperationParameters
+ .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
+ .parameters.getTag()) {
+ case ndk_hwcrypto::types::SymmetricAuthCryptoParameters::aes:
+ switch (ndkOperationParameters
+ .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
+ .parameters
+ .get<ndk_hwcrypto::types::SymmetricAuthCryptoParameters::aes>()
+ .getTag()) {
+ case ndk_hwcrypto::types::AesGcmMode::gcmTag16:
+ cppAesGcmModeParameters = convertSymmetricModeParameters(
+ ndkOperationParameters
+ .get<ndk_hwcrypto::OperationParameters::
+ symmetricAuthCrypto>()
+ .parameters
+ .get<ndk_hwcrypto::types::
+ SymmetricAuthCryptoParameters::aes>()
+ .get<ndk_hwcrypto::types::AesGcmMode::gcmTag16>());
+ cppAesGcmMode.set<cpp_hwcrypto::types::AesGcmMode::gcmTag16>(
+ std::move(cppAesGcmModeParameters));
+ cppSymmetricAuthOperationParameters.parameters
+ .set<cpp_hwcrypto::types::SymmetricAuthCryptoParameters::aes>(
+ std::move(cppAesGcmMode));
+ break;
+ default:
+ LOG(ERROR) << "received invalid aes gcm parameters";
+ return std::nullopt;
+ }
+ break;
+ default:
+ LOG(ERROR) << "received invalid symmetric auth crypto parameters";
+ return std::nullopt;
+ }
+ operationParameters.set<cpp_hwcrypto::OperationParameters::symmetricAuthCrypto>(
+ std::move(cppSymmetricAuthOperationParameters));
+ break;
+ case ndk_hwcrypto::OperationParameters::symmetricCrypto:
+ opaqueKey = retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey,
+ keyMapping>(
+ ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
+ .key);
+ if (!opaqueKey) {
+ LOG(ERROR) << "couldn't get aes key";
+ return std::nullopt;
+ }
+ cppSymmetricOperationParameters.key = std::move(opaqueKey);
+ cppSymmetricOperation = convertSymmetricOperation(
+ ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
+ .direction);
+ if (!cppSymmetricOperation.has_value()) {
+ LOG(ERROR) << "couldn't get aes direction";
+ return std::nullopt;
+ }
+ cppSymmetricOperationParameters.direction = std::move(cppSymmetricOperation.value());
+ switch (ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
+ .parameters.getTag()) {
+ case ndk_hwcrypto::types::SymmetricCryptoParameters::aes:
+ switch (ndkOperationParameters
+ .get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
+ .parameters
+ .get<ndk_hwcrypto::types::SymmetricCryptoParameters::aes>()
+ .getTag()) {
+ case ndk_hwcrypto::types::AesCipherMode::cbc:
+ cipherModeParameters = convertSymmetricModeParameters(
+ ndkOperationParameters
+ .get<ndk_hwcrypto::OperationParameters::
+ symmetricCrypto>()
+ .parameters
+ .get<ndk_hwcrypto::types::SymmetricCryptoParameters::
+ aes>()
+ .get<ndk_hwcrypto::types::AesCipherMode::cbc>());
+ cppAesCipherMode.set<cpp_hwcrypto::types::AesCipherMode::cbc>(
+ std::move(cipherModeParameters));
+ cppSymmetricOperationParameters.parameters
+ .set<cpp_hwcrypto::types::SymmetricCryptoParameters::aes>(
+ std::move(cppAesCipherMode));
+ break;
+ case ndk_hwcrypto::types::AesCipherMode::ctr:
+ cipherModeParameters = convertSymmetricModeParameters(
+ ndkOperationParameters
+ .get<ndk_hwcrypto::OperationParameters::
+ symmetricCrypto>()
+ .parameters
+ .get<ndk_hwcrypto::types::SymmetricCryptoParameters::
+ aes>()
+ .get<ndk_hwcrypto::types::AesCipherMode::ctr>());
+ cppAesCipherMode.set<cpp_hwcrypto::types::AesCipherMode::ctr>(
+ std::move(cipherModeParameters));
+ cppSymmetricOperationParameters.parameters
+ .set<cpp_hwcrypto::types::SymmetricCryptoParameters::aes>(
+ std::move(cppAesCipherMode));
+ break;
+ default:
+ LOG(ERROR) << "received invalid aes parameters";
+ return std::nullopt;
+ }
+ break;
+ default:
+ LOG(ERROR) << "received invalid symmetric crypto parameters";
+ return std::nullopt;
+ }
+ operationParameters.set<cpp_hwcrypto::OperationParameters::symmetricCrypto>(
+ std::move(cppSymmetricOperationParameters));
+ break;
+ case ndk_hwcrypto::OperationParameters::hmac:
+ opaqueKey = retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey,
+ keyMapping>(
+ ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::hmac>().key);
+ if (!opaqueKey) {
+ LOG(ERROR) << "couldn't get hmac key";
+ return std::nullopt;
+ }
+ hmacParameters.key = opaqueKey;
+ operationParameters.set<cpp_hwcrypto::OperationParameters::hmac>(
+ std::move(hmacParameters));
+ break;
+ default:
+ LOG(ERROR) << "received invalid operation parameters";
+ return std::nullopt;
+ }
+ return operationParameters;
+}
+
+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) {
+ Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+ if (operationSets == nullptr) {
+ LOG(ERROR) << "received a null operation set";
+ return convertStatus(status);
+ }
+ if (aidl_return == nullptr) {
+ LOG(ERROR) << "received a null CryptoOperationResult set";
+ return convertStatus(status);
+ }
+ std::vector<cpp_hwcrypto::CryptoOperationResult> binderResult;
+ std::vector<cpp_hwcrypto::CryptoOperationSet> cppOperationSets;
+ for (ndk_hwcrypto::CryptoOperationSet& operationSet : *operationSets) {
+ cpp_hwcrypto::CryptoOperationSet cppSingleOperation =
+ cpp_hwcrypto::CryptoOperationSet();
+ cppSingleOperation.context =
+ retrieveCppBinder<cpp_hwcrypto::ICryptoOperationContext,
+ ndk_hwcrypto::ICryptoOperationContext, contextMapping>(
+ operationSet.context);
+ for (ndk_hwcrypto::CryptoOperation& operation : operationSet.operations) {
+ cpp_hwcrypto::CryptoOperation cppOperation;
+ cpp_hwcrypto::types::Void voidObj;
+ std::optional<cpp_hwcrypto::types::OperationData> cppOperationData;
+ std::optional<cpp_hwcrypto::PatternParameters> cppPatternParameters;
+ std::optional<cpp_hwcrypto::OperationParameters> cppOperationParameters;
+ switch (operation.getTag()) {
+ case ndk_hwcrypto::CryptoOperation::setMemoryBuffer:
+ // TODO: finish this case
+ exit(1);
+ break;
+ case ndk_hwcrypto::CryptoOperation::setOperationParameters:
+ cppOperationParameters = convertOperationParameters(
+ operation.get<
+ ndk_hwcrypto::CryptoOperation::setOperationParameters>());
+ if (cppOperationParameters.has_value()) {
+ cppOperation.set<cpp_hwcrypto::CryptoOperation::setOperationParameters>(
+ std::move(cppOperationParameters.value()));
+ } else {
+ LOG(ERROR) << "couldn't convert operation parameters";
+ return convertStatus(status);
+ }
+ break;
+ case ndk_hwcrypto::CryptoOperation::setPattern:
+ cppPatternParameters = convertPatternParameters(
+ operation.get<ndk_hwcrypto::CryptoOperation::setPattern>());
+ if (cppPatternParameters.has_value()) {
+ cppOperation.set<cpp_hwcrypto::CryptoOperation::setPattern>(
+ std::move(cppPatternParameters.value()));
+ } else {
+ LOG(ERROR) << "couldn't convert pattern parameters";
+ return convertStatus(status);
+ }
+ break;
+ case ndk_hwcrypto::CryptoOperation::copyData:
+ cppOperationData = convertOperationData(
+ operation.get<ndk_hwcrypto::CryptoOperation::copyData>());
+ if (cppOperationData.has_value()) {
+ cppOperation.set<cpp_hwcrypto::CryptoOperation::copyData>(
+ std::move(cppOperationData.value()));
+ } else {
+ LOG(ERROR) << "couldn't convert CryptoOperation::copyData";
+ return convertStatus(status);
+ }
+ break;
+ case ndk_hwcrypto::CryptoOperation::aadInput:
+ cppOperationData = convertOperationData(
+ operation.get<ndk_hwcrypto::CryptoOperation::aadInput>());
+ if (cppOperationData.has_value()) {
+ cppOperation.set<cpp_hwcrypto::CryptoOperation::aadInput>(
+ std::move(cppOperationData.value()));
+ } else {
+ LOG(ERROR) << "couldn't convert CryptoOperation::aadInput";
+ return convertStatus(status);
+ }
+ break;
+ case ndk_hwcrypto::CryptoOperation::dataInput:
+ cppOperationData = convertOperationData(
+ operation.get<ndk_hwcrypto::CryptoOperation::dataInput>());
+ if (cppOperationData.has_value()) {
+ cppOperation.set<cpp_hwcrypto::CryptoOperation::dataInput>(
+ std::move(cppOperationData.value()));
+ } else {
+ LOG(ERROR) << "couldn't convert CryptoOperation::dataInput";
+ return convertStatus(status);
+ }
+ break;
+ case ndk_hwcrypto::CryptoOperation::dataOutput:
+ cppOperationData = convertOperationData(
+ operation.get<ndk_hwcrypto::CryptoOperation::dataOutput>());
+ if (cppOperationData.has_value()) {
+ cppOperation.set<cpp_hwcrypto::CryptoOperation::dataOutput>(
+ std::move(cppOperationData.value()));
+ } else {
+ LOG(ERROR) << "couldn't convert CryptoOperation::dataOutput";
+ return convertStatus(status);
+ }
+ break;
+ case ndk_hwcrypto::CryptoOperation::destroyContext:
+ cppOperation.set<cpp_hwcrypto::CryptoOperation::destroyContext>(
+ std::move(voidObj));
+ break;
+ case ndk_hwcrypto::CryptoOperation::finish:
+ cppOperation.set<cpp_hwcrypto::CryptoOperation::finish>(std::move(voidObj));
+ break;
+ default:
+ // This shouldn't happen
+ LOG(ERROR) << "received unknown crypto operation";
+ return convertStatus(status);
+ }
+ cppSingleOperation.operations.push_back(std::move(cppOperation));
+ }
+ cppOperationSets.push_back(std::move(cppSingleOperation));
+ }
+ status = mHwCryptoOperations->processCommandList(&cppOperationSets, &binderResult);
+ if (status.isOk()) {
+ *aidl_return = std::vector<ndk_hwcrypto::CryptoOperationResult>();
+ for (cpp_hwcrypto::CryptoOperationResult& result : binderResult) {
+ ndk_hwcrypto::CryptoOperationResult ndkResult =
+ ndk_hwcrypto::CryptoOperationResult();
+ if (result.context != nullptr) {
+ insertBinderMapping<cpp_hwcrypto::ICryptoOperationContext,
+ ndk_hwcrypto::ICryptoOperationContext,
+ HwCryptoOperationContextNdk, contextMapping>(
+ result.context, &ndkResult.context);
+ } else {
+ ndkResult.context = nullptr;
+ }
+ aidl_return->push_back(std::move(ndkResult));
+ }
+ } else {
+ // No reason to copy back the data output vectors if this failed
+ LOG(ERROR) << "couldn't process command list";
+ return convertStatus(status);
+ }
+ // We need to copy the vectors from the cpp operations back to the ndk one
+ if (cppOperationSets.size() != operationSets->size()) {
+ LOG(ERROR) << "ndk and cpp operation sets had a different number of elements";
+ return convertStatus(Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
+ }
+ for (unsigned setIdx = 0; setIdx < cppOperationSets.size(); ++setIdx) {
+ if (cppOperationSets[setIdx].operations.size() !=
+ (*operationSets)[setIdx].operations.size()) {
+ LOG(ERROR) << "ndk and cpp operations on set " << setIdx
+ << " had a different number of elements";
+ return convertStatus(Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
+ }
+ for (unsigned operationIdx = 0;
+ operationIdx < cppOperationSets[setIdx].operations.size(); ++operationIdx) {
+ if (cppOperationSets[setIdx].operations[operationIdx].getTag() ==
+ cpp_hwcrypto::CryptoOperation::dataOutput) {
+ if ((*operationSets)[setIdx].operations[operationIdx].getTag() !=
+ ndk_hwcrypto::CryptoOperation::dataOutput) {
+ LOG(ERROR)
+ << "ndk and cpp operations on set " << setIdx << " and operation "
+ << operationIdx << " had a different operation type";
+ return convertStatus(
+ Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
+ }
+ if (cppOperationSets[setIdx]
+ .operations[operationIdx]
+ .get<cpp_hwcrypto::CryptoOperation::dataOutput>()
+ .getTag() == cpp_hwcrypto::types::OperationData::dataBuffer) {
+ // This is the only case on which we need to move the data backto the
+ // original array
+ if ((*operationSets)[setIdx]
+ .operations[operationIdx]
+ .get<ndk_hwcrypto::CryptoOperation::dataOutput>()
+ .getTag() != ndk_hwcrypto::types::OperationData::dataBuffer) {
+ LOG(ERROR) << "ndk and cpp operations on set " << setIdx
+ << " and operation " << operationIdx
+ << " had a different operation data output type";
+ return convertStatus(
+ Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
+ }
+ (*operationSets)[setIdx]
+ .operations[operationIdx]
+ .get<ndk_hwcrypto::CryptoOperation::dataOutput>()
+ .set<ndk_hwcrypto::types::OperationData::dataBuffer>(
+ cppOperationSets[setIdx]
+ .operations[operationIdx]
+ .get<cpp_hwcrypto::CryptoOperation::dataOutput>()
+ .get<cpp_hwcrypto::types::OperationData::
+ dataBuffer>());
+ }
+ }
+ }
+ }
+ return convertStatus(status);
+ }
+};
+
+class OpaqueKeyNdk : public ndk_hwcrypto::BnOpaqueKey {
+ private:
+ sp<cpp_hwcrypto::IOpaqueKey> mOpaqueKey;
+ std::weak_ptr<ndk_hwcrypto::IOpaqueKey> self;
+
+ public:
+ OpaqueKeyNdk(sp<cpp_hwcrypto::IOpaqueKey> opaqueKey) : mOpaqueKey(std::move(opaqueKey)) {}
+
+ ~OpaqueKeyNdk() { keyMapping.erase(self); }
+
+ 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;
+ }
+ opaqueKeyNdk->self = opaqueKeyNdk;
+ 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::fromServiceSpecificErrorWithMessage(
+ ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED,
+ "android is not authorized to call setProtectionId");
+ }
+};
+
+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 ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED,
+ "android is not authorized to call deriveCurrentDicePolicyBoundKey");
+}
+
+ndk::ScopedAStatus HwCryptoKey::deriveDicePolicyBoundKey(
+ const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& /*derivationKey*/,
+ const ::std::vector<uint8_t>& /*dicePolicyForKeyVersion*/,
+ ndk_hwcrypto::IHwCryptoKey::DiceBoundKeyResult* /*aidl_return*/) {
+ return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED,
+ "android is not authorized to call deriveDicePolicyBoundKey");
+}
+
+ndk::ScopedAStatus HwCryptoKey::deriveKey(
+ const ndk_hwcrypto::IHwCryptoKey::DerivedKeyParameters& /*parameters*/,
+ ndk_hwcrypto::IHwCryptoKey::DerivedKey* /*aidl_return*/) {
+ return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED,
+ "android is not authorized to call deriveKey");
+}
+
+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/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
index 29c47f5..b2a1304 100644
--- a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
@@ -21,6 +21,7 @@
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <aidl/android/hardware/wifi/BnWifi.h>
+#include <aidl/android/hardware/wifi/BnWifiStaIfaceEventCallback.h>
#include <android/binder_manager.h>
#include <android/binder_status.h>
#include <binder/IServiceManager.h>
@@ -29,6 +30,7 @@
#include "wifi_aidl_test_utils.h"
+using aidl::android::hardware::wifi::BnWifiStaIfaceEventCallback;
using aidl::android::hardware::wifi::CachedScanData;
using aidl::android::hardware::wifi::IWifi;
using aidl::android::hardware::wifi::IWifiStaIface;
@@ -392,6 +394,66 @@
}
}
+class WifiStaIfaceEventCallback : public BnWifiStaIfaceEventCallback {
+ public:
+ WifiStaIfaceEventCallback() = default;
+
+ ::ndk::ScopedAStatus onBackgroundFullScanResult(
+ int32_t /* in_cmdId */, int32_t /* in_bucketsScanned */,
+ const ::aidl::android::hardware::wifi::StaScanResult& /* in_result */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onBackgroundScanFailure(int32_t /* in_cmdId */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onBackgroundScanResults(
+ int32_t /* in_cmdId */,
+ const std::vector<::aidl::android::hardware::wifi::StaScanData>& /* in_scanDatas */)
+ override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onRssiThresholdBreached(int32_t /* in_cmdId */,
+ const std::array<uint8_t, 6>& /* in_currBssid */,
+ int32_t /* in_currRssi */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onTwtFailure(int32_t /*in_cmdId*/,
+ ::aidl::android::hardware::wifi::IWifiStaIfaceEventCallback::
+ TwtErrorCode /* in_error */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onTwtSessionCreate(
+ int32_t /* in_cmdId */,
+ const ::aidl::android::hardware::wifi::TwtSession& /* in_twtSession */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onTwtSessionUpdate(
+ int32_t /* in_cmdId */,
+ const ::aidl::android::hardware::wifi::TwtSession& /* in_twtSession */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onTwtSessionTeardown(
+ int32_t /* in_cmdId */, int32_t /* in_twtSessionId */,
+ ::aidl::android::hardware::wifi::IWifiStaIfaceEventCallback::
+ TwtTeardownReasonCode /* in_reasonCode */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onTwtSessionStats(
+ int32_t /* in_cmdId */, int32_t /* in_twtSessionId */,
+ const ::aidl::android::hardware::wifi::TwtSessionStats& /* in_twtSessionStats */)
+ override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onTwtSessionSuspend(int32_t /* in_cmdId */,
+ int32_t /* in_twtSessionId */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onTwtSessionResume(int32_t /* in_cmdId */,
+ int32_t /* in_twtSessionId */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+};
+
/**
* TwtGetCapabilities
*/
@@ -433,6 +495,10 @@
if (!twt_capabilities.isTwtRequesterSupported) {
GTEST_SKIP() << "TWT is not supported";
}
+ const std::shared_ptr<WifiStaIfaceEventCallback> callback =
+ ndk::SharedRefBase::make<WifiStaIfaceEventCallback>();
+ ASSERT_NE(callback, nullptr);
+ EXPECT_TRUE(wifi_sta_iface_->registerEventCallback(callback).isOk());
TwtRequest twtRequest;
twtRequest.mloLinkId = 0;
@@ -493,9 +559,13 @@
twtRequest.minWakeIntervalUs = 10000;
twtRequest.maxWakeIntervalUs = 100000;
+ auto status = wifi_sta_iface_->twtSessionUpdate(1, 10, twtRequest);
+ if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ GTEST_SKIP() << "TwtSessionUpdate is not supported";
+ }
// Expecting a IWifiStaIfaceEventCallback.onTwtFailure() with INVALID_PARAMS
// as the error code.
- EXPECT_TRUE(wifi_sta_iface_->twtSessionUpdate(1, 10, twtRequest).isOk());
+ EXPECT_TRUE(status.isOk());
}
/**
@@ -509,9 +579,13 @@
GTEST_SKIP() << "TWT is not supported";
}
+ auto status = wifi_sta_iface_->twtSessionSuspend(1, 10);
+ if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ GTEST_SKIP() << "TwtSessionSuspend is not supported";
+ }
// Expecting a IWifiStaIfaceEventCallback.onTwtFailure() with INVALID_PARAMS
// as the error code.
- EXPECT_TRUE(wifi_sta_iface_->twtSessionSuspend(1, 10).isOk());
+ EXPECT_TRUE(status.isOk());
}
/**
@@ -525,9 +599,13 @@
GTEST_SKIP() << "TWT is not supported";
}
+ auto status = wifi_sta_iface_->twtSessionResume(1, 10);
+ if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ GTEST_SKIP() << "TwtSessionResume is not supported";
+ }
// Expecting a IWifiStaIfaceEventCallback.onTwtFailure() with INVALID_PARAMS
// as the error code.
- EXPECT_TRUE(wifi_sta_iface_->twtSessionResume(1, 10).isOk());
+ EXPECT_TRUE(status.isOk());
}
/*