Merge "Add two missing newlines." 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/compatibility_matrices/compatibility_matrix.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml
index 8d5a50a..85702e2 100644
--- a/compatibility_matrices/compatibility_matrix.202504.xml
+++ b/compatibility_matrices/compatibility_matrix.202504.xml
@@ -523,6 +523,14 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" exclusive-to="virtual-machine">
+ <name>android.hardware.security.see.storage</name>
+ <version>1</version>
+ <interface>
+ <name>ISecureStorage</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="aidl" updatable-via-apex="true">
<name>android.hardware.security.secureclock</name>
<version>1</version>
diff --git a/compatibility_matrices/compatibility_matrix.202604.xml b/compatibility_matrices/compatibility_matrix.202604.xml
index 793b166..46b04c9 100644
--- a/compatibility_matrices/compatibility_matrix.202604.xml
+++ b/compatibility_matrices/compatibility_matrix.202604.xml
@@ -523,6 +523,14 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" exclusive-to="virtual-machine">
+ <name>android.hardware.security.see.storage</name>
+ <version>1</version>
+ <interface>
+ <name>ISecureStorage</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="aidl" updatable-via-apex="true">
<name>android.hardware.security.secureclock</name>
<version>1</version>
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/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 9fb7db8..1c8a6f8 100644
--- a/radio/aidl/vts/radio_modem_test.cpp
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -201,6 +201,13 @@
GTEST_SKIP() << "Skipping getDeviceIdentity "
"due to undefined FEATURE_TELEPHONY";
}
+ int32_t aidl_version;
+ ndk::ScopedAStatus aidl_status = radio_modem->getInterfaceVersion(&aidl_version);
+ ASSERT_OK(aidl_status);
+ if (aidl_version >= 4) {
+ ALOGI("Skipped the test since getDeviceIdentity is deprecated");
+ GTEST_SKIP();
+ }
serial = GetRandomSerialNumber();
@@ -285,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/vts/functional/Android.bp b/security/see/hwcrypto/aidl/vts/functional/Android.bp
index c2514d1..eb2eba1 100644
--- a/security/see/hwcrypto/aidl/vts/functional/Android.bp
+++ b/security/see/hwcrypto/aidl/vts/functional/Android.bp
@@ -30,6 +30,7 @@
"libvsock",
"librpcbinder_rs",
"librustutils",
+ "libhwcryptohal_common",
],
arch: {
arm64: {
@@ -50,8 +51,8 @@
}
rust_test {
- name: "VtsAidlHwCryptoConnTest",
- srcs: ["connection_test.rs"],
+ name: "VtsAidlHwCryptoTests",
+ srcs: ["hwcryptokey_tests.rs"],
require_root: true,
defaults: [
"hw_crypto_hal_aidl_rust_defaults",
@@ -59,4 +60,24 @@
rustlibs: [
"libhwcryptohal_vts_test",
],
+ 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/AndroidTestSystem.xml b/security/see/hwcrypto/aidl/vts/functional/AndroidTestSystem.xml
deleted file mode 100644
index 649be23..0000000
--- a/security/see/hwcrypto/aidl/vts/functional/AndroidTestSystem.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="VtsAidlHwCryptoConnTestSystem" value="/data/local/tmp/VtsAidlHwCryptoConnTestSystem" />
- </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="VtsAidlHwCryptoConnTestSystem" />
- <!-- Rust tests are run in parallel by default. Run these ones
- single-threaded, so that one test's secrets don't affect
- the behaviour of a different test. -->
- <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 81ae3fa..465dde7 100644
--- a/security/see/hwcrypto/aidl/vts/functional/lib.rs
+++ b/security/see/hwcrypto/aidl/vts/functional/lib.rs
@@ -17,61 +17,11 @@
//! VTS test library for HwCrypto functionality.
//! It provides the base clases necessaries to write HwCrypto VTS tests
-#[cfg(target_arch = "x86_64")]
-use anyhow::Context;
use anyhow::Result;
-#[cfg(target_arch = "x86_64")]
-use binder::{ExceptionCode, FromIBinder, IntoBinderResult, ParcelFileDescriptor};
-#[cfg(target_arch = "x86_64")]
-use rpcbinder::RpcSession;
-#[cfg(target_arch = "x86_64")]
-use vsock::VsockStream;
-#[cfg(target_arch = "x86_64")]
-use std::os::fd::{FromRawFd, IntoRawFd};
-#[cfg(target_arch = "x86_64")]
-use std::fs::File;
-#[cfg(target_arch = "x86_64")]
-use std::io::Read;
-#[cfg(target_arch = "x86_64")]
-use rustutils::system_properties;
-#[cfg(target_arch = "aarch64")]
use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::IHwCryptoKey::BpHwCryptoKey;
use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::IHwCryptoKey::IHwCryptoKey;
-#[cfg(target_arch = "x86_64")]
-const HWCRYPTO_SERVICE_PORT: u32 = 4;
-
-/// Local function to connect to service
-#[cfg(target_arch = "x86_64")]
-pub fn connect_service<T: FromIBinder + ?Sized>(
- cid: u32,
- port: u32,
-) -> 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 using a direct vsock connection
-#[cfg(target_arch = "x86_64")]
-pub fn get_hwcryptokey() -> Result<binder::Strong<dyn IHwCryptoKey>, binder::Status> {
- let cid = system_properties::read("trusty.test_vm.vm_cid")
- .context("couldn't get vm cid")
- .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)?)
-}
-
/// Get a HwCryptoKey binder service object using the service manager
-#[cfg(target_arch = "aarch64")]
pub fn get_hwcryptokey() -> Result<binder::Strong<dyn IHwCryptoKey>, binder::Status> {
let interface_name = <BpHwCryptoKey as IHwCryptoKey>::get_descriptor().to_owned() + "/default";
Ok(binder::get_interface(&interface_name)?)
diff --git a/security/see/hwcrypto/default/Android.bp b/security/see/hwcrypto/default/Android.bp
index ab23cfd..7a4a7b6 100644
--- a/security/see/hwcrypto/default/Android.bp
+++ b/security/see/hwcrypto/default/Android.bp
@@ -112,6 +112,7 @@
cc_test {
name: "HwCryptoHalDelegatorTests",
enabled: false,
+ require_root: true,
srcs: [
"delegatorTest.cpp",
],
@@ -124,12 +125,14 @@
shared_libs: [
"libbase",
"liblog",
+ "libutils",
"libbinder",
"libbinder_ndk",
],
static_libs: [
"android.hardware.security.see.hwcrypto-V1-ndk",
"android.hardware.security.see.hwcrypto-V1-cpp",
+ "hwcryptohallib",
],
arch: {
diff --git a/security/see/hwcrypto/default/delegatorTest.cpp b/security/see/hwcrypto/default/delegatorTest.cpp
index a80d6fd..28b177d 100644
--- a/security/see/hwcrypto/default/delegatorTest.cpp
+++ b/security/see/hwcrypto/default/delegatorTest.cpp
@@ -1,11 +1,84 @@
+#include <android/binder_manager.h>
#include <gtest/gtest.h>
+#include <linux/dma-heap.h>
+#include <sys/auxv.h>
+#include <sys/mman.h>
#include "hwcryptokeyimpl.h"
+static inline bool align_overflow(size_t size, size_t alignment, size_t* aligned) {
+ if (size % alignment == 0) {
+ *aligned = size;
+ return false;
+ }
+ size_t temp = 0;
+ bool overflow = __builtin_add_overflow(size / alignment, 1, &temp);
+ overflow |= __builtin_mul_overflow(temp, alignment, aligned);
+ return overflow;
+}
+
+static int allocate_buffers(size_t size) {
+ const char* device_name = "/dev/dma_heap/system";
+ int dma_heap_fd = open(device_name, O_RDONLY | O_CLOEXEC);
+ if (dma_heap_fd < 0) {
+ LOG(ERROR) << "Cannot open " << device_name;
+ return -1;
+ }
+ size_t aligned = 0;
+ if (align_overflow(size, getauxval(AT_PAGESZ), &aligned)) {
+ LOG(ERROR) << "Rounding up buffer size oveflowed";
+ return -1;
+ }
+ struct dma_heap_allocation_data allocation_request = {
+ .len = aligned,
+ .fd_flags = O_RDWR | O_CLOEXEC,
+ };
+ int rc = ioctl(dma_heap_fd, DMA_HEAP_IOCTL_ALLOC, &allocation_request);
+ if (rc < 0) {
+ LOG(ERROR) << "Buffer allocation request failed " << rc;
+ return -1;
+ }
+ int fd = allocation_request.fd;
+ if (fd < 0) {
+ LOG(ERROR) << "Allocation request returned bad fd" << fd;
+ return -1;
+ }
+ return fd;
+}
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
+TEST(HwCryptoHalDelegator, FdTest) {
+ const std::string instance =
+ std::string() + ndk_hwcrypto::IHwCryptoKey::descriptor + "/default";
+ ndk::SpAIBinder binder(AServiceManager_waitForService(instance.c_str()));
+ ASSERT_NE(binder, nullptr);
+ auto hwCryptoKey = ndk_hwcrypto::IHwCryptoKey::fromBinder(binder);
+ ASSERT_NE(hwCryptoKey, nullptr);
+ auto fd = allocate_buffers(4096);
+ EXPECT_GE(fd, 0);
+ ndk::ScopedFileDescriptor ndkFd(fd);
+ ndk_hwcrypto::MemoryBufferParameter memBuffParam = ndk_hwcrypto::MemoryBufferParameter();
+ memBuffParam.bufferHandle.set<ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::input>(
+ std::move(ndkFd));
+ memBuffParam.sizeBytes = 4096;
+ auto operation = ndk_hwcrypto::CryptoOperation();
+ operation.set<ndk_hwcrypto::CryptoOperation::setMemoryBuffer>(std::move(memBuffParam));
+ ndk_hwcrypto::CryptoOperationSet operationSet = ndk_hwcrypto::CryptoOperationSet();
+ operationSet.context = nullptr;
+ operationSet.operations.push_back(std::move(operation));
+ std::vector<ndk_hwcrypto::CryptoOperationSet> operationSets;
+ operationSets.push_back(std::move(operationSet));
+ std::vector<ndk_hwcrypto::CryptoOperationResult> aidl_return;
+ std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations> hwCryptoOperations;
+ auto res = hwCryptoKey->getHwCryptoOperations(&hwCryptoOperations);
+ EXPECT_TRUE(res.isOk());
+ res = hwCryptoOperations->processCommandList(&operationSets, &aidl_return);
+ EXPECT_TRUE(res.isOk());
+}
+
TEST(HwCryptoHalDelegator, keyPolicyCppToNdk) {
cpp_hwcrypto::KeyPolicy cppPolicy = cpp_hwcrypto::KeyPolicy();
cppPolicy.keyType = cpp_hwcrypto::types::KeyType::AES_128_CBC_PKCS7_PADDING;
@@ -46,4 +119,4 @@
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/hwcryptokeyimpl.h b/security/see/hwcrypto/default/hwcryptokeyimpl.h
index 19be8b4..7d3ade7 100644
--- a/security/see/hwcrypto/default/hwcryptokeyimpl.h
+++ b/security/see/hwcrypto/default/hwcryptokeyimpl.h
@@ -46,30 +46,33 @@
ndk::ScopedAStatus deriveCurrentDicePolicyBoundKey(
const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& derivationKey,
- ndk_hwcrypto::IHwCryptoKey::DiceCurrentBoundKeyResult* aidl_return);
+ 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);
+ ndk_hwcrypto::IHwCryptoKey::DiceBoundKeyResult* aidl_return) override;
ndk::ScopedAStatus deriveKey(const ndk_hwcrypto::IHwCryptoKey::DerivedKeyParameters& parameters,
- ndk_hwcrypto::IHwCryptoKey::DerivedKey* aidl_return);
+ ndk_hwcrypto::IHwCryptoKey::DerivedKey* aidl_return) override;
ndk::ScopedAStatus getHwCryptoOperations(
- std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations>* aidl_return);
+ 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);
+ 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);
+ 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);
+ 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);
+ ndk::ScopedAStatus getKeyslotData(
+ ndk_hwcrypto::IHwCryptoKey::KeySlot slotId,
+ std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) override;
};
template <typename LHP, typename RHP>
@@ -79,9 +82,10 @@
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(reinterpret_cast<decltype(policy.keyPermissions[0])>(permission)));
+ std::move(static_cast<decltype(policy.keyPermissions)::value_type>(permission)));
}
return policy;
}
diff --git a/security/see/hwcrypto/default/hwcryptolib.cpp b/security/see/hwcrypto/default/hwcryptolib.cpp
index 0e15883..a7ecca1 100644
--- a/security/see/hwcrypto/default/hwcryptolib.cpp
+++ b/security/see/hwcrypto/default/hwcryptolib.cpp
@@ -115,11 +115,14 @@
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) {
@@ -132,18 +135,18 @@
LOG(ERROR) << "failed to allocate HwCryptoOperationContext";
return nullptr;
}
+ contextNdk->self = contextNdk;
return contextNdk;
}
};
-// TODO: Check refactoring opportunities like returning a Result<cpp_hwcrypto::types::OperationData>
-// once we add the code that uses this function.
-Result<void> setOperationData(const ndk_hwcrypto::types::OperationData& ndkOperationData,
- cpp_hwcrypto::types::OperationData* cppOperationData) {
+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>(
+ cppOperationData.set<cpp_hwcrypto::types::OperationData::dataBuffer>(
ndkOperationData.get<ndk_hwcrypto::types::OperationData::dataBuffer>());
break;
case ndk_hwcrypto::types::OperationData::memoryBufferReference:
@@ -155,14 +158,253 @@
ndkOperationData
.get<ndk_hwcrypto::types::OperationData::memoryBufferReference>()
.sizeBytes;
- cppOperationData->set<cpp_hwcrypto::types::OperationData::memoryBufferReference>(
+ cppOperationData.set<cpp_hwcrypto::types::OperationData::memoryBufferReference>(
std::move(cppMemBuffRef));
break;
default:
- // This shouldn't happen with the current definitions
- return ErrnoError() << "received unknown operation data type";
+ LOG(ERROR) << "received unknown operation data type";
+ return std::nullopt;
}
- return {};
+ 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::MemoryBufferParameter> convertMemoryBufferParameters(
+ const ndk_hwcrypto::MemoryBufferParameter& ndkMemBuffParams) {
+ cpp_hwcrypto::MemoryBufferParameter memBuffParams = cpp_hwcrypto::MemoryBufferParameter();
+ memBuffParams.sizeBytes = ndkMemBuffParams.sizeBytes;
+ android::os::ParcelFileDescriptor pfd;
+ ndk::ScopedFileDescriptor ndkFd;
+ switch (ndkMemBuffParams.bufferHandle.getTag()) {
+ case ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::input:
+ ndkFd = ndkMemBuffParams.bufferHandle
+ .get<ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::input>()
+ .dup();
+ pfd.reset(binder::unique_fd(ndkFd.release()));
+ memBuffParams.bufferHandle
+ .set<cpp_hwcrypto::MemoryBufferParameter::MemoryBuffer::input>(std::move(pfd));
+ break;
+ case ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::output:
+ ndkFd = ndkMemBuffParams.bufferHandle
+ .get<ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::output>()
+ .dup();
+ pfd.reset(binder::unique_fd(ndkFd.release()));
+ memBuffParams.bufferHandle
+ .set<cpp_hwcrypto::MemoryBufferParameter::MemoryBuffer::output>(std::move(pfd));
+ break;
+ default:
+ LOG(ERROR) << "unknown bufferHandle type";
+ return std::nullopt;
+ }
+ return memBuffParams;
+}
+
+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 {
@@ -189,19 +431,215 @@
}
ndk::ScopedAStatus processCommandList(
- std::vector<ndk_hwcrypto::CryptoOperationSet>* /*operationSets*/,
- std::vector<ndk_hwcrypto::CryptoOperationResult>* /*aidl_return*/) {
- return ndk::ScopedAStatus::ok();
+ 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;
+ std::optional<cpp_hwcrypto::MemoryBufferParameter> cppMemBuffParams;
+ switch (operation.getTag()) {
+ case ndk_hwcrypto::CryptoOperation::setMemoryBuffer:
+ cppMemBuffParams = convertMemoryBufferParameters(
+ operation.get<ndk_hwcrypto::CryptoOperation::setMemoryBuffer>());
+ if (cppMemBuffParams.has_value()) {
+ cppOperation.set<cpp_hwcrypto::CryptoOperation::setMemoryBuffer>(
+ std::move(cppMemBuffParams.value()));
+ } else {
+ return convertStatus(status);
+ }
+ 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;
@@ -213,6 +651,7 @@
LOG(ERROR) << "failed to allocate HwCryptoKey";
return nullptr;
}
+ opaqueKeyNdk->self = opaqueKeyNdk;
return opaqueKeyNdk;
}
@@ -271,13 +710,19 @@
ndk::ScopedAStatus setProtectionId(
const ndk_hwcrypto::types::ProtectionId /*protectionId*/,
const ::std::vector<ndk_hwcrypto::types::OperationType>& /*allowedOperations*/) {
- return ndk::ScopedAStatus::ok();
+ 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) {});
+ auto session_initializer = [](sp<RpcSession>& session) {
+ session->setFileDescriptorTransportMode(RpcSession::FileDescriptorTransportMode::TRUSTY);
+ };
+ mSession =
+ RpcTrustyConnectWithSessionInitializer(tipcDev, HWCRYPTO_KEY_PORT, session_initializer);
if (!mSession) {
return ErrnoError() << "failed to connect to hwcrypto";
}
@@ -308,24 +753,26 @@
ndk::ScopedAStatus HwCryptoKey::deriveCurrentDicePolicyBoundKey(
const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& /*derivationKey*/,
ndk_hwcrypto::IHwCryptoKey::DiceCurrentBoundKeyResult* /*aidl_return*/) {
- // return mHwCryptoServer->deriveCurrentDicePolicyBoundKey(derivationKey, aidl_return);
- return ndk::ScopedAStatus::ok();
+ 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 mHwCryptoServer->deriveDicePolicyBoundKey(derivationKey, dicePolicyForKeyVersion,
- // aidl_return);
- return ndk::ScopedAStatus::ok();
+ 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 mHwCryptoServer->deriveKey(parameters, aidl_return);
- return ndk::ScopedAStatus::ok();
+ return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED,
+ "android is not authorized to call deriveKey");
}
ndk::ScopedAStatus HwCryptoKey::getHwCryptoOperations(
diff --git a/security/see/storage/default/Android.bp b/security/see/storage/default/Android.bp
new file mode 100644
index 0000000..7ea7739
--- /dev/null
+++ b/security/see/storage/default/Android.bp
@@ -0,0 +1,21 @@
+//
+// 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.
+
+prebuilt_etc {
+ name: "android.hardware.security.see.storage-service.trusty.xml",
+ sub_dir: "vintf",
+ vendor: true,
+ src: "android.hardware.security.see.storage-service.trusty.xml",
+}
diff --git a/security/see/storage/default/android.hardware.security.see.storage-service.trusty.xml b/security/see/storage/default/android.hardware.security.see.storage-service.trusty.xml
new file mode 100644
index 0000000..89f3839
--- /dev/null
+++ b/security/see/storage/default/android.hardware.security.see.storage-service.trusty.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl" exclusive-to="virtual-machine">
+ <name>android.hardware.security.see.storage</name>
+ <version>1</version>
+ <interface>
+ <name>ISecureStorage</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>