Merge tm-qpr-dev-plus-aosp-without-vendor@9467136
Bug: 264720040
Merged-In: I59ea99e8a1720f61954747f6c29e14cfea9a0f56
Change-Id: I016e93351fe6ba3e46cff141280ea0b1ebffd37c
diff --git a/audio/aidl/TEST_MAPPING b/audio/aidl/TEST_MAPPING
index 486c13d..6a545c1 100644
--- a/audio/aidl/TEST_MAPPING
+++ b/audio/aidl/TEST_MAPPING
@@ -13,7 +13,7 @@
"name": "VtsHalDownmixTargetTest"
},
{
- "name": "VtsHalDynamicProcessingTargetTest"
+ "name": "VtsHalDynamicsProcessingTargetTest"
},
{
"name": "VtsHalEnvironmentalReverbTargetTest"
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
index 7f34f33..9edad09 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
@@ -44,22 +44,6 @@
int diffusionPm;
int densityPm;
boolean bypass;
- const int MIN_ROOM_LEVEL_MB = (-6000);
- const int MAX_ROOM_LEVEL_MB = 0;
- const int MIN_ROOM_HF_LEVEL_MB = (-4000);
- const int MAX_ROOM_HF_LEVEL_MB = 0;
- const int MIN_DECAY_TIME_MS = 100;
- const int MAX_DECAY_TIME_MS = 20000;
- const int MIN_DECAY_HF_RATIO_PM = 100;
- const int MAX_DECAY_HF_RATIO_PM = 1000;
- const int MIN_LEVEL_MB = (-6000);
- const int MAX_LEVEL_MB = 0;
- const int MIN_DELAY_MS = 0;
- const int MAX_DELAY_MS = 65;
- const int MIN_DIFFUSION_PM = 0;
- const int MAX_DIFFUSION_PM = 1000;
- const int MIN_DENSITY_PM = 0;
- const int MAX_DENSITY_PM = 1000;
@VintfStability
union Id {
int vendorExtensionTag;
@@ -68,6 +52,17 @@
@VintfStability
parcelable Capability {
android.hardware.audio.effect.VendorExtension extension;
+ int minRoomLevelMb;
+ int maxRoomLevelMb;
+ int minRoomHfLevelMb;
+ int maxRoomHfLevelMb;
int maxDecayTimeMs;
+ int minDecayHfRatioPm;
+ int maxDecayHfRatioPm;
+ int minLevelMb;
+ int maxLevelMb;
+ int maxDelayMs;
+ int maxDiffusionPm;
+ int maxDensityPm;
}
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
index eaa4bb1..3ba44a0 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
@@ -35,7 +35,7 @@
@VintfStability
union Parameter {
android.hardware.audio.effect.Parameter.Common common;
- android.media.audio.common.AudioDeviceDescription deviceDescription;
+ android.media.audio.common.AudioDeviceDescription[] deviceDescription;
android.media.audio.common.AudioMode mode;
android.media.audio.common.AudioSource source;
android.hardware.audio.effect.Parameter.VolumeStereo volumeStereo;
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 e25b15a..501dc01 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
@@ -30,6 +30,7 @@
STANDBY -> PAUSED [label="burst"]; // producer -> active
IDLE -> STANDBY [label="standby"]; // consumer -> passive
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 -> TRANSFERRING [label="burst"]; // early unblocking
@@ -45,6 +46,7 @@
PAUSED -> IDLE [label="flush"]; // producer -> passive, buffer is cleared
DRAINING -> IDLE [label="←IStreamCallback.onDrainReady"];
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
diff --git a/audio/aidl/android/hardware/audio/core/stream-out-sm.gv b/audio/aidl/android/hardware/audio/core/stream-out-sm.gv
index 6aa5c61..47e7fda 100644
--- a/audio/aidl/android/hardware/audio/core/stream-out-sm.gv
+++ b/audio/aidl/android/hardware/audio/core/stream-out-sm.gv
@@ -31,6 +31,7 @@
ACTIVE -> ACTIVE [label="burst"];
ACTIVE -> PAUSED [label="pause"]; // consumer -> passive (not consuming)
ACTIVE -> DRAINING [label="drain"]; // producer -> passive
+ ACTIVE -> IDLE [label="drain"]; // synchronous drain
PAUSED -> PAUSED [label="burst"];
PAUSED -> ACTIVE [label="start"]; // consumer -> active
PAUSED -> IDLE [label="flush"]; // producer -> passive, buffer is cleared
diff --git a/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
index 81c0dde..fc98fe6 100644
--- a/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
+++ b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
@@ -50,112 +50,96 @@
VendorExtension extension;
/**
+ * Minimal possible room level in millibels.
+ */
+ int minRoomLevelMb;
+ /**
+ * Maximum possible room level in millibels.
+ */
+ int maxRoomLevelMb;
+ /**
+ * Minimal possible room hf level in millibels.
+ */
+ int minRoomHfLevelMb;
+ /**
+ * Maximum possible room hf level in millibels.
+ */
+ int maxRoomHfLevelMb;
+ /**
* Max decay time supported in millisecond.
*/
int maxDecayTimeMs;
+ /**
+ * Minimal possible per mille decay hf ratio.
+ */
+ int minDecayHfRatioPm;
+ /**
+ * Maximum possible per mille decay hf ratio.
+ */
+ int maxDecayHfRatioPm;
+ /**
+ * Minimal possible room level in millibels.
+ */
+ int minLevelMb;
+ /**
+ * Maximum possible room level in millibels.
+ */
+ int maxLevelMb;
+ /**
+ * Maximum possible delay time in milliseconds.
+ */
+ int maxDelayMs;
+ /**
+ * Maximum possible per mille diffusion.
+ */
+ int maxDiffusionPm;
+ /**
+ * Maximum possible per mille density.
+ */
+ int maxDensityPm;
}
/**
- * Minimal possible room level in millibels.
- */
- const int MIN_ROOM_LEVEL_MB = -6000;
- /**
- * Maximum possible room level in millibels.
- */
- const int MAX_ROOM_LEVEL_MB = 0;
- /**
- * Room level apply to the reverb effect in millibels.
+ * Room level apply to the reverb effect in millibels. The value of the roomLevelMb must be in
+ * range of the value specified by the 'minRoomLevelMb' capability and the 'maxRoomLevelMb'
+ * capability.
*/
int roomLevelMb;
-
/**
- * Minimal possible room hf level in millibels.
- */
- const int MIN_ROOM_HF_LEVEL_MB = -4000;
- /**
- * Maximum possible room hf level in millibels.
- */
- const int MAX_ROOM_HF_LEVEL_MB = 0;
- /**
- * Room HF level apply to the reverb effect in millibels.
+ * Room HF level apply to the reverb effect in millibels. The value of the roomHfLevelMb must be
+ * in range of the value specified by the 'minRoomHfLevelMb' capability and the
+ * 'maxRoomHfLevelMb' capability.
*/
int roomHfLevelMb;
-
/**
- * Minimal possible decay time in milliseconds.
- */
- const int MIN_DECAY_TIME_MS = 100;
- /**
- * Maximum possible decay time in milliseconds.
- */
- const int MAX_DECAY_TIME_MS = 20000;
- /**
- * Delay time apply to the reverb effect in milliseconds.
+ * Delay time apply to the reverb effect in milliseconds.The value of the decayTimeMs must
+ * be non-negative and not exceed the value specified by the 'maxDecayTimeMs' capability.
*/
int decayTimeMs;
-
/**
- * Minimal possible per mille decay hf ratio.
- */
- const int MIN_DECAY_HF_RATIO_PM = 100;
- /**
- * Maximum possible per mille decay hf ratio.
- */
- const int MAX_DECAY_HF_RATIO_PM = 1000;
- /**
- * HF decay ratio in permilles.
+ * HF decay ratio in permilles. The value of the decayHfRatioPm must be in range
+ * of the value specified by the 'minDecayHfRatioPm' capability and the 'maxDecayHfRatioPm'
+ * capability.
*/
int decayHfRatioPm;
-
/**
- * Minimal possible room level in millibels.
- */
- const int MIN_LEVEL_MB = -6000;
- /**
- * Maximum possible room level in millibels.
- */
- const int MAX_LEVEL_MB = 0;
- /**
- * Reverb level in millibels.
+ * Reverb level in millibels. The value of the levelMb must be in range
+ * of the value specified by the 'minLevelMb' capability and the 'maxLevelMb' capability.
*/
int levelMb;
-
/**
- * Minimal possible delay time in milliseconds.
- */
- const int MIN_DELAY_MS = 0;
- /**
- * Maximum possible delay time in milliseconds.
- */
- const int MAX_DELAY_MS = 65;
- /**
- * Reverb delay in milliseconds.
+ * Reverb delay in milliseconds. The value of the delayMs must be non-negative and not
+ * exceed the value specified by the 'maxDelayMs' capability.
*/
int delayMs;
-
/**
- * Minimal possible per mille diffusion.
- */
- const int MIN_DIFFUSION_PM = 0;
- /**
- * Maximum possible per mille diffusion.
- */
- const int MAX_DIFFUSION_PM = 1000;
- /**
- * Diffusion in permilles.
+ * Diffusion in permilles. The value of the diffusionPm must be non-negative and not
+ * exceed the value specified by the 'maxDiffusionPm' capability.
*/
int diffusionPm;
-
/**
- * Minimal possible per mille density.
- */
- const int MIN_DENSITY_PM = 0;
- /**
- * Maximum possible per mille density.
- */
- const int MAX_DENSITY_PM = 1000;
- /**
- * Density in permilles.
+ * Density in permilles. The value of the densityPm must be non-negative and not
+ * exceed the value specified by the 'maxDensityPm' capability.
*/
int densityPm;
diff --git a/audio/aidl/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
index 1c001d2..473dfb5 100644
--- a/audio/aidl/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
@@ -120,10 +120,11 @@
Common common;
/**
- * Used by audio framework to set the device type to effect engine.
- * Effect must implement setParameter(device) if Flags.deviceIndication set to true.
+ * Used by audio framework to set the device type(s) to effect engine.
+ * Effect engine must apply all AudioDeviceDescription in the list.
+ * Effect must implement setParameter(deviceDescription) if Flags.deviceIndication set to true.
*/
- AudioDeviceDescription deviceDescription;
+ AudioDeviceDescription[] deviceDescription;
/**
* Used by audio framework to set the audio mode to effect engine.
* Effect must implement setParameter(mode) if Flags.audioModeIndication set to true.
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 1e6785f..95043f7 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -69,6 +69,7 @@
"Module.cpp",
"SoundDose.cpp",
"Stream.cpp",
+ "StreamStub.cpp",
"Telephony.cpp",
],
generated_sources: [
@@ -163,6 +164,7 @@
"libloudnessenhanceraidl",
"libnssw",
"libpresetreverbsw",
+ "libreverbaidl",
"libtinyxml2",
"libvirtualizersw",
"libvisualizeraidl",
diff --git a/audio/aidl/default/EffectFactory.cpp b/audio/aidl/default/EffectFactory.cpp
index 3b40ae0..5cd87fd 100644
--- a/audio/aidl/default/EffectFactory.cpp
+++ b/audio/aidl/default/EffectFactory.cpp
@@ -165,7 +165,7 @@
return status;
}
-void Factory::openEffectLibrary(const AudioUuid& impl, const std::string& libName) {
+bool Factory::openEffectLibrary(const AudioUuid& impl, const std::string& libName) {
std::function<void(void*)> dlClose = [](void* handle) -> void {
if (handle && dlclose(handle)) {
LOG(ERROR) << "dlclose failed " << dlerror();
@@ -176,7 +176,7 @@
std::unique_ptr<void, decltype(dlClose)>{dlopen(libName.c_str(), RTLD_LAZY), dlClose};
if (!libHandle) {
LOG(ERROR) << __func__ << ": dlopen failed, err: " << dlerror();
- return;
+ return false;
}
LOG(INFO) << __func__ << " dlopen lib:" << libName << "\nimpl:" << impl.toString()
@@ -186,6 +186,7 @@
{impl,
std::make_tuple(std::move(libHandle),
std::unique_ptr<struct effect_dl_interface_s>(interface), libName)});
+ return true;
}
void Factory::createIdentityWithConfig(const EffectConfig::LibraryUuid& configLib,
@@ -201,8 +202,9 @@
LOG(DEBUG) << __func__ << ": typeUuid " << id.type.toString() << "\nimplUuid "
<< id.uuid.toString() << " proxyUuid "
<< (proxyUuid.has_value() ? proxyUuid->toString() : "null");
- openEffectLibrary(id.uuid, path->second);
- mIdentitySet.insert(std::move(id));
+ if (openEffectLibrary(id.uuid, path->second)) {
+ mIdentitySet.insert(std::move(id));
+ }
} else {
LOG(ERROR) << __func__ << ": library " << libName << " not exist!";
return;
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index e8b5bfc..acad70f 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -28,6 +28,7 @@
#include "core-impl/Bluetooth.h"
#include "core-impl/Module.h"
#include "core-impl/SoundDose.h"
+#include "core-impl/StreamStub.h"
#include "core-impl/Telephony.h"
#include "core-impl/utils.h"
@@ -46,6 +47,7 @@
using aidl::android::media::audio::common::AudioPortConfig;
using aidl::android::media::audio::common::AudioPortExt;
using aidl::android::media::audio::common::AudioProfile;
+using aidl::android::media::audio::common::Boolean;
using aidl::android::media::audio::common::Int;
using aidl::android::media::audio::common::PcmType;
using android::hardware::audio::common::getFrameSizeInBytes;
@@ -101,9 +103,10 @@
erase_all_values(mPatches, std::set<int32_t>{patchId});
}
-ndk::ScopedAStatus Module::createStreamContext(int32_t in_portConfigId, int64_t in_bufferSizeFrames,
- std::shared_ptr<IStreamCallback> asyncCallback,
- StreamContext* out_context) {
+ndk::ScopedAStatus Module::createStreamContext(
+ int32_t in_portConfigId, int64_t in_bufferSizeFrames,
+ std::shared_ptr<IStreamCallback> asyncCallback,
+ std::shared_ptr<IStreamOutEventCallback> outEventCallback, StreamContext* out_context) {
if (in_bufferSizeFrames <= 0) {
LOG(ERROR) << __func__ << ": non-positive buffer size " << in_bufferSizeFrames;
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
@@ -138,12 +141,15 @@
(flags.getTag() == AudioIoFlags::Tag::output &&
!isBitPositionFlagSet(flags.get<AudioIoFlags::Tag::output>(),
AudioOutputFlags::MMAP_NOIRQ))) {
+ StreamContext::DebugParameters params{mDebug.streamTransientStateDelayMs,
+ mVendorDebug.forceTransientBurst,
+ mVendorDebug.forceSynchronousDrain};
StreamContext temp(
std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/),
std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/),
portConfigIt->format.value(), portConfigIt->channelMask.value(),
std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames),
- asyncCallback, mDebug.streamTransientStateDelayMs);
+ asyncCallback, outEventCallback, params);
if (temp.isValid()) {
*out_context = std::move(temp);
} else {
@@ -541,14 +547,15 @@
}
StreamContext context;
if (auto status = createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames, nullptr,
- &context);
+ nullptr, &context);
!status.isOk()) {
return status;
}
context.fillDescriptor(&_aidl_return->desc);
std::shared_ptr<StreamIn> stream;
- if (auto status = StreamIn::createInstance(in_args.sinkMetadata, std::move(context),
- mConfig->microphones, &stream);
+ // TODO: Add a mapping from module instance names to a corresponding 'createInstance'.
+ if (auto status = StreamInStub::createInstance(in_args.sinkMetadata, std::move(context),
+ mConfig->microphones, &stream);
!status.isOk()) {
return status;
}
@@ -594,14 +601,16 @@
}
StreamContext context;
if (auto status = createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames,
- isNonBlocking ? in_args.callback : nullptr, &context);
+ isNonBlocking ? in_args.callback : nullptr,
+ in_args.eventCallback, &context);
!status.isOk()) {
return status;
}
context.fillDescriptor(&_aidl_return->desc);
std::shared_ptr<StreamOut> stream;
- if (auto status = StreamOut::createInstance(in_args.sourceMetadata, std::move(context),
- in_args.offloadInfo, &stream);
+ // TODO: Add a mapping from module instance names to a corresponding 'createInstance'.
+ if (auto status = StreamOutStub::createInstance(in_args.sourceMetadata, std::move(context),
+ in_args.offloadInfo, &stream);
!status.isOk()) {
return status;
}
@@ -976,18 +985,69 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
+const std::string Module::VendorDebug::kForceTransientBurstName = "aosp.forceTransientBurst";
+const std::string Module::VendorDebug::kForceSynchronousDrainName = "aosp.forceSynchronousDrain";
+
ndk::ScopedAStatus Module::getVendorParameters(const std::vector<std::string>& in_ids,
std::vector<VendorParameter>* _aidl_return) {
LOG(DEBUG) << __func__ << ": id count: " << in_ids.size();
- (void)_aidl_return;
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ bool allParametersKnown = true;
+ for (const auto& id : in_ids) {
+ if (id == VendorDebug::kForceTransientBurstName) {
+ VendorParameter forceTransientBurst{.id = id};
+ forceTransientBurst.ext.setParcelable(Boolean{mVendorDebug.forceTransientBurst});
+ _aidl_return->push_back(std::move(forceTransientBurst));
+ } else if (id == VendorDebug::kForceSynchronousDrainName) {
+ VendorParameter forceSynchronousDrain{.id = id};
+ forceSynchronousDrain.ext.setParcelable(Boolean{mVendorDebug.forceSynchronousDrain});
+ _aidl_return->push_back(std::move(forceSynchronousDrain));
+ } else {
+ allParametersKnown = false;
+ LOG(ERROR) << __func__ << ": unrecognized parameter \"" << id << "\"";
+ }
+ }
+ if (allParametersKnown) return ndk::ScopedAStatus::ok();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
+namespace {
+
+template <typename W>
+bool extractParameter(const VendorParameter& p, decltype(W::value)* v) {
+ std::optional<W> value;
+ binder_status_t result = p.ext.getParcelable(&value);
+ if (result == STATUS_OK && value.has_value()) {
+ *v = value.value().value;
+ return true;
+ }
+ LOG(ERROR) << __func__ << ": failed to read the value of the parameter \"" << p.id
+ << "\": " << result;
+ return false;
+}
+
+} // namespace
+
ndk::ScopedAStatus Module::setVendorParameters(const std::vector<VendorParameter>& in_parameters,
bool in_async) {
LOG(DEBUG) << __func__ << ": parameter count " << in_parameters.size()
<< ", async: " << in_async;
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ bool allParametersKnown = true;
+ for (const auto& p : in_parameters) {
+ if (p.id == VendorDebug::kForceTransientBurstName) {
+ if (!extractParameter<Boolean>(p, &mVendorDebug.forceTransientBurst)) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ } else if (p.id == VendorDebug::kForceSynchronousDrainName) {
+ if (!extractParameter<Boolean>(p, &mVendorDebug.forceSynchronousDrain)) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ } else {
+ allParametersKnown = false;
+ LOG(ERROR) << __func__ << ": unrecognized parameter \"" << p.id << "\"";
+ }
+ }
+ if (allParametersKnown) return ndk::ScopedAStatus::ok();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
ndk::ScopedAStatus Module::addDeviceEffect(
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index a490a2a..25814e4 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -85,16 +85,19 @@
if (mCommandMQ == nullptr) return "Command MQ is null";
if (mReplyMQ == nullptr) return "Reply MQ is null";
if (mDataMQ == nullptr) return "Data MQ is null";
- if (sizeof(decltype(mDataBuffer)::element_type) != mDataMQ->getQuantumSize()) {
+ if (sizeof(DataBufferElement) != mDataMQ->getQuantumSize()) {
return "Unexpected Data MQ quantum size: " + std::to_string(mDataMQ->getQuantumSize());
}
mDataBufferSize = mDataMQ->getQuantumCount() * mDataMQ->getQuantumSize();
- mDataBuffer.reset(new (std::nothrow) int8_t[mDataBufferSize]);
+ mDataBuffer.reset(new (std::nothrow) DataBufferElement[mDataBufferSize]);
if (mDataBuffer == nullptr) {
return "Failed to allocate data buffer for element count " +
std::to_string(mDataMQ->getQuantumCount()) +
", size in bytes: " + std::to_string(mDataBufferSize);
}
+ if (::android::status_t status = mDriver->init(); status != STATUS_OK) {
+ return "Failed to initialize the driver: " + std::to_string(status);
+ }
return "";
}
@@ -191,46 +194,59 @@
}
break;
case Tag::drain:
- if (command.get<Tag::drain>() == StreamDescriptor::DrainMode::DRAIN_UNSPECIFIED) {
+ if (const auto mode = command.get<Tag::drain>();
+ mode == StreamDescriptor::DrainMode::DRAIN_UNSPECIFIED) {
if (mState == StreamDescriptor::State::ACTIVE) {
- usleep(1000); // Simulate a blocking call into the driver.
- populateReply(&reply, mIsConnected);
- // Can switch the state to ERROR if a driver error occurs.
- mState = StreamDescriptor::State::DRAINING;
+ if (::android::status_t status = mDriver->drain(mode);
+ status == ::android::OK) {
+ populateReply(&reply, mIsConnected);
+ mState = StreamDescriptor::State::DRAINING;
+ } else {
+ LOG(ERROR) << __func__ << ": drain failed: " << status;
+ mState = StreamDescriptor::State::ERROR;
+ }
} else {
populateReplyWrongState(&reply, command);
}
} else {
- LOG(WARNING) << __func__
- << ": invalid drain mode: " << toString(command.get<Tag::drain>());
+ LOG(WARNING) << __func__ << ": invalid drain mode: " << toString(mode);
}
break;
case Tag::standby:
if (mState == StreamDescriptor::State::IDLE) {
- usleep(1000); // Simulate a blocking call into the driver.
- populateReply(&reply, mIsConnected);
- // Can switch the state to ERROR if a driver error occurs.
- mState = StreamDescriptor::State::STANDBY;
+ if (::android::status_t status = mDriver->standby(); status == ::android::OK) {
+ populateReply(&reply, mIsConnected);
+ mState = StreamDescriptor::State::STANDBY;
+ } else {
+ LOG(ERROR) << __func__ << ": standby failed: " << status;
+ mState = StreamDescriptor::State::ERROR;
+ }
} else {
populateReplyWrongState(&reply, command);
}
break;
case Tag::pause:
if (mState == StreamDescriptor::State::ACTIVE) {
- usleep(1000); // Simulate a blocking call into the driver.
- populateReply(&reply, mIsConnected);
- // Can switch the state to ERROR if a driver error occurs.
- mState = StreamDescriptor::State::PAUSED;
+ if (::android::status_t status = mDriver->pause(); status == ::android::OK) {
+ populateReply(&reply, mIsConnected);
+ mState = StreamDescriptor::State::PAUSED;
+ } else {
+ LOG(ERROR) << __func__ << ": pause failed: " << status;
+ mState = StreamDescriptor::State::ERROR;
+ }
} else {
populateReplyWrongState(&reply, command);
}
break;
case Tag::flush:
if (mState == StreamDescriptor::State::PAUSED) {
- usleep(1000); // Simulate a blocking call into the driver.
- populateReply(&reply, mIsConnected);
- // Can switch the state to ERROR if a driver error occurs.
- mState = StreamDescriptor::State::STANDBY;
+ if (::android::status_t status = mDriver->flush(); status == ::android::OK) {
+ populateReply(&reply, mIsConnected);
+ mState = StreamDescriptor::State::STANDBY;
+ } else {
+ LOG(ERROR) << __func__ << ": flush failed: " << status;
+ mState = StreamDescriptor::State::ERROR;
+ }
} else {
populateReplyWrongState(&reply, command);
}
@@ -247,33 +263,39 @@
}
bool StreamInWorkerLogic::read(size_t clientSize, StreamDescriptor::Reply* reply) {
- // Can switch the state to ERROR if a driver error occurs.
const size_t byteCount = std::min({clientSize, mDataMQ->availableToWrite(), mDataBufferSize});
const bool isConnected = mIsConnected;
+ size_t actualFrameCount = 0;
bool fatal = false;
- // Simulate reading of data, or provide zeroes if the stream is not connected.
- for (size_t i = 0; i < byteCount; ++i) {
- using buffer_type = decltype(mDataBuffer)::element_type;
- constexpr int kBufferValueRange = std::numeric_limits<buffer_type>::max() -
- std::numeric_limits<buffer_type>::min() + 1;
- mDataBuffer[i] = isConnected ? (std::rand() % kBufferValueRange) +
- std::numeric_limits<buffer_type>::min()
- : 0;
+ int32_t latency = Module::kLatencyMs;
+ if (isConnected) {
+ if (::android::status_t status = mDriver->transfer(
+ mDataBuffer.get(), byteCount / mFrameSize, &actualFrameCount, &latency);
+ status != ::android::OK) {
+ fatal = true;
+ LOG(ERROR) << __func__ << ": read failed: " << status;
+ }
+ } else {
+ usleep(3000); // Simulate blocking transfer delay.
+ for (size_t i = 0; i < byteCount; ++i) mDataBuffer[i] = 0;
+ actualFrameCount = byteCount / mFrameSize;
}
- usleep(3000); // Simulate a blocking call into the driver.
- // Set 'fatal = true' if a driver error occurs.
- if (bool success = byteCount > 0 ? mDataMQ->write(&mDataBuffer[0], byteCount) : true; success) {
- LOG(DEBUG) << __func__ << ": writing of " << byteCount << " bytes into data MQ"
+ const size_t actualByteCount = actualFrameCount * mFrameSize;
+ if (bool success =
+ actualByteCount > 0 ? mDataMQ->write(&mDataBuffer[0], actualByteCount) : true;
+ success) {
+ LOG(DEBUG) << __func__ << ": writing of " << actualByteCount << " bytes into data MQ"
<< " succeeded; connected? " << isConnected;
// Frames are provided and counted regardless of connection status.
- reply->fmqByteCount += byteCount;
- mFrameCount += byteCount / mFrameSize;
+ reply->fmqByteCount += actualByteCount;
+ mFrameCount += actualFrameCount;
populateReply(reply, isConnected);
} else {
- LOG(WARNING) << __func__ << ": writing of " << byteCount << " bytes of data to MQ failed";
+ LOG(WARNING) << __func__ << ": writing of " << actualByteCount
+ << " bytes of data to MQ failed";
reply->status = STATUS_NOT_ENOUGH_DATA;
}
- reply->latencyMs = Module::kLatencyMs;
+ reply->latencyMs = latency;
return !fatal;
}
@@ -395,14 +417,23 @@
}
break;
case Tag::drain:
- if (command.get<Tag::drain>() == StreamDescriptor::DrainMode::DRAIN_ALL ||
- command.get<Tag::drain>() == StreamDescriptor::DrainMode::DRAIN_EARLY_NOTIFY) {
+ if (const auto mode = command.get<Tag::drain>();
+ mode == StreamDescriptor::DrainMode::DRAIN_ALL ||
+ mode == StreamDescriptor::DrainMode::DRAIN_EARLY_NOTIFY) {
if (mState == StreamDescriptor::State::ACTIVE ||
mState == StreamDescriptor::State::TRANSFERRING) {
- usleep(1000); // Simulate a blocking call into the driver.
- populateReply(&reply, mIsConnected);
- // Can switch the state to ERROR if a driver error occurs.
- switchToTransientState(StreamDescriptor::State::DRAINING);
+ if (::android::status_t status = mDriver->drain(mode);
+ status == ::android::OK) {
+ populateReply(&reply, mIsConnected);
+ if (mState == StreamDescriptor::State::ACTIVE && mForceSynchronousDrain) {
+ mState = StreamDescriptor::State::IDLE;
+ } else {
+ switchToTransientState(StreamDescriptor::State::DRAINING);
+ }
+ } else {
+ LOG(ERROR) << __func__ << ": drain failed: " << status;
+ mState = StreamDescriptor::State::ERROR;
+ }
} else if (mState == StreamDescriptor::State::TRANSFER_PAUSED) {
mState = StreamDescriptor::State::DRAIN_PAUSED;
populateReply(&reply, mIsConnected);
@@ -410,46 +441,58 @@
populateReplyWrongState(&reply, command);
}
} else {
- LOG(WARNING) << __func__
- << ": invalid drain mode: " << toString(command.get<Tag::drain>());
+ LOG(WARNING) << __func__ << ": invalid drain mode: " << toString(mode);
}
break;
case Tag::standby:
if (mState == StreamDescriptor::State::IDLE) {
- usleep(1000); // Simulate a blocking call into the driver.
- populateReply(&reply, mIsConnected);
- // Can switch the state to ERROR if a driver error occurs.
- mState = StreamDescriptor::State::STANDBY;
+ if (::android::status_t status = mDriver->standby(); status == ::android::OK) {
+ populateReply(&reply, mIsConnected);
+ mState = StreamDescriptor::State::STANDBY;
+ } else {
+ LOG(ERROR) << __func__ << ": standby failed: " << status;
+ mState = StreamDescriptor::State::ERROR;
+ }
} else {
populateReplyWrongState(&reply, command);
}
break;
case Tag::pause: {
- bool commandAccepted = true;
+ std::optional<StreamDescriptor::State> nextState;
switch (mState) {
case StreamDescriptor::State::ACTIVE:
- mState = StreamDescriptor::State::PAUSED;
+ nextState = StreamDescriptor::State::PAUSED;
break;
case StreamDescriptor::State::DRAINING:
- mState = StreamDescriptor::State::DRAIN_PAUSED;
+ nextState = StreamDescriptor::State::DRAIN_PAUSED;
break;
case StreamDescriptor::State::TRANSFERRING:
- mState = StreamDescriptor::State::TRANSFER_PAUSED;
+ nextState = StreamDescriptor::State::TRANSFER_PAUSED;
break;
default:
populateReplyWrongState(&reply, command);
- commandAccepted = false;
}
- if (commandAccepted) {
- populateReply(&reply, mIsConnected);
+ if (nextState.has_value()) {
+ if (::android::status_t status = mDriver->pause(); status == ::android::OK) {
+ populateReply(&reply, mIsConnected);
+ mState = nextState.value();
+ } else {
+ LOG(ERROR) << __func__ << ": pause failed: " << status;
+ mState = StreamDescriptor::State::ERROR;
+ }
}
} break;
case Tag::flush:
if (mState == StreamDescriptor::State::PAUSED ||
mState == StreamDescriptor::State::DRAIN_PAUSED ||
mState == StreamDescriptor::State::TRANSFER_PAUSED) {
- populateReply(&reply, mIsConnected);
- mState = StreamDescriptor::State::IDLE;
+ if (::android::status_t status = mDriver->flush(); status == ::android::OK) {
+ populateReply(&reply, mIsConnected);
+ mState = StreamDescriptor::State::IDLE;
+ } else {
+ LOG(ERROR) << __func__ << ": flush failed: " << status;
+ mState = StreamDescriptor::State::ERROR;
+ }
} else {
populateReplyWrongState(&reply, command);
}
@@ -467,30 +510,49 @@
bool StreamOutWorkerLogic::write(size_t clientSize, StreamDescriptor::Reply* reply) {
const size_t readByteCount = mDataMQ->availableToRead();
- // Amount of data that the HAL module is going to actually use.
- const size_t byteCount = std::min({clientSize, readByteCount, mDataBufferSize});
bool fatal = false;
+ int32_t latency = Module::kLatencyMs;
if (bool success = readByteCount > 0 ? mDataMQ->read(&mDataBuffer[0], readByteCount) : true) {
const bool isConnected = mIsConnected;
LOG(DEBUG) << __func__ << ": reading of " << readByteCount << " bytes from data MQ"
<< " succeeded; connected? " << isConnected;
- // Frames are consumed and counted regardless of connection status.
- reply->fmqByteCount += byteCount;
- mFrameCount += byteCount / mFrameSize;
+ // Amount of data that the HAL module is going to actually use.
+ size_t byteCount = std::min({clientSize, readByteCount, mDataBufferSize});
+ if (byteCount >= mFrameSize && mForceTransientBurst) {
+ // In order to prevent the state machine from going to ACTIVE state,
+ // simulate partial write.
+ byteCount -= mFrameSize;
+ }
+ size_t actualFrameCount = 0;
+ if (isConnected) {
+ if (::android::status_t status = mDriver->transfer(
+ mDataBuffer.get(), byteCount / mFrameSize, &actualFrameCount, &latency);
+ status != ::android::OK) {
+ fatal = true;
+ LOG(ERROR) << __func__ << ": write failed: " << status;
+ }
+ } else {
+ if (mAsyncCallback == nullptr) {
+ usleep(3000); // Simulate blocking transfer delay.
+ }
+ actualFrameCount = byteCount / mFrameSize;
+ }
+ const size_t actualByteCount = actualFrameCount * mFrameSize;
+ // Frames are consumed and counted regardless of the connection status.
+ reply->fmqByteCount += actualByteCount;
+ mFrameCount += actualFrameCount;
populateReply(reply, isConnected);
- usleep(3000); // Simulate a blocking call into the driver.
- // Set 'fatal = true' if a driver error occurs.
} else {
LOG(WARNING) << __func__ << ": reading of " << readByteCount
<< " bytes of data from MQ failed";
reply->status = STATUS_NOT_ENOUGH_DATA;
}
- reply->latencyMs = Module::kLatencyMs;
+ reply->latencyMs = latency;
return !fatal;
}
-template <class Metadata, class StreamWorker>
-StreamCommonImpl<Metadata, StreamWorker>::~StreamCommonImpl() {
+template <class Metadata>
+StreamCommonImpl<Metadata>::~StreamCommonImpl() {
if (!isClosed()) {
LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak";
stopWorker();
@@ -498,8 +560,8 @@
}
}
-template <class Metadata, class StreamWorker>
-void StreamCommonImpl<Metadata, StreamWorker>::createStreamCommon(
+template <class Metadata>
+void StreamCommonImpl<Metadata>::createStreamCommon(
const std::shared_ptr<StreamCommonInterface>& delegate) {
if (mCommon != nullptr) {
LOG(FATAL) << __func__ << ": attempting to create the common interface twice";
@@ -509,8 +571,8 @@
AIBinder_setMinSchedulerPolicy(mCommonBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
}
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::getStreamCommon(
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::getStreamCommon(
std::shared_ptr<IStreamCommon>* _aidl_return) {
if (mCommon == nullptr) {
LOG(FATAL) << __func__ << ": the common interface was not created";
@@ -520,31 +582,30 @@
return ndk::ScopedAStatus::ok();
}
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::updateHwAvSyncId(
- int32_t in_hwAvSyncId) {
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateHwAvSyncId(int32_t in_hwAvSyncId) {
LOG(DEBUG) << __func__ << ": id " << in_hwAvSyncId;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::getVendorParameters(
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::getVendorParameters(
const std::vector<std::string>& in_ids, std::vector<VendorParameter>* _aidl_return) {
LOG(DEBUG) << __func__ << ": id count: " << in_ids.size();
(void)_aidl_return;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::setVendorParameters(
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::setVendorParameters(
const std::vector<VendorParameter>& in_parameters, bool in_async) {
LOG(DEBUG) << __func__ << ": parameters count " << in_parameters.size()
<< ", async: " << in_async;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::addEffect(
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::addEffect(
const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
if (in_effect == nullptr) {
LOG(DEBUG) << __func__ << ": null effect";
@@ -554,8 +615,8 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::removeEffect(
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::removeEffect(
const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
if (in_effect == nullptr) {
LOG(DEBUG) << __func__ << ": null effect";
@@ -565,16 +626,16 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::close() {
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::close() {
LOG(DEBUG) << __func__;
if (!isClosed()) {
stopWorker();
LOG(DEBUG) << __func__ << ": joining the worker thread...";
- mWorker.stop();
+ mWorker->stop();
LOG(DEBUG) << __func__ << ": worker thread joined";
mContext.reset();
- mWorker.setClosed();
+ mWorker->setClosed();
return ndk::ScopedAStatus::ok();
} else {
LOG(ERROR) << __func__ << ": stream was already closed";
@@ -582,8 +643,8 @@
}
}
-template <class Metadata, class StreamWorker>
-void StreamCommonImpl<Metadata, StreamWorker>::stopWorker() {
+template <class Metadata>
+void StreamCommonImpl<Metadata>::stopWorker() {
if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) {
LOG(DEBUG) << __func__ << ": asking the worker to exit...";
auto cmd = StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::halReservedExit>(
@@ -599,9 +660,8 @@
}
}
-template <class Metadata, class StreamWorker>
-ndk::ScopedAStatus StreamCommonImpl<Metadata, StreamWorker>::updateMetadata(
- const Metadata& metadata) {
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateMetadata(const Metadata& metadata) {
LOG(DEBUG) << __func__;
if (!isClosed()) {
mMetadata = metadata;
@@ -612,16 +672,11 @@
}
// static
-ndk::ScopedAStatus StreamIn::createInstance(const common::SinkMetadata& sinkMetadata,
- StreamContext context,
- const std::vector<MicrophoneInfo>& microphones,
- std::shared_ptr<StreamIn>* result) {
- auto stream = ndk::SharedRefBase::make<StreamIn>(sinkMetadata, std::move(context), microphones);
+ndk::ScopedAStatus StreamIn::initInstance(const std::shared_ptr<StreamIn>& stream) {
if (auto status = stream->init(); !status.isOk()) {
return status;
}
stream->createStreamCommon(stream);
- *result = std::move(stream);
return ndk::ScopedAStatus::ok();
}
@@ -636,8 +691,10 @@
} // namespace
StreamIn::StreamIn(const SinkMetadata& sinkMetadata, StreamContext&& context,
+ const DriverInterface::CreateInstance& createDriver,
+ const StreamWorkerInterface::CreateInstance& createWorker,
const std::vector<MicrophoneInfo>& microphones)
- : StreamCommonImpl<SinkMetadata, StreamInWorker>(sinkMetadata, std::move(context)),
+ : StreamCommonImpl<SinkMetadata>(sinkMetadata, std::move(context), createDriver, createWorker),
mMicrophones(transformMicrophones(microphones)) {
LOG(DEBUG) << __func__;
}
@@ -695,23 +752,20 @@
}
// static
-ndk::ScopedAStatus StreamOut::createInstance(const SourceMetadata& sourceMetadata,
- StreamContext context,
- const std::optional<AudioOffloadInfo>& offloadInfo,
- std::shared_ptr<StreamOut>* result) {
- auto stream =
- ndk::SharedRefBase::make<StreamOut>(sourceMetadata, std::move(context), offloadInfo);
+ndk::ScopedAStatus StreamOut::initInstance(const std::shared_ptr<StreamOut>& stream) {
if (auto status = stream->init(); !status.isOk()) {
return status;
}
stream->createStreamCommon(stream);
- *result = std::move(stream);
return ndk::ScopedAStatus::ok();
}
StreamOut::StreamOut(const SourceMetadata& sourceMetadata, StreamContext&& context,
+ const DriverInterface::CreateInstance& createDriver,
+ const StreamWorkerInterface::CreateInstance& createWorker,
const std::optional<AudioOffloadInfo>& offloadInfo)
- : StreamCommonImpl<SourceMetadata, StreamOutWorker>(sourceMetadata, std::move(context)),
+ : StreamCommonImpl<SourceMetadata>(sourceMetadata, std::move(context), createDriver,
+ createWorker),
mOffloadInfo(offloadInfo) {
LOG(DEBUG) << __func__;
}
diff --git a/audio/aidl/default/StreamStub.cpp b/audio/aidl/default/StreamStub.cpp
new file mode 100644
index 0000000..5442179
--- /dev/null
+++ b/audio/aidl/default/StreamStub.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_Stream"
+#include <android-base/logging.h>
+
+#include "core-impl/Module.h"
+#include "core-impl/StreamStub.h"
+
+using aidl::android::hardware::audio::common::SinkMetadata;
+using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::media::audio::common::AudioOffloadInfo;
+
+namespace aidl::android::hardware::audio::core {
+
+DriverStub::DriverStub(const StreamContext& context, bool isInput)
+ : mFrameSizeBytes(context.getFrameSize()), mIsInput(isInput) {}
+
+::android::status_t DriverStub::init() {
+ usleep(1000);
+ return ::android::OK;
+}
+
+::android::status_t DriverStub::drain(StreamDescriptor::DrainMode) {
+ usleep(1000);
+ return ::android::OK;
+}
+
+::android::status_t DriverStub::flush() {
+ usleep(1000);
+ return ::android::OK;
+}
+
+::android::status_t DriverStub::pause() {
+ usleep(1000);
+ return ::android::OK;
+}
+
+::android::status_t DriverStub::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+ int32_t* latencyMs) {
+ usleep(3000);
+ if (mIsInput) {
+ uint8_t* byteBuffer = static_cast<uint8_t*>(buffer);
+ for (size_t i = 0; i < frameCount * mFrameSizeBytes; ++i) {
+ byteBuffer[i] = std::rand() % 255;
+ }
+ }
+ *actualFrameCount = frameCount;
+ *latencyMs = Module::kLatencyMs;
+ return ::android::OK;
+}
+
+::android::status_t DriverStub::standby() {
+ usleep(1000);
+ return ::android::OK;
+}
+
+// static
+ndk::ScopedAStatus StreamInStub::createInstance(const SinkMetadata& sinkMetadata,
+ StreamContext&& context,
+ const std::vector<MicrophoneInfo>& microphones,
+ std::shared_ptr<StreamIn>* result) {
+ std::shared_ptr<StreamIn> stream =
+ ndk::SharedRefBase::make<StreamInStub>(sinkMetadata, std::move(context), microphones);
+ if (auto status = initInstance(stream); !status.isOk()) {
+ return status;
+ }
+ *result = std::move(stream);
+ return ndk::ScopedAStatus::ok();
+}
+
+StreamInStub::StreamInStub(const SinkMetadata& sinkMetadata, StreamContext&& context,
+ const std::vector<MicrophoneInfo>& microphones)
+ : StreamIn(
+ sinkMetadata, std::move(context),
+ [](const StreamContext& ctx) -> DriverInterface* {
+ return new DriverStub(ctx, true /*isInput*/);
+ },
+ [](const StreamContext& ctx, DriverInterface* driver) -> StreamWorkerInterface* {
+ // The default worker implementation is used.
+ return new StreamInWorker(ctx, driver);
+ },
+ microphones) {}
+
+// static
+ndk::ScopedAStatus StreamOutStub::createInstance(const SourceMetadata& sourceMetadata,
+ StreamContext&& context,
+ const std::optional<AudioOffloadInfo>& offloadInfo,
+ std::shared_ptr<StreamOut>* result) {
+ std::shared_ptr<StreamOut> stream = ndk::SharedRefBase::make<StreamOutStub>(
+ sourceMetadata, std::move(context), offloadInfo);
+ if (auto status = initInstance(stream); !status.isOk()) {
+ return status;
+ }
+ *result = std::move(stream);
+ return ndk::ScopedAStatus::ok();
+}
+
+StreamOutStub::StreamOutStub(const SourceMetadata& sourceMetadata, StreamContext&& context,
+ const std::optional<AudioOffloadInfo>& offloadInfo)
+ : StreamOut(
+ sourceMetadata, std::move(context),
+ [](const StreamContext& ctx) -> DriverInterface* {
+ return new DriverStub(ctx, false /*isInput*/);
+ },
+ [](const StreamContext& ctx, DriverInterface* driver) -> StreamWorkerInterface* {
+ // The default worker implementation is used.
+ return new StreamOutWorker(ctx, driver);
+ },
+ offloadInfo) {}
+
+} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index e460f89..6714a7e 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -40,6 +40,7 @@
<library name="nssw" path="libnssw.so"/>
<library name="env_reverbsw" path="libenvreverbsw.so"/>
<library name="preset_reverbsw" path="libpresetreverbsw.so"/>
+ <library name="reverb" path="libreverbaidl.so"/>
<library name="virtualizersw" path="libvirtualizersw.so"/>
<library name="visualizer" path="libvisualizeraidl.so"/>
<library name="volumesw" path="libvolumesw.so"/>
@@ -78,6 +79,10 @@
<effect name="env_reverb" library="env_reverbsw" uuid="fa819886-588b-11ed-9b6a-0242ac120002"/>
<effect name="noise_suppression" library="nssw" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
<effect name="preset_reverb" library="preset_reverbsw" uuid="fa8199c6-588b-11ed-9b6a-0242ac120002"/>
+ <effect name="reverb_env_aux" library="reverb" uuid="4a387fc0-8ab3-11df-8bad-0002a5d5c51b"/>
+ <effect name="reverb_env_ins" library="reverb" uuid="c7a511a0-a3bb-11df-860e-0002a5d5c51b"/>
+ <effect name="reverb_pre_aux" library="reverb" uuid="f29a1400-a3bb-11df-8ddc-0002a5d5c51b"/>
+ <effect name="reverb_pre_ins" library="reverb" uuid="172cdf00-a3bc-11df-a72f-0002a5d5c51b"/>
<effectProxy name="virtualizer" uuid="d3467faa-acc7-4d34-acaf-0002a5d5c51b">
<libsw library="virtualizersw" uuid="fa819d86-588b-11ed-9b6a-0242ac120002"/>
<libsw library="bundle" uuid="1d4033c0-8557-11df-9f2d-0002a5d5c51b"/>
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.cpp b/audio/aidl/default/envReverb/EnvReverbSw.cpp
index 9d7159a..905dba4 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.cpp
+++ b/audio/aidl/default/envReverb/EnvReverbSw.cpp
@@ -60,8 +60,18 @@
namespace aidl::android::hardware::audio::effect {
const std::string EnvReverbSw::kEffectName = "EnvReverbSw";
-const EnvironmentalReverb::Capability EnvReverbSw::kCapability = {
- .maxDecayTimeMs = EnvironmentalReverb::MAX_DECAY_TIME_MS};
+const EnvironmentalReverb::Capability EnvReverbSw::kCapability = {.minRoomLevelMb = -6000,
+ .maxRoomLevelMb = 0,
+ .minRoomHfLevelMb = -4000,
+ .maxRoomHfLevelMb = 0,
+ .maxDecayTimeMs = 7000,
+ .minDecayHfRatioPm = 100,
+ .maxDecayHfRatioPm = 2000,
+ .minLevelMb = -6000,
+ .maxLevelMb = 0,
+ .maxDelayMs = 65,
+ .maxDiffusionPm = 1000,
+ .maxDensityPm = 1000};
const Descriptor EnvReverbSw::kDescriptor = {
.common = {.id = {.type = kEnvReverbTypeUUID,
.uuid = kEnvReverbSwImplUUID,
@@ -251,4 +261,88 @@
return {STATUS_OK, samples, samples};
}
+RetCode EnvReverbSwContext::setErRoomLevel(int roomLevel) {
+ if (roomLevel < EnvReverbSw::kCapability.minRoomLevelMb ||
+ roomLevel > EnvReverbSw::kCapability.maxRoomLevelMb) {
+ LOG(ERROR) << __func__ << " invalid roomLevel: " << roomLevel;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ // TODO : Add implementation to apply new room level
+ mRoomLevel = roomLevel;
+ return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErRoomHfLevel(int roomHfLevel) {
+ if (roomHfLevel < EnvReverbSw::kCapability.minRoomHfLevelMb ||
+ roomHfLevel > EnvReverbSw::kCapability.maxRoomHfLevelMb) {
+ LOG(ERROR) << __func__ << " invalid roomHfLevel: " << roomHfLevel;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ // TODO : Add implementation to apply new room HF level
+ mRoomHfLevel = roomHfLevel;
+ return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDecayTime(int decayTime) {
+ if (decayTime < 0 || decayTime > EnvReverbSw::kCapability.maxDecayTimeMs) {
+ LOG(ERROR) << __func__ << " invalid decayTime: " << decayTime;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ // TODO : Add implementation to apply new decay time
+ mDecayTime = decayTime;
+ return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDecayHfRatio(int decayHfRatio) {
+ if (decayHfRatio < EnvReverbSw::kCapability.minDecayHfRatioPm ||
+ decayHfRatio > EnvReverbSw::kCapability.maxDecayHfRatioPm) {
+ LOG(ERROR) << __func__ << " invalid decayHfRatio: " << decayHfRatio;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ // TODO : Add implementation to apply new decay HF ratio
+ mDecayHfRatio = decayHfRatio;
+ return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErLevel(int level) {
+ if (level < EnvReverbSw::kCapability.minLevelMb ||
+ level > EnvReverbSw::kCapability.maxLevelMb) {
+ LOG(ERROR) << __func__ << " invalid level: " << level;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ // TODO : Add implementation to apply new level
+ mLevel = level;
+ return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDelay(int delay) {
+ if (delay < 0 || delay > EnvReverbSw::kCapability.maxDelayMs) {
+ LOG(ERROR) << __func__ << " invalid delay: " << delay;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ // TODO : Add implementation to apply new delay
+ mDelay = delay;
+ return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDiffusion(int diffusion) {
+ if (diffusion < 0 || diffusion > EnvReverbSw::kCapability.maxDiffusionPm) {
+ LOG(ERROR) << __func__ << " invalid diffusion: " << diffusion;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ // TODO : Add implementation to apply new diffusion
+ mDiffusion = diffusion;
+ return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDensity(int density) {
+ if (density < 0 || density > EnvReverbSw::kCapability.maxDensityPm) {
+ LOG(ERROR) << __func__ << " invalid density: " << density;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ // TODO : Add implementation to apply new density
+ mDensity = density;
+ return RetCode::SUCCESS;
+}
+
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.h b/audio/aidl/default/envReverb/EnvReverbSw.h
index f521215..77f384e 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.h
+++ b/audio/aidl/default/envReverb/EnvReverbSw.h
@@ -33,100 +33,28 @@
LOG(DEBUG) << __func__;
}
- RetCode setErRoomLevel(int roomLevel) {
- if (roomLevel < EnvironmentalReverb::MIN_ROOM_LEVEL_MB ||
- roomLevel > EnvironmentalReverb::MAX_ROOM_LEVEL_MB) {
- LOG(ERROR) << __func__ << " invalid roomLevel: " << roomLevel;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new room level
- mRoomLevel = roomLevel;
- return RetCode::SUCCESS;
- }
+ RetCode setErRoomLevel(int roomLevel);
int getErRoomLevel() const { return mRoomLevel; }
- RetCode setErRoomHfLevel(int roomHfLevel) {
- if (roomHfLevel < EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB ||
- roomHfLevel > EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB) {
- LOG(ERROR) << __func__ << " invalid roomHfLevel: " << roomHfLevel;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new room HF level
- mRoomHfLevel = roomHfLevel;
- return RetCode::SUCCESS;
- }
+ RetCode setErRoomHfLevel(int roomHfLevel);
int getErRoomHfLevel() const { return mRoomHfLevel; }
- RetCode setErDecayTime(int decayTime) {
- if (decayTime < EnvironmentalReverb::MIN_DECAY_TIME_MS ||
- decayTime > EnvironmentalReverb::MAX_DECAY_TIME_MS) {
- LOG(ERROR) << __func__ << " invalid decayTime: " << decayTime;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new decay time
- mDecayTime = decayTime;
- return RetCode::SUCCESS;
- }
+ RetCode setErDecayTime(int decayTime);
int getErDecayTime() const { return mDecayTime; }
- RetCode setErDecayHfRatio(int decayHfRatio) {
- if (decayHfRatio < EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM ||
- decayHfRatio > EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM) {
- LOG(ERROR) << __func__ << " invalid decayHfRatio: " << decayHfRatio;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new decay HF ratio
- mDecayHfRatio = decayHfRatio;
- return RetCode::SUCCESS;
- }
+ RetCode setErDecayHfRatio(int decayHfRatio);
int getErDecayHfRatio() const { return mDecayHfRatio; }
- RetCode setErLevel(int level) {
- if (level < EnvironmentalReverb::MIN_LEVEL_MB ||
- level > EnvironmentalReverb::MAX_LEVEL_MB) {
- LOG(ERROR) << __func__ << " invalid level: " << level;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new level
- mLevel = level;
- return RetCode::SUCCESS;
- }
+ RetCode setErLevel(int level);
int getErLevel() const { return mLevel; }
- RetCode setErDelay(int delay) {
- if (delay < EnvironmentalReverb::MIN_DELAY_MS ||
- delay > EnvironmentalReverb::MAX_DELAY_MS) {
- LOG(ERROR) << __func__ << " invalid delay: " << delay;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new delay
- mDelay = delay;
- return RetCode::SUCCESS;
- }
+ RetCode setErDelay(int delay);
int getErDelay() const { return mDelay; }
- RetCode setErDiffusion(int diffusion) {
- if (diffusion < EnvironmentalReverb::MIN_DIFFUSION_PM ||
- diffusion > EnvironmentalReverb::MAX_DIFFUSION_PM) {
- LOG(ERROR) << __func__ << " invalid diffusion: " << diffusion;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new diffusion
- mDiffusion = diffusion;
- return RetCode::SUCCESS;
- }
+ RetCode setErDiffusion(int diffusion);
int getErDiffusion() const { return mDiffusion; }
- RetCode setErDensity(int density) {
- if (density < EnvironmentalReverb::MIN_DENSITY_PM ||
- density > EnvironmentalReverb::MAX_DENSITY_PM) {
- LOG(ERROR) << __func__ << " invalid density: " << density;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new density
- mDensity = density;
- return RetCode::SUCCESS;
- }
+ RetCode setErDensity(int density);
int getErDensity() const { return mDensity; }
RetCode setErBypass(bool bypass) {
@@ -137,14 +65,14 @@
bool getErBypass() const { return mBypass; }
private:
- int mRoomLevel = EnvironmentalReverb::MIN_ROOM_LEVEL_MB; // Default room level
- int mRoomHfLevel = EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB; // Default room hf level
+ int mRoomLevel = -6000; // Default room level
+ int mRoomHfLevel = 0; // Default room hf level
int mDecayTime = 1000; // Default decay time
int mDecayHfRatio = 500; // Default decay hf ratio
- int mLevel = EnvironmentalReverb::MIN_LEVEL_MB; // Default level
+ int mLevel = -6000; // Default level
int mDelay = 40; // Default delay
- int mDiffusion = EnvironmentalReverb::MAX_DIFFUSION_PM; // Default diffusion
- int mDensity = EnvironmentalReverb::MAX_DENSITY_PM; // Default density
+ int mDiffusion = 1000; // Default diffusion
+ int mDensity = 1000; // Default density
bool mBypass = false; // Default bypass
};
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index e9f43d8..9e4499b 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -36,6 +36,13 @@
explicit Module(Type type) : mType(type) {}
private:
+ struct VendorDebug {
+ static const std::string kForceTransientBurstName;
+ static const std::string kForceSynchronousDrainName;
+ bool forceTransientBurst = false;
+ bool forceSynchronousDrain = false;
+ };
+
ndk::ScopedAStatus setModuleDebug(
const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) override;
ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
@@ -108,6 +115,7 @@
ndk::ScopedAStatus createStreamContext(
int32_t in_portConfigId, int64_t in_bufferSizeFrames,
std::shared_ptr<IStreamCallback> asyncCallback,
+ std::shared_ptr<IStreamOutEventCallback> outEventCallback,
::aidl::android::hardware::audio::core::StreamContext* out_context);
std::vector<::aidl::android::media::audio::common::AudioDevice> findConnectedDevices(
int32_t portConfigId);
@@ -128,6 +136,7 @@
const Type mType;
std::unique_ptr<internal::Configuration> mConfig;
ModuleDebug mDebug;
+ VendorDebug mVendorDebug;
// For the interfaces requiring to return the same instance, we need to hold them
// via a strong pointer. The binder token is retained for a call to 'setMinSchedulerPolicy'.
std::shared_ptr<ITelephony> mTelephony;
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index 5abd4de..7cd4259 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -31,12 +31,14 @@
#include <aidl/android/hardware/audio/core/BnStreamIn.h>
#include <aidl/android/hardware/audio/core/BnStreamOut.h>
#include <aidl/android/hardware/audio/core/IStreamCallback.h>
+#include <aidl/android/hardware/audio/core/IStreamOutEventCallback.h>
#include <aidl/android/hardware/audio/core/MicrophoneInfo.h>
#include <aidl/android/hardware/audio/core/StreamDescriptor.h>
#include <aidl/android/media/audio/common/AudioDevice.h>
#include <aidl/android/media/audio/common/AudioOffloadInfo.h>
#include <fmq/AidlMessageQueue.h>
#include <system/thread_defs.h>
+#include <utils/Errors.h>
#include "core-impl/utils.h"
@@ -62,12 +64,22 @@
// Ensure that this value is not used by any of StreamDescriptor.State enums
static constexpr int32_t STATE_CLOSED = -1;
+ struct DebugParameters {
+ // An extra delay for transient states, in ms.
+ int transientStateDelayMs = 0;
+ // Force the "burst" command to move the SM to the TRANSFERRING state.
+ bool forceTransientBurst = false;
+ // Force the "drain" command to be synchronous, going directly to the IDLE state.
+ bool forceSynchronousDrain = false;
+ };
+
StreamContext() = default;
StreamContext(std::unique_ptr<CommandMQ> commandMQ, std::unique_ptr<ReplyMQ> replyMQ,
const ::aidl::android::media::audio::common::AudioFormatDescription& format,
const ::aidl::android::media::audio::common::AudioChannelLayout& channelLayout,
std::unique_ptr<DataMQ> dataMQ, std::shared_ptr<IStreamCallback> asyncCallback,
- int transientStateDelayMs)
+ std::shared_ptr<IStreamOutEventCallback> outEventCallback,
+ DebugParameters debugParameters)
: mCommandMQ(std::move(commandMQ)),
mInternalCommandCookie(std::rand()),
mReplyMQ(std::move(replyMQ)),
@@ -75,7 +87,8 @@
mChannelLayout(channelLayout),
mDataMQ(std::move(dataMQ)),
mAsyncCallback(asyncCallback),
- mTransientStateDelayMs(transientStateDelayMs) {}
+ mOutEventCallback(outEventCallback),
+ mDebugParameters(debugParameters) {}
StreamContext(StreamContext&& other)
: mCommandMQ(std::move(other.mCommandMQ)),
mInternalCommandCookie(other.mInternalCommandCookie),
@@ -83,8 +96,9 @@
mFormat(other.mFormat),
mChannelLayout(other.mChannelLayout),
mDataMQ(std::move(other.mDataMQ)),
- mAsyncCallback(other.mAsyncCallback),
- mTransientStateDelayMs(other.mTransientStateDelayMs) {}
+ mAsyncCallback(std::move(other.mAsyncCallback)),
+ mOutEventCallback(std::move(other.mOutEventCallback)),
+ mDebugParameters(std::move(other.mDebugParameters)) {}
StreamContext& operator=(StreamContext&& other) {
mCommandMQ = std::move(other.mCommandMQ);
mInternalCommandCookie = other.mInternalCommandCookie;
@@ -92,8 +106,9 @@
mFormat = std::move(other.mFormat);
mChannelLayout = std::move(other.mChannelLayout);
mDataMQ = std::move(other.mDataMQ);
- mAsyncCallback = other.mAsyncCallback;
- mTransientStateDelayMs = other.mTransientStateDelayMs;
+ mAsyncCallback = std::move(other.mAsyncCallback);
+ mOutEventCallback = std::move(other.mOutEventCallback);
+ mDebugParameters = std::move(other.mDebugParameters);
return *this;
}
@@ -107,10 +122,15 @@
::aidl::android::media::audio::common::AudioFormatDescription getFormat() const {
return mFormat;
}
+ bool getForceTransientBurst() const { return mDebugParameters.forceTransientBurst; }
+ bool getForceSynchronousDrain() const { return mDebugParameters.forceSynchronousDrain; }
size_t getFrameSize() const;
int getInternalCommandCookie() const { return mInternalCommandCookie; }
+ std::shared_ptr<IStreamOutEventCallback> getOutEventCallback() const {
+ return mOutEventCallback;
+ }
ReplyMQ* getReplyMQ() const { return mReplyMQ.get(); }
- int getTransientStateDelayMs() const { return mTransientStateDelayMs; }
+ int getTransientStateDelayMs() const { return mDebugParameters.transientStateDelayMs; }
bool isValid() const;
void reset();
@@ -122,7 +142,22 @@
::aidl::android::media::audio::common::AudioChannelLayout mChannelLayout;
std::unique_ptr<DataMQ> mDataMQ;
std::shared_ptr<IStreamCallback> mAsyncCallback;
- int mTransientStateDelayMs;
+ std::shared_ptr<IStreamOutEventCallback> mOutEventCallback; // Only used by output streams
+ DebugParameters mDebugParameters;
+};
+
+struct DriverInterface {
+ using CreateInstance = std::function<DriverInterface*(const StreamContext&)>;
+ virtual ~DriverInterface() = default;
+ // This function is called once, on the main thread, before starting the worker thread.
+ virtual ::android::status_t init() = 0;
+ // All the functions below are called on the worker thread.
+ virtual ::android::status_t drain(StreamDescriptor::DrainMode mode) = 0;
+ virtual ::android::status_t flush() = 0;
+ virtual ::android::status_t pause() = 0;
+ virtual ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+ int32_t* latencyMs) = 0;
+ virtual ::android::status_t standby() = 0;
};
class StreamWorkerCommonLogic : public ::android::hardware::audio::common::StreamLogic {
@@ -134,14 +169,19 @@
void setIsConnected(bool connected) { mIsConnected = connected; }
protected:
- explicit StreamWorkerCommonLogic(const StreamContext& context)
- : mInternalCommandCookie(context.getInternalCommandCookie()),
+ using DataBufferElement = int8_t;
+
+ StreamWorkerCommonLogic(const StreamContext& context, DriverInterface* driver)
+ : mDriver(driver),
+ mInternalCommandCookie(context.getInternalCommandCookie()),
mFrameSize(context.getFrameSize()),
mCommandMQ(context.getCommandMQ()),
mReplyMQ(context.getReplyMQ()),
mDataMQ(context.getDataMQ()),
mAsyncCallback(context.getAsyncCallback()),
- mTransientStateDelayMs(context.getTransientStateDelayMs()) {}
+ mTransientStateDelayMs(context.getTransientStateDelayMs()),
+ mForceTransientBurst(context.getForceTransientBurst()),
+ mForceSynchronousDrain(context.getForceSynchronousDrain()) {}
std::string init() override;
void populateReply(StreamDescriptor::Reply* reply, bool isConnected) const;
void populateReplyWrongState(StreamDescriptor::Reply* reply,
@@ -151,6 +191,7 @@
mTransientStateStart = std::chrono::steady_clock::now();
}
+ DriverInterface* const mDriver;
// Atomic fields are used both by the main and worker threads.
std::atomic<bool> mIsConnected = false;
static_assert(std::atomic<StreamDescriptor::State>::is_always_lock_free);
@@ -158,23 +199,56 @@
// All fields are used on the worker thread only.
const int mInternalCommandCookie;
const size_t mFrameSize;
- StreamContext::CommandMQ* mCommandMQ;
- StreamContext::ReplyMQ* mReplyMQ;
- StreamContext::DataMQ* mDataMQ;
+ StreamContext::CommandMQ* const mCommandMQ;
+ StreamContext::ReplyMQ* const mReplyMQ;
+ StreamContext::DataMQ* const mDataMQ;
std::shared_ptr<IStreamCallback> mAsyncCallback;
const std::chrono::duration<int, std::milli> mTransientStateDelayMs;
std::chrono::time_point<std::chrono::steady_clock> mTransientStateStart;
+ const bool mForceTransientBurst;
+ const bool mForceSynchronousDrain;
// We use an array and the "size" field instead of a vector to be able to detect
// memory allocation issues.
- std::unique_ptr<int8_t[]> mDataBuffer;
+ std::unique_ptr<DataBufferElement[]> mDataBuffer;
size_t mDataBufferSize;
long mFrameCount = 0;
};
+// This interface is used to decouple stream implementations from a concrete StreamWorker
+// implementation.
+struct StreamWorkerInterface {
+ using CreateInstance = std::function<StreamWorkerInterface*(const StreamContext& context,
+ DriverInterface* driver)>;
+ virtual ~StreamWorkerInterface() = default;
+ virtual bool isClosed() const = 0;
+ virtual void setIsConnected(bool isConnected) = 0;
+ virtual void setClosed() = 0;
+ virtual bool start() = 0;
+ virtual void stop() = 0;
+};
+
+template <class WorkerLogic>
+class StreamWorkerImpl : public StreamWorkerInterface,
+ public ::android::hardware::audio::common::StreamWorker<WorkerLogic> {
+ using WorkerImpl = ::android::hardware::audio::common::StreamWorker<WorkerLogic>;
+
+ public:
+ StreamWorkerImpl(const StreamContext& context, DriverInterface* driver)
+ : WorkerImpl(context, driver) {}
+ bool isClosed() const override { return WorkerImpl::isClosed(); }
+ void setIsConnected(bool isConnected) override { WorkerImpl::setIsConnected(isConnected); }
+ void setClosed() override { WorkerImpl::setClosed(); }
+ bool start() override {
+ return WorkerImpl::start(WorkerImpl::kThreadName, ANDROID_PRIORITY_AUDIO);
+ }
+ void stop() override { return WorkerImpl::stop(); }
+};
+
class StreamInWorkerLogic : public StreamWorkerCommonLogic {
public:
static const std::string kThreadName;
- explicit StreamInWorkerLogic(const StreamContext& context) : StreamWorkerCommonLogic(context) {}
+ StreamInWorkerLogic(const StreamContext& context, DriverInterface* driver)
+ : StreamWorkerCommonLogic(context, driver) {}
protected:
Status cycle() override;
@@ -182,21 +256,23 @@
private:
bool read(size_t clientSize, StreamDescriptor::Reply* reply);
};
-using StreamInWorker = ::android::hardware::audio::common::StreamWorker<StreamInWorkerLogic>;
+using StreamInWorker = StreamWorkerImpl<StreamInWorkerLogic>;
class StreamOutWorkerLogic : public StreamWorkerCommonLogic {
public:
static const std::string kThreadName;
- explicit StreamOutWorkerLogic(const StreamContext& context)
- : StreamWorkerCommonLogic(context) {}
+ StreamOutWorkerLogic(const StreamContext& context, DriverInterface* driver)
+ : StreamWorkerCommonLogic(context, driver), mEventCallback(context.getOutEventCallback()) {}
protected:
Status cycle() override;
private:
bool write(size_t clientSize, StreamDescriptor::Reply* reply);
+
+ std::shared_ptr<IStreamOutEventCallback> mEventCallback;
};
-using StreamOutWorker = ::android::hardware::audio::common::StreamWorker<StreamOutWorkerLogic>;
+using StreamOutWorker = StreamWorkerImpl<StreamOutWorkerLogic>;
// This provides a C++ interface with methods of the IStreamCommon Binder interface,
// but intentionally does not inherit from it. This is needed to avoid inheriting
@@ -268,7 +344,7 @@
std::weak_ptr<StreamCommonInterface> mDelegate;
};
-template <class Metadata, class StreamWorker>
+template <class Metadata>
class StreamCommonImpl : public StreamCommonInterface {
public:
ndk::ScopedAStatus close() override;
@@ -286,21 +362,25 @@
ndk::ScopedAStatus getStreamCommon(std::shared_ptr<IStreamCommon>* _aidl_return);
ndk::ScopedAStatus init() {
- return mWorker.start(StreamWorker::kThreadName, ANDROID_PRIORITY_AUDIO)
- ? ndk::ScopedAStatus::ok()
- : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ return mWorker->start() ? ndk::ScopedAStatus::ok()
+ : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
- bool isClosed() const { return mWorker.isClosed(); }
+ bool isClosed() const { return mWorker->isClosed(); }
void setIsConnected(
const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
- mWorker.setIsConnected(!devices.empty());
+ mWorker->setIsConnected(!devices.empty());
mConnectedDevices = devices;
}
ndk::ScopedAStatus updateMetadata(const Metadata& metadata);
protected:
- StreamCommonImpl(const Metadata& metadata, StreamContext&& context)
- : mMetadata(metadata), mContext(std::move(context)), mWorker(mContext) {}
+ StreamCommonImpl(const Metadata& metadata, StreamContext&& context,
+ const DriverInterface::CreateInstance& createDriver,
+ const StreamWorkerInterface::CreateInstance& createWorker)
+ : mMetadata(metadata),
+ mContext(std::move(context)),
+ mDriver(createDriver(mContext)),
+ mWorker(createWorker(mContext, mDriver.get())) {}
~StreamCommonImpl();
void stopWorker();
void createStreamCommon(const std::shared_ptr<StreamCommonInterface>& delegate);
@@ -309,16 +389,16 @@
ndk::SpAIBinder mCommonBinder;
Metadata mMetadata;
StreamContext mContext;
- StreamWorker mWorker;
+ std::unique_ptr<DriverInterface> mDriver;
+ std::unique_ptr<StreamWorkerInterface> mWorker;
std::vector<::aidl::android::media::audio::common::AudioDevice> mConnectedDevices;
};
-class StreamIn : public StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata,
- StreamInWorker>,
+class StreamIn : public StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata>,
public BnStreamIn {
ndk::ScopedAStatus getStreamCommon(std::shared_ptr<IStreamCommon>* _aidl_return) override {
- return StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata,
- StreamInWorker>::getStreamCommon(_aidl_return);
+ return StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata>::
+ getStreamCommon(_aidl_return);
}
ndk::ScopedAStatus getActiveMicrophones(
std::vector<MicrophoneDynamicInfo>* _aidl_return) override;
@@ -328,42 +408,46 @@
ndk::ScopedAStatus setMicrophoneFieldDimension(float in_zoom) override;
ndk::ScopedAStatus updateMetadata(const ::aidl::android::hardware::audio::common::SinkMetadata&
in_sinkMetadata) override {
- return StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata,
- StreamInWorker>::updateMetadata(in_sinkMetadata);
+ return StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata>::
+ updateMetadata(in_sinkMetadata);
}
ndk::ScopedAStatus getHwGain(std::vector<float>* _aidl_return) override;
ndk::ScopedAStatus setHwGain(const std::vector<float>& in_channelGains) override;
- public:
- static ndk::ScopedAStatus createInstance(
- const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
- StreamContext context, const std::vector<MicrophoneInfo>& microphones,
- std::shared_ptr<StreamIn>* result);
-
- private:
+ protected:
friend class ndk::SharedRefBase;
+
+ static ndk::ScopedAStatus initInstance(const std::shared_ptr<StreamIn>& stream);
+
StreamIn(const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
- StreamContext&& context, const std::vector<MicrophoneInfo>& microphones);
+ StreamContext&& context, const DriverInterface::CreateInstance& createDriver,
+ const StreamWorkerInterface::CreateInstance& createWorker,
+ const std::vector<MicrophoneInfo>& microphones);
void createStreamCommon(const std::shared_ptr<StreamIn>& myPtr) {
- StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata,
- StreamInWorker>::createStreamCommon(myPtr);
+ StreamCommonImpl<
+ ::aidl::android::hardware::audio::common::SinkMetadata>::createStreamCommon(myPtr);
}
const std::map<::aidl::android::media::audio::common::AudioDevice, std::string> mMicrophones;
+
+ public:
+ using CreateInstance = std::function<ndk::ScopedAStatus(
+ const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+ StreamContext&& context, const std::vector<MicrophoneInfo>& microphones,
+ std::shared_ptr<StreamIn>* result)>;
};
-class StreamOut : public StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata,
- StreamOutWorker>,
+class StreamOut : public StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata>,
public BnStreamOut {
ndk::ScopedAStatus getStreamCommon(std::shared_ptr<IStreamCommon>* _aidl_return) override {
- return StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata,
- StreamOutWorker>::getStreamCommon(_aidl_return);
+ return StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata>::
+ getStreamCommon(_aidl_return);
}
ndk::ScopedAStatus updateMetadata(
const ::aidl::android::hardware::audio::common::SourceMetadata& in_sourceMetadata)
override {
- return StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata,
- StreamOutWorker>::updateMetadata(in_sourceMetadata);
+ return StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata>::
+ updateMetadata(in_sourceMetadata);
}
ndk::ScopedAStatus getHwVolume(std::vector<float>* _aidl_return) override;
ndk::ScopedAStatus setHwVolume(const std::vector<float>& in_channelVolumes) override;
@@ -385,26 +469,31 @@
override;
ndk::ScopedAStatus selectPresentation(int32_t in_presentationId, int32_t in_programId) override;
- public:
- static ndk::ScopedAStatus createInstance(
- const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
- StreamContext context,
- const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
- offloadInfo,
- std::shared_ptr<StreamOut>* result);
-
- private:
- friend class ndk::SharedRefBase;
- StreamOut(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
- StreamContext&& context,
- const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
- offloadInfo);
void createStreamCommon(const std::shared_ptr<StreamOut>& myPtr) {
- StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata,
- StreamOutWorker>::createStreamCommon(myPtr);
+ StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata>::
+ createStreamCommon(myPtr);
}
+ protected:
+ friend class ndk::SharedRefBase;
+
+ static ndk::ScopedAStatus initInstance(const std::shared_ptr<StreamOut>& stream);
+
+ StreamOut(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+ StreamContext&& context, const DriverInterface::CreateInstance& createDriver,
+ const StreamWorkerInterface::CreateInstance& createWorker,
+ const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+ offloadInfo);
+
std::optional<::aidl::android::media::audio::common::AudioOffloadInfo> mOffloadInfo;
+
+ public:
+ using CreateInstance = std::function<ndk::ScopedAStatus(
+ const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+ StreamContext&& context,
+ const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+ offloadInfo,
+ std::shared_ptr<StreamOut>* result)>;
};
class StreamWrapper {
diff --git a/audio/aidl/default/include/core-impl/StreamStub.h b/audio/aidl/default/include/core-impl/StreamStub.h
new file mode 100644
index 0000000..98a062a
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/StreamStub.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "core-impl/Stream.h"
+
+namespace aidl::android::hardware::audio::core {
+
+class DriverStub : public DriverInterface {
+ public:
+ DriverStub(const StreamContext& context, bool isInput);
+ ::android::status_t init() override;
+ ::android::status_t drain(StreamDescriptor::DrainMode) override;
+ ::android::status_t flush() override;
+ ::android::status_t pause() override;
+ ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+ int32_t* latencyMs) override;
+ ::android::status_t standby() override;
+
+ private:
+ const size_t mFrameSizeBytes;
+ const bool mIsInput;
+};
+
+class StreamInStub final : public StreamIn {
+ public:
+ static ndk::ScopedAStatus createInstance(
+ const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+ StreamContext&& context, const std::vector<MicrophoneInfo>& microphones,
+ std::shared_ptr<StreamIn>* result);
+
+ private:
+ friend class ndk::SharedRefBase;
+ StreamInStub(const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+ StreamContext&& context, const std::vector<MicrophoneInfo>& microphones);
+};
+
+class StreamOutStub final : public StreamOut {
+ public:
+ static ndk::ScopedAStatus createInstance(
+ const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+ StreamContext&& context,
+ const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+ offloadInfo,
+ std::shared_ptr<StreamOut>* result);
+
+ private:
+ friend class ndk::SharedRefBase;
+ StreamOutStub(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+ StreamContext&& context,
+ const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+ offloadInfo);
+};
+
+} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/effect-impl/EffectContext.h b/audio/aidl/default/include/effect-impl/EffectContext.h
index a3e7ff2..7bbf19e 100644
--- a/audio/aidl/default/include/effect-impl/EffectContext.h
+++ b/audio/aidl/default/include/effect-impl/EffectContext.h
@@ -91,11 +91,13 @@
int getSessionId() { return mSessionId; }
virtual RetCode setOutputDevice(
- const aidl::android::media::audio::common::AudioDeviceDescription& device) {
+ const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>&
+ device) {
mOutputDevice = device;
return RetCode::SUCCESS;
}
- virtual aidl::android::media::audio::common::AudioDeviceDescription getOutputDevice() {
+ virtual std::vector<aidl::android::media::audio::common::AudioDeviceDescription>
+ getOutputDevice() {
return mOutputDevice;
}
@@ -133,7 +135,7 @@
size_t mInputFrameSize;
size_t mOutputFrameSize;
Parameter::Common mCommon;
- aidl::android::media::audio::common::AudioDeviceDescription mOutputDevice;
+ std::vector<aidl::android::media::audio::common::AudioDeviceDescription> mOutputDevice;
aidl::android::media::audio::common::AudioMode mMode;
aidl::android::media::audio::common::AudioSource mSource;
Parameter::VolumeStereo mVolumeStereo;
diff --git a/audio/aidl/default/include/effect-impl/EffectUUID.h b/audio/aidl/default/include/effect-impl/EffectUUID.h
index 1a60829..7703091 100644
--- a/audio/aidl/default/include/effect-impl/EffectUUID.h
+++ b/audio/aidl/default/include/effect-impl/EffectUUID.h
@@ -189,6 +189,18 @@
0x11ed,
0x9b6a,
{0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// 4a387fc0-8ab3-11df-8bad-0002a5d5c51b
+static const AudioUuid kAuxEnvReverbImplUUID = {static_cast<int32_t>(0x4a387fc0),
+ 0x8ab3,
+ 0x11df,
+ 0x8bad,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// c7a511a0-a3bb-11df-860e-0002a5d5c51b
+static const AudioUuid kInsertEnvReverbImplUUID = {static_cast<int32_t>(0xc7a511a0),
+ 0xa3bb,
+ 0x11df,
+ 0x860e,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
// 58b4b260-8e06-11e0-aa8e-0002a5d5c51b
static const AudioUuid kNoiseSuppressionTypeUUID = {static_cast<int32_t>(0x58b4b260),
0x8e06,
@@ -213,6 +225,18 @@
0x11ed,
0x9b6a,
{0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// f29a1400-a3bb-11df-8ddc-0002a5d5c51b
+static const AudioUuid kAuxPresetReverbImplUUID = {static_cast<int32_t>(0xf29a1400),
+ 0xa3bb,
+ 0x11df,
+ 0x8ddc,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 172cdf00-a3bc-11df-a72f-0002a5d5c51b
+static const AudioUuid kInsertPresetReverbImplUUID = {static_cast<int32_t>(0x172cdf00),
+ 0xa3bc,
+ 0x11df,
+ 0xa72f,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
// 37cc2c00-dddd-11db-8577-0002a5d5c51b
static const AudioUuid kVirtualizerTypeUUID = {static_cast<int32_t>(0x37cc2c00),
0xdddd,
diff --git a/audio/aidl/default/include/effectFactory-impl/EffectFactory.h b/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
index 04bd1bb..b32ec56 100644
--- a/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
+++ b/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
@@ -101,7 +101,7 @@
ndk::ScopedAStatus destroyEffectImpl(const std::shared_ptr<IEffect>& in_handle);
void cleanupEffectMap();
- void openEffectLibrary(const ::aidl::android::media::audio::common::AudioUuid& impl,
+ bool openEffectLibrary(const ::aidl::android::media::audio::common::AudioUuid& impl,
const std::string& libName);
void createIdentityWithConfig(
const EffectConfig::LibraryUuid& configLib,
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 8da475e..d4f2811 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -18,6 +18,7 @@
#include <chrono>
#include <cmath>
#include <condition_variable>
+#include <forward_list>
#include <limits>
#include <memory>
#include <mutex>
@@ -85,6 +86,7 @@
using aidl::android::media::audio::common::AudioPortExt;
using aidl::android::media::audio::common::AudioSource;
using aidl::android::media::audio::common::AudioUsage;
+using aidl::android::media::audio::common::Boolean;
using aidl::android::media::audio::common::Float;
using aidl::android::media::audio::common::Int;
using aidl::android::media::audio::common::Void;
@@ -126,7 +128,7 @@
return WithDebugFlags(parent.mFlags);
}
- WithDebugFlags() {}
+ WithDebugFlags() = default;
explicit WithDebugFlags(const ModuleDebug& initial) : mInitial(initial), mFlags(initial) {}
WithDebugFlags(const WithDebugFlags&) = delete;
WithDebugFlags& operator=(const WithDebugFlags&) = delete;
@@ -135,7 +137,10 @@
EXPECT_IS_OK(mModule->setModuleDebug(mInitial));
}
}
- void SetUp(IModule* module) { ASSERT_IS_OK(module->setModuleDebug(mFlags)); }
+ void SetUp(IModule* module) {
+ ASSERT_IS_OK(module->setModuleDebug(mFlags));
+ mModule = module;
+ }
ModuleDebug& flags() { return mFlags; }
private:
@@ -144,13 +149,65 @@
IModule* mModule = nullptr;
};
+template <typename T>
+class WithModuleParameter {
+ public:
+ WithModuleParameter(const std::string parameterId, const T& value)
+ : mParameterId(parameterId), mValue(value) {}
+ WithModuleParameter(const WithModuleParameter&) = delete;
+ WithModuleParameter& operator=(const WithModuleParameter&) = delete;
+ ~WithModuleParameter() {
+ if (mModule != nullptr) {
+ VendorParameter parameter{.id = mParameterId};
+ parameter.ext.setParcelable(mInitial);
+ EXPECT_IS_OK(mModule->setVendorParameters({parameter}, false));
+ }
+ }
+ ScopedAStatus SetUpNoChecks(IModule* module, bool failureExpected) {
+ std::vector<VendorParameter> parameters;
+ ScopedAStatus result = module->getVendorParameters({mParameterId}, ¶meters);
+ if (result.isOk() && parameters.size() == 1) {
+ std::optional<T> maybeInitial;
+ binder_status_t status = parameters[0].ext.getParcelable(&maybeInitial);
+ if (status == STATUS_OK && maybeInitial.has_value()) {
+ mInitial = maybeInitial.value();
+ VendorParameter parameter{.id = mParameterId};
+ parameter.ext.setParcelable(mValue);
+ result = module->setVendorParameters({parameter}, false);
+ if (result.isOk()) {
+ LOG(INFO) << __func__ << ": overriding parameter \"" << mParameterId
+ << "\" with " << mValue.toString()
+ << ", old value: " << mInitial.toString();
+ mModule = module;
+ }
+ } else {
+ LOG(ERROR) << __func__ << ": error while retrieving the value of \"" << mParameterId
+ << "\"";
+ return ScopedAStatus::fromStatus(status);
+ }
+ }
+ if (!result.isOk()) {
+ LOG(failureExpected ? INFO : ERROR)
+ << __func__ << ": can not override vendor parameter \"" << mParameterId << "\""
+ << result;
+ }
+ return result;
+ }
+
+ private:
+ const std::string mParameterId;
+ const T mValue;
+ IModule* mModule = nullptr;
+ T mInitial;
+};
+
// For consistency, WithAudioPortConfig can start both with a non-existent
// port config, and with an existing one. Existence is determined by the
// id of the provided config. If it's not 0, then WithAudioPortConfig is
// essentially a no-op wrapper.
class WithAudioPortConfig {
public:
- WithAudioPortConfig() {}
+ WithAudioPortConfig() = default;
explicit WithAudioPortConfig(const AudioPortConfig& config) : mInitialConfig(config) {}
WithAudioPortConfig(const WithAudioPortConfig&) = delete;
WithAudioPortConfig& operator=(const WithAudioPortConfig&) = delete;
@@ -302,26 +359,31 @@
void SetUpImpl(const std::string& moduleName) {
ASSERT_NO_FATAL_FAILURE(ConnectToService(moduleName));
- debug.flags().simulateDeviceConnections = true;
- ASSERT_NO_FATAL_FAILURE(debug.SetUp(module.get()));
}
- void TearDownImpl() {
- if (module != nullptr) {
- EXPECT_IS_OK(module->setModuleDebug(ModuleDebug{}));
- }
- }
+ void TearDownImpl() { debug.reset(); }
void ConnectToService(const std::string& moduleName) {
+ ASSERT_EQ(module, nullptr);
+ ASSERT_EQ(debug, nullptr);
module = IModule::fromBinder(binderUtil.connectToService(moduleName));
ASSERT_NE(module, nullptr);
+ ASSERT_NO_FATAL_FAILURE(SetUpDebug());
}
void RestartService() {
ASSERT_NE(module, nullptr);
moduleConfig.reset();
+ debug.reset();
module = IModule::fromBinder(binderUtil.restartService());
ASSERT_NE(module, nullptr);
+ ASSERT_NO_FATAL_FAILURE(SetUpDebug());
+ }
+
+ void SetUpDebug() {
+ debug.reset(new WithDebugFlags());
+ debug->flags().simulateDeviceConnections = true;
+ ASSERT_NO_FATAL_FAILURE(debug->SetUp(module.get()));
}
void ApplyEveryConfig(const std::vector<AudioPortConfig>& configs) {
@@ -390,7 +452,7 @@
std::shared_ptr<IModule> module;
std::unique_ptr<ModuleConfig> moduleConfig;
AudioHalBinderServiceUtil binderUtil;
- WithDebugFlags debug;
+ std::unique_ptr<WithDebugFlags> debug;
};
class AudioCoreModule : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
@@ -465,6 +527,7 @@
size_t getBufferSizeFrames() const { return mBufferSizeFrames; }
CommandMQ* getCommandMQ() const { return mCommandMQ.get(); }
DataMQ* getDataMQ() const { return mDataMQ.get(); }
+ size_t getFrameSizeBytes() const { return mFrameSizeBytes; }
ReplyMQ* getReplyMQ() const { return mReplyMQ.get(); }
private:
@@ -504,10 +567,48 @@
return std::to_string(static_cast<int32_t>(event));
}
+// Note: we use a reference wrapper, not a pointer, because methods of std::*list
+// return references to inserted elements. This way, we can put a returned reference
+// into the children vector without any type conversions, and this makes DAG creation
+// code more clear.
+template <typename T>
+struct DagNode : public std::pair<T, std::vector<std::reference_wrapper<DagNode<T>>>> {
+ using Children = std::vector<std::reference_wrapper<DagNode>>;
+ DagNode(const T& t, const Children& c) : std::pair<T, Children>(t, c) {}
+ DagNode(T&& t, Children&& c) : std::pair<T, Children>(std::move(t), std::move(c)) {}
+ const T& datum() const { return this->first; }
+ Children& children() { return this->second; }
+ const Children& children() const { return this->second; }
+};
+// Since DagNodes do contain references to next nodes, node links provided
+// by the list are not used. Thus, the order of the nodes in the list is not
+// important, except that the starting node must be at the front of the list,
+// which means, it must always be added last.
+template <typename T>
+struct Dag : public std::forward_list<DagNode<T>> {
+ Dag() = default;
+ // We prohibit copying and moving Dag instances because implementing that
+ // is not trivial due to references between nodes.
+ Dag(const Dag&) = delete;
+ Dag(Dag&&) = delete;
+ Dag& operator=(const Dag&) = delete;
+ Dag& operator=(Dag&&) = delete;
+};
+
// Transition to the next state happens either due to a command from the client,
// or after an event received from the server.
using TransitionTrigger = std::variant<StreamDescriptor::Command, StreamEventReceiver::Event>;
-using StateTransition = std::pair<TransitionTrigger, StreamDescriptor::State>;
+std::string toString(const TransitionTrigger& trigger) {
+ if (std::holds_alternative<StreamDescriptor::Command>(trigger)) {
+ return std::string("'")
+ .append(toString(std::get<StreamDescriptor::Command>(trigger).getTag()))
+ .append("' command");
+ }
+ return std::string("'")
+ .append(toString(std::get<StreamEventReceiver::Event>(trigger)))
+ .append("' event");
+}
+
struct StateSequence {
virtual ~StateSequence() = default;
virtual void rewind() = 0;
@@ -517,6 +618,10 @@
virtual void advance(StreamDescriptor::State state) = 0;
};
+// Defines the current state and the trigger to transfer to the next one,
+// thus "state" is the "from" state.
+using StateTransitionFrom = std::pair<StreamDescriptor::State, TransitionTrigger>;
+
static const StreamDescriptor::Command kGetStatusCommand =
StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::getStatus>(Void{});
static const StreamDescriptor::Command kStartCommand =
@@ -542,66 +647,65 @@
StreamEventReceiver::Event::TransferReady;
static const StreamEventReceiver::Event kDrainReadyEvent = StreamEventReceiver::Event::DrainReady;
-// Handle possible bifurcations:
-// - on burst and on start: 'TRANSFERRING' -> {'ACTIVE', 'TRANSFERRING'}
-// - on pause: 'TRANSFER_PAUSED' -> {'PAUSED', 'TRANSFER_PAUSED'}
-// It is assumed that the 'steps' provided on the construction contain the sequence
-// for the async case, which gets corrected in the case when the HAL decided to do
-// a synchronous transfer.
-class SmartStateSequence : public StateSequence {
+struct StateDag : public Dag<StateTransitionFrom> {
+ using Node = StateDag::reference;
+ using NextStates = StateDag::value_type::Children;
+
+ template <typename... Next>
+ Node makeNode(StreamDescriptor::State s, TransitionTrigger t, Next&&... next) {
+ return emplace_front(std::make_pair(s, t), NextStates{std::forward<Next>(next)...});
+ }
+ Node makeNodes(const std::vector<StateTransitionFrom>& v, Node last) {
+ auto helper = [&](auto i, auto&& h) -> Node {
+ if (i == v.end()) return last;
+ return makeNode(i->first, i->second, h(++i, h));
+ };
+ return helper(v.begin(), helper);
+ }
+ Node makeNodes(const std::vector<StateTransitionFrom>& v, StreamDescriptor::State f) {
+ return makeNodes(v, makeFinalNode(f));
+ }
+ Node makeFinalNode(StreamDescriptor::State s) {
+ // The actual command used here is irrelevant. Since it's the final node
+ // in the test sequence, no commands sent after reaching it.
+ return emplace_front(std::make_pair(s, kGetStatusCommand), NextStates{});
+ }
+};
+
+class StateSequenceFollower : public StateSequence {
public:
- explicit SmartStateSequence(const std::vector<StateTransition>& steps) : mSteps(steps) {}
- explicit SmartStateSequence(std::vector<StateTransition>&& steps) : mSteps(std::move(steps)) {}
- void rewind() override { mCurrentStep = 0; }
- bool done() const override { return mCurrentStep >= mSteps.size(); }
- TransitionTrigger getTrigger() override { return mSteps[mCurrentStep].first; }
+ explicit StateSequenceFollower(std::unique_ptr<StateDag> steps)
+ : mSteps(std::move(steps)), mCurrent(mSteps->front()) {}
+ void rewind() override { mCurrent = mSteps->front(); }
+ bool done() const override { return current().children().empty(); }
+ TransitionTrigger getTrigger() override { return current().datum().second; }
std::set<StreamDescriptor::State> getExpectedStates() override {
- std::set<StreamDescriptor::State> result = {getState()};
- if (isBurstBifurcation() || isStartBifurcation()) {
- result.insert(StreamDescriptor::State::ACTIVE);
- } else if (isPauseBifurcation()) {
- result.insert(StreamDescriptor::State::PAUSED);
- }
+ std::set<StreamDescriptor::State> result;
+ std::transform(current().children().cbegin(), current().children().cend(),
+ std::inserter(result, result.begin()),
+ [](const auto& node) { return node.get().datum().first; });
+ LOG(DEBUG) << __func__ << ": " << ::android::internal::ToString(result);
return result;
}
void advance(StreamDescriptor::State state) override {
- if (isBurstBifurcation() && state == StreamDescriptor::State::ACTIVE &&
- mCurrentStep + 1 < mSteps.size() &&
- mSteps[mCurrentStep + 1].first == TransitionTrigger{kTransferReadyEvent}) {
- mCurrentStep++;
+ if (auto it = std::find_if(
+ current().children().cbegin(), current().children().cend(),
+ [&](const auto& node) { return node.get().datum().first == state; });
+ it != current().children().cend()) {
+ LOG(DEBUG) << __func__ << ": " << toString(mCurrent.get().datum().first) << " -> "
+ << toString(it->get().datum().first);
+ mCurrent = *it;
+ } else {
+ LOG(FATAL) << __func__ << ": state " << toString(state) << " is unexpected";
}
- mCurrentStep++;
}
private:
- StreamDescriptor::State getState() const { return mSteps[mCurrentStep].second; }
- bool isBurstBifurcation() {
- return getTrigger() == TransitionTrigger{kBurstCommand} &&
- getState() == StreamDescriptor::State::TRANSFERRING;
- }
- bool isPauseBifurcation() {
- return getTrigger() == TransitionTrigger{kPauseCommand} &&
- getState() == StreamDescriptor::State::TRANSFER_PAUSED;
- }
- bool isStartBifurcation() {
- return getTrigger() == TransitionTrigger{kStartCommand} &&
- getState() == StreamDescriptor::State::TRANSFERRING;
- }
- const std::vector<StateTransition> mSteps;
- size_t mCurrentStep = 0;
+ StateDag::const_reference current() const { return mCurrent.get(); }
+ std::unique_ptr<StateDag> mSteps;
+ std::reference_wrapper<StateDag::value_type> mCurrent;
};
-std::string toString(const TransitionTrigger& trigger) {
- if (std::holds_alternative<StreamDescriptor::Command>(trigger)) {
- return std::string("'")
- .append(toString(std::get<StreamDescriptor::Command>(trigger).getTag()))
- .append("' command");
- }
- return std::string("'")
- .append(toString(std::get<StreamEventReceiver::Event>(trigger)))
- .append("' event");
-}
-
struct StreamLogicDriver {
virtual ~StreamLogicDriver() = default;
// Return 'true' to stop the worker.
@@ -927,7 +1031,7 @@
return common->close();
}
- WithStream() {}
+ WithStream() = default;
explicit WithStream(const AudioPortConfig& portConfig) : mPortConfig(portConfig) {}
WithStream(const WithStream&) = delete;
WithStream& operator=(const WithStream&) = delete;
@@ -1032,7 +1136,7 @@
class WithAudioPatch {
public:
- WithAudioPatch() {}
+ WithAudioPatch() = default;
WithAudioPatch(const AudioPortConfig& srcPortConfig, const AudioPortConfig& sinkPortConfig)
: mSrcPortConfig(srcPortConfig), mSinkPortConfig(sinkPortConfig) {}
WithAudioPatch(bool sinkIsCfg1, const AudioPortConfig& portConfig1,
@@ -1473,7 +1577,7 @@
GTEST_SKIP() << "No external devices in the module.";
}
AudioPort ignored;
- WithDebugFlags doNotSimulateConnections = WithDebugFlags::createNested(debug);
+ WithDebugFlags doNotSimulateConnections = WithDebugFlags::createNested(*debug);
doNotSimulateConnections.flags().simulateDeviceConnections = false;
ASSERT_NO_FATAL_FAILURE(doNotSimulateConnections.SetUp(module.get()));
for (const auto& port : ports) {
@@ -1493,7 +1597,7 @@
}
WithDevicePortConnectedState portConnected(*ports.begin(), GenerateUniqueDeviceAddress());
ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
- ModuleDebug midwayDebugChange = debug.flags();
+ ModuleDebug midwayDebugChange = debug->flags();
midwayDebugChange.simulateDeviceConnections = false;
EXPECT_STATUS(EX_ILLEGAL_STATE, module->setModuleDebug(midwayDebugChange))
<< "when trying to disable connections simulation while having a connected device";
@@ -2716,8 +2820,8 @@
class StreamLogicDefaultDriver : public StreamLogicDriver {
public:
- explicit StreamLogicDefaultDriver(std::shared_ptr<StateSequence> commands)
- : mCommands(commands) {
+ StreamLogicDefaultDriver(std::shared_ptr<StateSequence> commands, size_t frameSizeBytes)
+ : mCommands(commands), mFrameSizeBytes(frameSizeBytes) {
mCommands->rewind();
}
@@ -2736,7 +2840,10 @@
if (actualSize != nullptr) {
// In the output scenario, reduce slightly the fmqByteCount to verify
// that the HAL module always consumes all data from the MQ.
- if (maxDataSize > 1) maxDataSize--;
+ if (maxDataSize > static_cast<int>(mFrameSizeBytes)) {
+ LOG(DEBUG) << __func__ << ": reducing data size by " << mFrameSizeBytes;
+ maxDataSize -= mFrameSizeBytes;
+ }
*actualSize = maxDataSize;
}
command->set<StreamDescriptor::Command::Tag::burst>(maxDataSize);
@@ -2782,6 +2889,7 @@
protected:
std::shared_ptr<StateSequence> mCommands;
+ const size_t mFrameSizeBytes;
std::optional<StreamDescriptor::State> mPreviousState;
std::optional<int64_t> mPreviousFrames;
bool mObservablePositionIncrease = false;
@@ -2830,7 +2938,7 @@
(!isNonBlocking && streamType == StreamTypeFilter::ASYNC)) {
continue;
}
- WithDebugFlags delayTransientStates = WithDebugFlags::createNested(debug);
+ WithDebugFlags delayTransientStates = WithDebugFlags::createNested(*debug);
delayTransientStates.flags().streamTransientStateDelayMs =
std::get<NAMED_CMD_DELAY_MS>(std::get<PARAM_CMD_SEQ>(GetParam()));
ASSERT_NO_FATAL_FAILURE(delayTransientStates.SetUp(module.get()));
@@ -2841,6 +2949,40 @@
} else {
ASSERT_NO_FATAL_FAILURE(RunStreamIoCommandsImplSeq2(portConfig, commandsAndStates));
}
+ if (isNonBlocking) {
+ // Also try running the same sequence with "aosp.forceTransientBurst" set.
+ // This will only work with the default implementation. When it works, the stream
+ // tries always to move to the 'TRANSFERRING' state after a burst.
+ // This helps to check more paths for our test scenarios.
+ WithModuleParameter forceTransientBurst("aosp.forceTransientBurst", Boolean{true});
+ if (forceTransientBurst.SetUpNoChecks(module.get(), true /*failureExpected*/)
+ .isOk()) {
+ if (!std::get<PARAM_SETUP_SEQ>(GetParam())) {
+ ASSERT_NO_FATAL_FAILURE(
+ RunStreamIoCommandsImplSeq1(portConfig, commandsAndStates));
+ } else {
+ ASSERT_NO_FATAL_FAILURE(
+ RunStreamIoCommandsImplSeq2(portConfig, commandsAndStates));
+ }
+ }
+ } else if (!IOTraits<Stream>::is_input) {
+ // Also try running the same sequence with "aosp.forceSynchronousDrain" set.
+ // This will only work with the default implementation. When it works, the stream
+ // tries always to move to the 'IDLE' state after a drain.
+ // This helps to check more paths for our test scenarios.
+ WithModuleParameter forceSynchronousDrain("aosp.forceSynchronousDrain",
+ Boolean{true});
+ if (forceSynchronousDrain.SetUpNoChecks(module.get(), true /*failureExpected*/)
+ .isOk()) {
+ if (!std::get<PARAM_SETUP_SEQ>(GetParam())) {
+ ASSERT_NO_FATAL_FAILURE(
+ RunStreamIoCommandsImplSeq1(portConfig, commandsAndStates));
+ } else {
+ ASSERT_NO_FATAL_FAILURE(
+ RunStreamIoCommandsImplSeq2(portConfig, commandsAndStates));
+ }
+ }
+ }
}
}
@@ -2861,7 +3003,8 @@
WithStream<Stream> stream(patch.getPortConfig(IOTraits<Stream>::is_input));
ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
- StreamLogicDefaultDriver driver(commandsAndStates);
+ StreamLogicDefaultDriver driver(commandsAndStates,
+ stream.getContext()->getFrameSizeBytes());
typename IOTraits<Stream>::Worker worker(*stream.getContext(), &driver,
stream.getEventReceiver());
@@ -2882,7 +3025,8 @@
std::shared_ptr<StateSequence> commandsAndStates) {
WithStream<Stream> stream(portConfig);
ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
- StreamLogicDefaultDriver driver(commandsAndStates);
+ StreamLogicDefaultDriver driver(commandsAndStates,
+ stream.getContext()->getFrameSizeBytes());
typename IOTraits<Stream>::Worker worker(*stream.getContext(), &driver,
stream.getEventReceiver());
@@ -3219,38 +3363,52 @@
// TODO: Add async test cases for input once it is implemented.
-std::shared_ptr<StateSequence> makeBurstCommands(bool isSync, size_t burstCount) {
- const auto burst =
- isSync ? std::vector<StateTransition>{std::make_pair(kBurstCommand,
- StreamDescriptor::State::ACTIVE)}
- : std::vector<StateTransition>{
- std::make_pair(kBurstCommand, StreamDescriptor::State::TRANSFERRING),
- std::make_pair(kTransferReadyEvent, StreamDescriptor::State::ACTIVE)};
- std::vector<StateTransition> result{
- std::make_pair(kStartCommand, StreamDescriptor::State::IDLE)};
- for (size_t i = 0; i < burstCount; ++i) {
- result.insert(result.end(), burst.begin(), burst.end());
+std::shared_ptr<StateSequence> makeBurstCommands(bool isSync) {
+ using State = StreamDescriptor::State;
+ auto d = std::make_unique<StateDag>();
+ StateDag::Node last = d->makeFinalNode(State::ACTIVE);
+ StateDag::Node active = d->makeNode(State::ACTIVE, kBurstCommand, last);
+ StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
+ if (!isSync) {
+ // Allow optional routing via the TRANSFERRING state on bursts.
+ active.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, last));
+ idle.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, active));
}
- return std::make_shared<SmartStateSequence>(result);
+ d->makeNode(State::STANDBY, kStartCommand, idle);
+ return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kReadSeq =
- std::make_tuple(std::string("Read"), 0, StreamTypeFilter::ANY, makeBurstCommands(true, 3));
-static const NamedCommandSequence kWriteSyncSeq = std::make_tuple(
- std::string("Write"), 0, StreamTypeFilter::SYNC, makeBurstCommands(true, 3));
-static const NamedCommandSequence kWriteAsyncSeq = std::make_tuple(
- std::string("Write"), 0, StreamTypeFilter::ASYNC, makeBurstCommands(false, 3));
+ std::make_tuple(std::string("Read"), 0, StreamTypeFilter::ANY, makeBurstCommands(true));
+static const NamedCommandSequence kWriteSyncSeq =
+ std::make_tuple(std::string("Write"), 0, StreamTypeFilter::SYNC, makeBurstCommands(true));
+static const NamedCommandSequence kWriteAsyncSeq =
+ std::make_tuple(std::string("Write"), 0, StreamTypeFilter::ASYNC, makeBurstCommands(false));
std::shared_ptr<StateSequence> makeAsyncDrainCommands(bool isInput) {
- return std::make_shared<SmartStateSequence>(std::vector<StateTransition>{
- std::make_pair(kStartCommand, StreamDescriptor::State::IDLE),
- std::make_pair(kBurstCommand, isInput ? StreamDescriptor::State::ACTIVE
- : StreamDescriptor::State::TRANSFERRING),
- std::make_pair(isInput ? kDrainInCommand : kDrainOutAllCommand,
- StreamDescriptor::State::DRAINING),
- isInput ? std::make_pair(kStartCommand, StreamDescriptor::State::ACTIVE)
- : std::make_pair(kBurstCommand, StreamDescriptor::State::TRANSFERRING),
- std::make_pair(isInput ? kDrainInCommand : kDrainOutAllCommand,
- StreamDescriptor::State::DRAINING)});
+ using State = StreamDescriptor::State;
+ auto d = std::make_unique<StateDag>();
+ if (isInput) {
+ d->makeNodes({std::make_pair(State::STANDBY, kStartCommand),
+ std::make_pair(State::IDLE, kBurstCommand),
+ std::make_pair(State::ACTIVE, kDrainInCommand),
+ std::make_pair(State::DRAINING, kStartCommand),
+ std::make_pair(State::ACTIVE, kDrainInCommand)},
+ State::DRAINING);
+ } else {
+ StateDag::Node draining =
+ d->makeNodes({std::make_pair(State::DRAINING, kBurstCommand),
+ std::make_pair(State::TRANSFERRING, kDrainOutAllCommand)},
+ State::DRAINING);
+ StateDag::Node idle =
+ d->makeNodes({std::make_pair(State::IDLE, kBurstCommand),
+ std::make_pair(State::TRANSFERRING, kDrainOutAllCommand)},
+ draining);
+ // If we get straight into ACTIVE on burst, no further testing is possible.
+ draining.children().push_back(d->makeFinalNode(State::ACTIVE));
+ idle.children().push_back(d->makeFinalNode(State::ACTIVE));
+ d->makeNode(State::STANDBY, kStartCommand, idle);
+ }
+ return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kWriteDrainAsyncSeq =
std::make_tuple(std::string("WriteDrain"), kStreamTransientStateTransitionDelayMs,
@@ -3259,58 +3417,92 @@
std::string("Drain"), 0, StreamTypeFilter::ANY, makeAsyncDrainCommands(true));
std::shared_ptr<StateSequence> makeDrainOutCommands(bool isSync) {
- return std::make_shared<SmartStateSequence>(std::vector<StateTransition>{
- std::make_pair(kStartCommand, StreamDescriptor::State::IDLE),
- std::make_pair(kBurstCommand, StreamDescriptor::State::ACTIVE),
- std::make_pair(kDrainOutAllCommand, StreamDescriptor::State::DRAINING),
- std::make_pair(isSync ? TransitionTrigger(kGetStatusCommand)
- : TransitionTrigger(kDrainReadyEvent),
- StreamDescriptor::State::IDLE)});
+ using State = StreamDescriptor::State;
+ auto d = std::make_unique<StateDag>();
+ StateDag::Node last = d->makeFinalNode(State::IDLE);
+ StateDag::Node active = d->makeNodes(
+ {std::make_pair(State::ACTIVE, kDrainOutAllCommand),
+ std::make_pair(State::DRAINING, isSync ? TransitionTrigger(kGetStatusCommand)
+ : TransitionTrigger(kDrainReadyEvent))},
+ last);
+ StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
+ if (!isSync) {
+ idle.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, active));
+ } else {
+ active.children().push_back(last);
+ }
+ d->makeNode(State::STANDBY, kStartCommand, idle);
+ return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kDrainOutSyncSeq = std::make_tuple(
std::string("Drain"), 0, StreamTypeFilter::SYNC, makeDrainOutCommands(true));
static const NamedCommandSequence kDrainOutAsyncSeq = std::make_tuple(
std::string("Drain"), 0, StreamTypeFilter::ASYNC, makeDrainOutCommands(false));
-std::shared_ptr<StateSequence> makeDrainOutPauseCommands(bool isSync) {
- return std::make_shared<SmartStateSequence>(std::vector<StateTransition>{
- std::make_pair(kStartCommand, StreamDescriptor::State::IDLE),
- std::make_pair(kBurstCommand, isSync ? StreamDescriptor::State::ACTIVE
- : StreamDescriptor::State::TRANSFERRING),
- std::make_pair(kDrainOutAllCommand, StreamDescriptor::State::DRAINING),
- std::make_pair(kPauseCommand, StreamDescriptor::State::DRAIN_PAUSED),
- std::make_pair(kStartCommand, StreamDescriptor::State::DRAINING),
- std::make_pair(kPauseCommand, StreamDescriptor::State::DRAIN_PAUSED),
- std::make_pair(kBurstCommand, isSync ? StreamDescriptor::State::PAUSED
- : StreamDescriptor::State::TRANSFER_PAUSED)});
+std::shared_ptr<StateSequence> makeDrainPauseOutCommands(bool isSync) {
+ using State = StreamDescriptor::State;
+ auto d = std::make_unique<StateDag>();
+ StateDag::Node draining = d->makeNodes({std::make_pair(State::DRAINING, kPauseCommand),
+ std::make_pair(State::DRAIN_PAUSED, kStartCommand),
+ std::make_pair(State::DRAINING, kPauseCommand),
+ std::make_pair(State::DRAIN_PAUSED, kBurstCommand)},
+ isSync ? State::PAUSED : State::TRANSFER_PAUSED);
+ StateDag::Node active = d->makeNode(State::ACTIVE, kDrainOutAllCommand, draining);
+ StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
+ if (!isSync) {
+ idle.children().push_back(d->makeNode(State::TRANSFERRING, kDrainOutAllCommand, draining));
+ } else {
+ // If we get straight into IDLE on drain, no further testing is possible.
+ active.children().push_back(d->makeFinalNode(State::IDLE));
+ }
+ d->makeNode(State::STANDBY, kStartCommand, idle);
+ return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kDrainPauseOutSyncSeq =
std::make_tuple(std::string("DrainPause"), kStreamTransientStateTransitionDelayMs,
- StreamTypeFilter::SYNC, makeDrainOutPauseCommands(true));
+ StreamTypeFilter::SYNC, makeDrainPauseOutCommands(true));
static const NamedCommandSequence kDrainPauseOutAsyncSeq =
std::make_tuple(std::string("DrainPause"), kStreamTransientStateTransitionDelayMs,
- StreamTypeFilter::ASYNC, makeDrainOutPauseCommands(false));
+ StreamTypeFilter::ASYNC, makeDrainPauseOutCommands(false));
// This sequence also verifies that the capture / presentation position is not reset on standby.
std::shared_ptr<StateSequence> makeStandbyCommands(bool isInput, bool isSync) {
- return std::make_shared<SmartStateSequence>(std::vector<StateTransition>{
- std::make_pair(kStartCommand, StreamDescriptor::State::IDLE),
- std::make_pair(kStandbyCommand, StreamDescriptor::State::STANDBY),
- std::make_pair(kStartCommand, StreamDescriptor::State::IDLE),
- std::make_pair(kBurstCommand, isInput || isSync
- ? StreamDescriptor::State::ACTIVE
- : StreamDescriptor::State::TRANSFERRING),
- std::make_pair(kPauseCommand, isInput || isSync
- ? StreamDescriptor::State::PAUSED
- : StreamDescriptor::State::TRANSFER_PAUSED),
- std::make_pair(kFlushCommand, isInput ? StreamDescriptor::State::STANDBY
- : StreamDescriptor::State::IDLE),
- std::make_pair(isInput ? kGetStatusCommand : kStandbyCommand, // no-op for input
- StreamDescriptor::State::STANDBY),
- std::make_pair(kStartCommand, StreamDescriptor::State::IDLE),
- std::make_pair(kBurstCommand, isInput || isSync
- ? StreamDescriptor::State::ACTIVE
- : StreamDescriptor::State::TRANSFERRING)});
+ using State = StreamDescriptor::State;
+ auto d = std::make_unique<StateDag>();
+ if (isInput) {
+ d->makeNodes({std::make_pair(State::STANDBY, kStartCommand),
+ std::make_pair(State::IDLE, kStandbyCommand),
+ std::make_pair(State::STANDBY, kStartCommand),
+ std::make_pair(State::IDLE, kBurstCommand),
+ std::make_pair(State::ACTIVE, kPauseCommand),
+ std::make_pair(State::PAUSED, kFlushCommand),
+ std::make_pair(State::STANDBY, kStartCommand),
+ std::make_pair(State::IDLE, kBurstCommand)},
+ State::ACTIVE);
+ } else {
+ StateDag::Node idle3 =
+ d->makeNode(State::IDLE, kBurstCommand, d->makeFinalNode(State::ACTIVE));
+ StateDag::Node idle2 = d->makeNodes({std::make_pair(State::IDLE, kStandbyCommand),
+ std::make_pair(State::STANDBY, kStartCommand)},
+ idle3);
+ StateDag::Node active = d->makeNodes({std::make_pair(State::ACTIVE, kPauseCommand),
+ std::make_pair(State::PAUSED, kFlushCommand)},
+ idle2);
+ StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
+ if (!isSync) {
+ idle3.children().push_back(d->makeFinalNode(State::TRANSFERRING));
+ StateDag::Node transferring =
+ d->makeNodes({std::make_pair(State::TRANSFERRING, kPauseCommand),
+ std::make_pair(State::TRANSFER_PAUSED, kFlushCommand)},
+ idle2);
+ idle.children().push_back(transferring);
+ }
+ d->makeNodes({std::make_pair(State::STANDBY, kStartCommand),
+ std::make_pair(State::IDLE, kStandbyCommand),
+ std::make_pair(State::STANDBY, kStartCommand)},
+ idle);
+ }
+ return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kStandbyInSeq = std::make_tuple(
std::string("Standby"), 0, StreamTypeFilter::ANY, makeStandbyCommands(true, false));
@@ -3320,50 +3512,71 @@
std::make_tuple(std::string("Standby"), kStreamTransientStateTransitionDelayMs,
StreamTypeFilter::ASYNC, makeStandbyCommands(false, false));
-static const NamedCommandSequence kPauseInSeq =
- std::make_tuple(std::string("Pause"), 0, StreamTypeFilter::ANY,
- std::make_shared<SmartStateSequence>(std::vector<StateTransition>{
- std::make_pair(kStartCommand, StreamDescriptor::State::IDLE),
- std::make_pair(kBurstCommand, StreamDescriptor::State::ACTIVE),
- std::make_pair(kPauseCommand, StreamDescriptor::State::PAUSED),
- std::make_pair(kBurstCommand, StreamDescriptor::State::ACTIVE),
- std::make_pair(kPauseCommand, StreamDescriptor::State::PAUSED),
- std::make_pair(kFlushCommand, StreamDescriptor::State::STANDBY)}));
-static const NamedCommandSequence kPauseOutSyncSeq =
- std::make_tuple(std::string("Pause"), 0, StreamTypeFilter::SYNC,
- std::make_shared<SmartStateSequence>(std::vector<StateTransition>{
- std::make_pair(kStartCommand, StreamDescriptor::State::IDLE),
- std::make_pair(kBurstCommand, StreamDescriptor::State::ACTIVE),
- std::make_pair(kPauseCommand, StreamDescriptor::State::PAUSED),
- std::make_pair(kStartCommand, StreamDescriptor::State::ACTIVE),
- std::make_pair(kPauseCommand, StreamDescriptor::State::PAUSED),
- std::make_pair(kBurstCommand, StreamDescriptor::State::PAUSED),
- std::make_pair(kStartCommand, StreamDescriptor::State::ACTIVE),
- std::make_pair(kPauseCommand, StreamDescriptor::State::PAUSED)}));
-/* TODO: Figure out a better way for testing sync/async bursts
-static const NamedCommandSequence kPauseOutAsyncSeq = std::make_tuple(
- std::string("Pause"), kStreamTransientStateTransitionDelayMs, StreamTypeFilter::ASYNC,
- std::make_shared<StaticStateSequence>(std::vector<StateTransition>{
- std::make_pair(kStartCommand, StreamDescriptor::State::IDLE),
- std::make_pair(kBurstCommand, StreamDescriptor::State::TRANSFERRING),
- std::make_pair(kPauseCommand, StreamDescriptor::State::TRANSFER_PAUSED),
- std::make_pair(kStartCommand, StreamDescriptor::State::TRANSFERRING),
- std::make_pair(kPauseCommand, StreamDescriptor::State::TRANSFER_PAUSED),
- std::make_pair(kDrainOutAllCommand, StreamDescriptor::State::DRAIN_PAUSED),
- std::make_pair(kBurstCommand, StreamDescriptor::State::TRANSFER_PAUSED)}));
-*/
+std::shared_ptr<StateSequence> makePauseCommands(bool isInput, bool isSync) {
+ using State = StreamDescriptor::State;
+ auto d = std::make_unique<StateDag>();
+ if (isInput) {
+ d->makeNodes({std::make_pair(State::STANDBY, kStartCommand),
+ std::make_pair(State::IDLE, kBurstCommand),
+ std::make_pair(State::ACTIVE, kPauseCommand),
+ std::make_pair(State::PAUSED, kBurstCommand),
+ std::make_pair(State::ACTIVE, kPauseCommand),
+ std::make_pair(State::PAUSED, kFlushCommand)},
+ State::STANDBY);
+ } else {
+ StateDag::Node idle = d->makeNodes({std::make_pair(State::IDLE, kBurstCommand),
+ std::make_pair(State::ACTIVE, kPauseCommand),
+ std::make_pair(State::PAUSED, kStartCommand),
+ std::make_pair(State::ACTIVE, kPauseCommand),
+ std::make_pair(State::PAUSED, kBurstCommand),
+ std::make_pair(State::PAUSED, kStartCommand),
+ std::make_pair(State::ACTIVE, kPauseCommand)},
+ State::PAUSED);
+ if (!isSync) {
+ idle.children().push_back(
+ d->makeNodes({std::make_pair(State::TRANSFERRING, kPauseCommand),
+ std::make_pair(State::TRANSFER_PAUSED, kStartCommand),
+ std::make_pair(State::TRANSFERRING, kPauseCommand),
+ std::make_pair(State::TRANSFER_PAUSED, kDrainOutAllCommand),
+ std::make_pair(State::DRAIN_PAUSED, kBurstCommand)},
+ State::TRANSFER_PAUSED));
+ }
+ d->makeNode(State::STANDBY, kStartCommand, idle);
+ }
+ return std::make_shared<StateSequenceFollower>(std::move(d));
+}
+static const NamedCommandSequence kPauseInSeq = std::make_tuple(
+ std::string("Pause"), 0, StreamTypeFilter::ANY, makePauseCommands(true, false));
+static const NamedCommandSequence kPauseOutSyncSeq = std::make_tuple(
+ std::string("Pause"), 0, StreamTypeFilter::SYNC, makePauseCommands(false, true));
+static const NamedCommandSequence kPauseOutAsyncSeq =
+ std::make_tuple(std::string("Pause"), kStreamTransientStateTransitionDelayMs,
+ StreamTypeFilter::ASYNC, makePauseCommands(false, false));
std::shared_ptr<StateSequence> makeFlushCommands(bool isInput, bool isSync) {
- return std::make_shared<SmartStateSequence>(std::vector<StateTransition>{
- std::make_pair(kStartCommand, StreamDescriptor::State::IDLE),
- std::make_pair(kBurstCommand, isInput || isSync
- ? StreamDescriptor::State::ACTIVE
- : StreamDescriptor::State::TRANSFERRING),
- std::make_pair(kPauseCommand, isInput || isSync
- ? StreamDescriptor::State::PAUSED
- : StreamDescriptor::State::TRANSFER_PAUSED),
- std::make_pair(kFlushCommand, isInput ? StreamDescriptor::State::STANDBY
- : StreamDescriptor::State::IDLE)});
+ using State = StreamDescriptor::State;
+ auto d = std::make_unique<StateDag>();
+ if (isInput) {
+ d->makeNodes({std::make_pair(State::STANDBY, kStartCommand),
+ std::make_pair(State::IDLE, kBurstCommand),
+ std::make_pair(State::ACTIVE, kPauseCommand),
+ std::make_pair(State::PAUSED, kFlushCommand)},
+ State::STANDBY);
+ } else {
+ StateDag::Node last = d->makeFinalNode(State::IDLE);
+ StateDag::Node idle = d->makeNodes({std::make_pair(State::IDLE, kBurstCommand),
+ std::make_pair(State::ACTIVE, kPauseCommand),
+ std::make_pair(State::PAUSED, kFlushCommand)},
+ last);
+ if (!isSync) {
+ idle.children().push_back(
+ d->makeNodes({std::make_pair(State::TRANSFERRING, kPauseCommand),
+ std::make_pair(State::TRANSFER_PAUSED, kFlushCommand)},
+ last));
+ }
+ d->makeNode(State::STANDBY, kStartCommand, idle);
+ }
+ return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kFlushInSeq = std::make_tuple(
std::string("Flush"), 0, StreamTypeFilter::ANY, makeFlushCommands(true, false));
@@ -3374,13 +3587,21 @@
StreamTypeFilter::ASYNC, makeFlushCommands(false, false));
std::shared_ptr<StateSequence> makeDrainPauseFlushOutCommands(bool isSync) {
- return std::make_shared<SmartStateSequence>(std::vector<StateTransition>{
- std::make_pair(kStartCommand, StreamDescriptor::State::IDLE),
- std::make_pair(kBurstCommand, isSync ? StreamDescriptor::State::ACTIVE
- : StreamDescriptor::State::TRANSFERRING),
- std::make_pair(kDrainOutAllCommand, StreamDescriptor::State::DRAINING),
- std::make_pair(kPauseCommand, StreamDescriptor::State::DRAIN_PAUSED),
- std::make_pair(kFlushCommand, StreamDescriptor::State::IDLE)});
+ using State = StreamDescriptor::State;
+ auto d = std::make_unique<StateDag>();
+ StateDag::Node draining = d->makeNodes({std::make_pair(State::DRAINING, kPauseCommand),
+ std::make_pair(State::DRAIN_PAUSED, kFlushCommand)},
+ State::IDLE);
+ StateDag::Node active = d->makeNode(State::ACTIVE, kDrainOutAllCommand, draining);
+ StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
+ if (!isSync) {
+ idle.children().push_back(d->makeNode(State::TRANSFERRING, kDrainOutAllCommand, draining));
+ } else {
+ // If we get straight into IDLE on drain, no further testing is possible.
+ active.children().push_back(d->makeFinalNode(State::IDLE));
+ }
+ d->makeNode(State::STANDBY, kStartCommand, idle);
+ return std::make_shared<StateSequenceFollower>(std::move(d));
}
static const NamedCommandSequence kDrainPauseFlushOutSyncSeq =
std::make_tuple(std::string("DrainPauseFlush"), kStreamTransientStateTransitionDelayMs,
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index 8938618..c5a0943 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -47,6 +47,10 @@
using aidl::android::hardware::audio::effect::IFactory;
using aidl::android::hardware::audio::effect::Parameter;
using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::AudioSource;
enum ParamName { PARAM_INSTANCE_NAME };
using EffectTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>>;
@@ -73,6 +77,13 @@
std::shared_ptr<IFactory> mFactory;
std::shared_ptr<IEffect> mEffect;
Descriptor mDescriptor;
+
+ void setAndGetParameter(Parameter::Id id, const Parameter& set) {
+ Parameter get;
+ EXPECT_IS_OK(mEffect->setParameter(set));
+ EXPECT_IS_OK(mEffect->getParameter(id, &get));
+ EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+ }
};
TEST_P(AudioEffectTest, SetupAndTearDown) {
@@ -392,14 +403,8 @@
Parameter::Common common = EffectHelper::createParamCommon(
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
- Parameter get = Parameter(), set = Parameter();
- set.set<Parameter::common>(common);
- EXPECT_IS_OK(mEffect->setParameter(set));
-
- Parameter::Id id;
- id.set<Parameter::Id::commonTag>(Parameter::common);
- EXPECT_IS_OK(mEffect->getParameter(id, &get));
- EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+ ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
@@ -414,14 +419,8 @@
Parameter::Common common = EffectHelper::createParamCommon(
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
- Parameter get = Parameter(), set = Parameter();
- set.set<Parameter::common>(common);
- EXPECT_IS_OK(mEffect->setParameter(set));
-
- Parameter::Id id;
- id.set<Parameter::Id::commonTag>(Parameter::common);
- EXPECT_IS_OK(mEffect->getParameter(id, &get));
- EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+ ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
ASSERT_NO_FATAL_FAILURE(close(mEffect));
@@ -439,14 +438,8 @@
Parameter::Common common = EffectHelper::createParamCommon(
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
- Parameter get = Parameter(), set = Parameter();
- set.set<Parameter::common>(common);
- EXPECT_IS_OK(mEffect->setParameter(set));
-
- Parameter::Id id;
- id.set<Parameter::Id::commonTag>(Parameter::common);
- EXPECT_IS_OK(mEffect->getParameter(id, &get));
- EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+ ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
@@ -461,18 +454,11 @@
Parameter::Common common = EffectHelper::createParamCommon(
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
- Parameter get = Parameter(), set = Parameter();
- set.set<Parameter::common>(common);
- EXPECT_IS_OK(mEffect->setParameter(set));
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+ ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
-
- Parameter::Id id;
- id.set<Parameter::Id::commonTag>(Parameter::common);
- EXPECT_IS_OK(mEffect->getParameter(id, &get));
- EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
-
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
}
@@ -487,21 +473,102 @@
Parameter::Common common = EffectHelper::createParamCommon(
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
- Parameter get = Parameter(), set = Parameter();
- set.set<Parameter::common>(common);
- EXPECT_IS_OK(mEffect->setParameter(set));
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+ ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
- Parameter::Id id;
- id.set<Parameter::Id::commonTag>(Parameter::common);
- EXPECT_IS_OK(mEffect->getParameter(id, &get));
- EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+ ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
}
+
+// Set and get AudioDeviceDescription in Parameter
+TEST_P(AudioEffectTest, SetAndGetParameterDeviceDescription) {
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+ ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+ std::vector<AudioDeviceDescription> deviceDescs = {
+ {.type = AudioDeviceType::IN_DEFAULT,
+ .connection = AudioDeviceDescription::CONNECTION_ANALOG},
+ {.type = AudioDeviceType::IN_DEVICE,
+ .connection = AudioDeviceDescription::CONNECTION_BT_A2DP}};
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::deviceDescription);
+ ASSERT_NO_FATAL_FAILURE(
+ setAndGetParameter(id, Parameter::make<Parameter::deviceDescription>(deviceDescs)));
+
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(mEffect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Set and get AudioMode in Parameter
+TEST_P(AudioEffectTest, SetAndGetParameterAudioMode) {
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+ ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::mode);
+ ASSERT_NO_FATAL_FAILURE(
+ setAndGetParameter(id, Parameter::make<Parameter::mode>(AudioMode::NORMAL)));
+ ASSERT_NO_FATAL_FAILURE(
+ setAndGetParameter(id, Parameter::make<Parameter::mode>(AudioMode::IN_COMMUNICATION)));
+
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(mEffect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Set and get AudioSource in Parameter
+TEST_P(AudioEffectTest, SetAndGetParameterAudioSource) {
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+ ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::source);
+ ASSERT_NO_FATAL_FAILURE(
+ setAndGetParameter(id, Parameter::make<Parameter::source>(AudioSource::DEFAULT)));
+ ASSERT_NO_FATAL_FAILURE(setAndGetParameter(
+ id, Parameter::make<Parameter::source>(AudioSource::VOICE_RECOGNITION)));
+
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(mEffect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Set and get VolumeStereo in Parameter
+TEST_P(AudioEffectTest, SetAndGetParameterVolume) {
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+ ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::volumeStereo);
+ Parameter::VolumeStereo volume = {.left = 10.0, .right = 10.0};
+ ASSERT_NO_FATAL_FAILURE(
+ setAndGetParameter(id, Parameter::make<Parameter::volumeStereo>(volume)));
+
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(mEffect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
/// Data processing test
// Send data to effects and expect it to be consumed by checking statusMQ.
TEST_P(AudioEffectTest, ConsumeDataInProcessingState) {
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index e99c4a4..82c8757 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -18,6 +18,7 @@
#include <Utils.h>
#include <aidl/Vintf.h>
+#include <unordered_set>
#include "EffectHelper.h"
using namespace android;
@@ -38,30 +39,6 @@
* any index supported value test expects EX_NONE from IEffect.setParameter(), otherwise expects
* EX_ILLEGAL_ARGUMENT.
*/
-const std::vector<int> kRoomLevelValues = {
- EnvironmentalReverb::MIN_ROOM_LEVEL_MB - 1, EnvironmentalReverb::MIN_ROOM_LEVEL_MB,
- EnvironmentalReverb::MAX_ROOM_LEVEL_MB, EnvironmentalReverb::MAX_ROOM_LEVEL_MB + 1};
-const std::vector<int> kRoomHfLevelValues = {
- EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB - 1, EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB,
- EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB, EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB + 1};
-const std::vector<int> kDecayTimeValues = {
- EnvironmentalReverb::MIN_DECAY_TIME_MS - 1, EnvironmentalReverb::MIN_DECAY_TIME_MS,
- EnvironmentalReverb::MAX_DECAY_TIME_MS, EnvironmentalReverb::MAX_DECAY_TIME_MS + 1};
-const std::vector<int> kDecayHfRatioValues = {
- EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM - 1, EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM,
- EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM, EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM + 1};
-const std::vector<int> kLevelValues = {
- EnvironmentalReverb::MIN_LEVEL_MB - 1, EnvironmentalReverb::MIN_LEVEL_MB,
- EnvironmentalReverb::MAX_LEVEL_MB, EnvironmentalReverb::MAX_LEVEL_MB + 1};
-const std::vector<int> kDelayValues = {
- EnvironmentalReverb::MIN_DELAY_MS - 1, EnvironmentalReverb::MIN_DELAY_MS,
- EnvironmentalReverb::MAX_DELAY_MS, EnvironmentalReverb::MAX_DELAY_MS + 1};
-const std::vector<int> kDiffusionValues = {
- EnvironmentalReverb::MIN_DIFFUSION_PM - 1, EnvironmentalReverb::MIN_DIFFUSION_PM,
- EnvironmentalReverb::MAX_DIFFUSION_PM, EnvironmentalReverb::MAX_DIFFUSION_PM + 1};
-const std::vector<int> kDensityValues = {
- EnvironmentalReverb::MIN_DENSITY_PM - 1, EnvironmentalReverb::MIN_DENSITY_PM,
- EnvironmentalReverb::MAX_DENSITY_PM, EnvironmentalReverb::MAX_DENSITY_PM + 1};
class EnvironmentalReverbHelper : public EffectHelper {
public:
@@ -88,8 +65,7 @@
}
Parameter::Specific getDefaultParamSpecific() {
- EnvironmentalReverb er = EnvironmentalReverb::make<EnvironmentalReverb::roomLevelMb>(
- EnvironmentalReverb::MIN_ROOM_LEVEL_MB);
+ EnvironmentalReverb er = EnvironmentalReverb::make<EnvironmentalReverb::roomLevelMb>(-6000);
Parameter::Specific specific =
Parameter::Specific::make<Parameter::Specific::environmentalReverb>(er);
return specific;
@@ -99,14 +75,14 @@
std::shared_ptr<IFactory> mFactory;
std::shared_ptr<IEffect> mEffect;
Descriptor mDescriptor;
- int mRoomLevel = EnvironmentalReverb::MIN_ROOM_LEVEL_MB;
- int mRoomHfLevel = EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB;
+ int mRoomLevel = -6000;
+ int mRoomHfLevel = 0;
int mDecayTime = 1000;
int mDecayHfRatio = 500;
- int mLevel = EnvironmentalReverb::MIN_LEVEL_MB;
+ int mLevel = -6000;
int mDelay = 40;
- int mDiffusion = EnvironmentalReverb::MAX_DIFFUSION_PM;
- int mDensity = EnvironmentalReverb::MAX_DENSITY_PM;
+ int mDiffusion = 1000;
+ int mDensity = 1000;
bool mBypass = false;
void SetAndGetReverbParameters() {
@@ -202,11 +178,11 @@
switch (tag) {
case EnvironmentalReverb::roomLevelMb: {
int roomLevel = er.get<EnvironmentalReverb::roomLevelMb>();
- return isRoomLevelInRange(roomLevel);
+ return isRoomLevelInRange(erCap, roomLevel);
}
case EnvironmentalReverb::roomHfLevelMb: {
int roomHfLevel = er.get<EnvironmentalReverb::roomHfLevelMb>();
- return isRoomHfLevelInRange(roomHfLevel);
+ return isRoomHfLevelInRange(erCap, roomHfLevel);
}
case EnvironmentalReverb::decayTimeMs: {
int decayTime = er.get<EnvironmentalReverb::decayTimeMs>();
@@ -214,23 +190,23 @@
}
case EnvironmentalReverb::decayHfRatioPm: {
int decayHfRatio = er.get<EnvironmentalReverb::decayHfRatioPm>();
- return isDecayHfRatioInRange(decayHfRatio);
+ return isDecayHfRatioInRange(erCap, decayHfRatio);
}
case EnvironmentalReverb::levelMb: {
int level = er.get<EnvironmentalReverb::levelMb>();
- return isLevelInRange(level);
+ return isLevelInRange(erCap, level);
}
case EnvironmentalReverb::delayMs: {
int delay = er.get<EnvironmentalReverb::delayMs>();
- return isDelayInRange(delay);
+ return isDelayInRange(erCap, delay);
}
case EnvironmentalReverb::diffusionPm: {
int diffusion = er.get<EnvironmentalReverb::diffusionPm>();
- return isDiffusionInRange(diffusion);
+ return isDiffusionInRange(erCap, diffusion);
}
case EnvironmentalReverb::densityPm: {
int density = er.get<EnvironmentalReverb::densityPm>();
- return isDensityInRange(density);
+ return isDensityInRange(erCap, density);
}
case EnvironmentalReverb::bypass: {
return true;
@@ -241,45 +217,191 @@
return false;
}
- bool isRoomLevelInRange(int roomLevel) const {
- return roomLevel >= EnvironmentalReverb::MIN_ROOM_LEVEL_MB &&
- roomLevel <= EnvironmentalReverb::MAX_ROOM_LEVEL_MB;
+ bool isRoomLevelInRange(const EnvironmentalReverb::Capability& cap, int roomLevel) const {
+ return roomLevel >= cap.minRoomLevelMb && roomLevel <= cap.maxRoomLevelMb;
}
- bool isRoomHfLevelInRange(int roomHfLevel) const {
- return roomHfLevel >= EnvironmentalReverb::MIN_ROOM_HF_LEVEL_MB &&
- roomHfLevel <= EnvironmentalReverb::MAX_ROOM_HF_LEVEL_MB;
+ bool isRoomHfLevelInRange(const EnvironmentalReverb::Capability& cap, int roomHfLevel) const {
+ return roomHfLevel >= cap.minRoomHfLevelMb && roomHfLevel <= cap.maxRoomHfLevelMb;
}
bool isDecayTimeInRange(const EnvironmentalReverb::Capability& cap, int decayTime) const {
- return decayTime >= EnvironmentalReverb::MIN_DECAY_TIME_MS &&
- decayTime <= EnvironmentalReverb::MAX_DECAY_TIME_MS &&
- decayTime <= cap.maxDecayTimeMs;
+ return decayTime >= 0 && decayTime <= cap.maxDecayTimeMs;
}
- bool isDecayHfRatioInRange(int decayHfRatio) const {
- return decayHfRatio >= EnvironmentalReverb::MIN_DECAY_HF_RATIO_PM &&
- decayHfRatio <= EnvironmentalReverb::MAX_DECAY_HF_RATIO_PM;
+ bool isDecayHfRatioInRange(const EnvironmentalReverb::Capability& cap, int decayHfRatio) const {
+ return decayHfRatio >= cap.minDecayHfRatioPm && decayHfRatio <= cap.maxDecayHfRatioPm;
}
- bool isLevelInRange(int level) const {
- return level >= EnvironmentalReverb::MIN_LEVEL_MB &&
- level <= EnvironmentalReverb::MAX_LEVEL_MB;
+ bool isLevelInRange(const EnvironmentalReverb::Capability& cap, int level) const {
+ return level >= cap.minLevelMb && level <= cap.maxLevelMb;
}
- bool isDelayInRange(int delay) const {
- return delay >= EnvironmentalReverb::MIN_DELAY_MS &&
- delay <= EnvironmentalReverb::MAX_DELAY_MS;
+ bool isDelayInRange(const EnvironmentalReverb::Capability& cap, int delay) const {
+ return delay >= 0 && delay <= cap.maxDelayMs;
}
- bool isDiffusionInRange(int diffusion) const {
- return diffusion >= EnvironmentalReverb::MIN_DIFFUSION_PM &&
- diffusion <= EnvironmentalReverb::MAX_DIFFUSION_PM;
+ bool isDiffusionInRange(const EnvironmentalReverb::Capability& cap, int diffusion) const {
+ return diffusion >= 0 && diffusion <= cap.maxDiffusionPm;
}
- bool isDensityInRange(int density) const {
- return density >= EnvironmentalReverb::MIN_DENSITY_PM &&
- density <= EnvironmentalReverb::MAX_DENSITY_PM;
+ bool isDensityInRange(const EnvironmentalReverb::Capability& cap, int density) const {
+ return density >= 0 && density <= cap.maxDensityPm;
+ }
+
+ static std::unordered_set<int> getRoomLevelValues() {
+ auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID);
+ int minRoomLevelMb = std::numeric_limits<int>::max();
+ int maxRoomLevelMb = std::numeric_limits<int>::min();
+ for (const auto& it : descList) {
+ maxRoomLevelMb = std::max(
+ it.second.capability.get<Capability::environmentalReverb>().maxRoomLevelMb,
+ maxRoomLevelMb);
+ minRoomLevelMb = std::min(
+ it.second.capability.get<Capability::environmentalReverb>().minRoomLevelMb,
+ minRoomLevelMb);
+ }
+ return {std::numeric_limits<int>::min(), minRoomLevelMb - 1, minRoomLevelMb,
+ (minRoomLevelMb + maxRoomLevelMb) >> 1, maxRoomLevelMb, maxRoomLevelMb + 1,
+ std::numeric_limits<int>::max()};
+ }
+
+ static std::unordered_set<int> getRoomHfLevelValues() {
+ auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID);
+ int minRoomHfLevelMb = std::numeric_limits<int>::max();
+ int maxRoomHfLevelMb = std::numeric_limits<int>::min();
+ for (const auto& it : descList) {
+ maxRoomHfLevelMb = std::max(
+ it.second.capability.get<Capability::environmentalReverb>().maxRoomHfLevelMb,
+ maxRoomHfLevelMb);
+ minRoomHfLevelMb = std::min(
+ it.second.capability.get<Capability::environmentalReverb>().minRoomHfLevelMb,
+ minRoomHfLevelMb);
+ }
+ return {std::numeric_limits<int>::min(),
+ minRoomHfLevelMb - 1,
+ minRoomHfLevelMb,
+ (minRoomHfLevelMb + maxRoomHfLevelMb) >> 1,
+ maxRoomHfLevelMb,
+ maxRoomHfLevelMb + 1,
+ std::numeric_limits<int>::max()};
+ }
+
+ static std::unordered_set<int> getDecayTimeValues() {
+ auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID);
+ const auto max = std::max_element(
+ descList.begin(), descList.end(),
+ [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
+ const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
+ return a.second.capability.get<Capability::environmentalReverb>()
+ .maxDecayTimeMs <
+ b.second.capability.get<Capability::environmentalReverb>()
+ .maxDecayTimeMs;
+ });
+ if (max == descList.end()) {
+ return {0};
+ }
+ int maxDecayTimeMs =
+ max->second.capability.get<Capability::environmentalReverb>().maxDecayTimeMs;
+ return {-1, 0, maxDecayTimeMs >> 1, maxDecayTimeMs - 1, maxDecayTimeMs, maxDecayTimeMs + 1};
+ }
+
+ static std::unordered_set<int> getDecayHfRatioValues() {
+ auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID);
+ int minDecayHfRatioPm = std::numeric_limits<int>::max();
+ int maxDecayHfRatioPm = std::numeric_limits<int>::min();
+ for (const auto& it : descList) {
+ maxDecayHfRatioPm = std::max(
+ it.second.capability.get<Capability::environmentalReverb>().maxDecayHfRatioPm,
+ maxDecayHfRatioPm);
+ minDecayHfRatioPm = std::min(
+ it.second.capability.get<Capability::environmentalReverb>().minDecayHfRatioPm,
+ minDecayHfRatioPm);
+ }
+ return {std::numeric_limits<int>::min(),
+ minDecayHfRatioPm - 1,
+ minDecayHfRatioPm,
+ (minDecayHfRatioPm + maxDecayHfRatioPm) >> 1,
+ maxDecayHfRatioPm,
+ maxDecayHfRatioPm + 1,
+ std::numeric_limits<int>::max()};
+ }
+
+ static std::unordered_set<int> getLevelValues() {
+ auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID);
+ int minLevelMb = std::numeric_limits<int>::max();
+ int maxLevelMb = std::numeric_limits<int>::min();
+ for (const auto& it : descList) {
+ maxLevelMb =
+ std::max(it.second.capability.get<Capability::environmentalReverb>().maxLevelMb,
+ maxLevelMb);
+ minLevelMb =
+ std::min(it.second.capability.get<Capability::environmentalReverb>().minLevelMb,
+ minLevelMb);
+ }
+ return {std::numeric_limits<int>::min(), minLevelMb - 1, minLevelMb,
+ (minLevelMb + maxLevelMb) >> 1, maxLevelMb, maxLevelMb + 1,
+ std::numeric_limits<int>::max()};
+ }
+
+ static std::unordered_set<int> getDelayValues() {
+ auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID);
+ const auto max = std::max_element(
+ descList.begin(), descList.end(),
+ [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
+ const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
+ return a.second.capability.get<Capability::environmentalReverb>().maxDelayMs <
+ b.second.capability.get<Capability::environmentalReverb>().maxDelayMs;
+ });
+ if (max == descList.end()) {
+ return {0};
+ }
+ int maxDelayMs = max->second.capability.get<Capability::environmentalReverb>().maxDelayMs;
+ return {-1, 0, maxDelayMs >> 1, maxDelayMs - 1, maxDelayMs, maxDelayMs + 1};
+ }
+
+ static std::unordered_set<int> getDiffusionValues() {
+ auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID);
+ const auto max = std::max_element(
+ descList.begin(), descList.end(),
+ [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
+ const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
+ return a.second.capability.get<Capability::environmentalReverb>()
+ .maxDiffusionPm <
+ b.second.capability.get<Capability::environmentalReverb>()
+ .maxDiffusionPm;
+ });
+ if (max == descList.end()) {
+ return {0};
+ }
+ int maxDiffusionPm =
+ max->second.capability.get<Capability::environmentalReverb>().maxDiffusionPm;
+ return {-1, 0, maxDiffusionPm >> 1, maxDiffusionPm - 1, maxDiffusionPm, maxDiffusionPm + 1};
+ }
+
+ static std::unordered_set<int> getDensityValues() {
+ auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID);
+ const auto max = std::max_element(
+ descList.begin(), descList.end(),
+ [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
+ const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
+ return a.second.capability.get<Capability::environmentalReverb>().maxDensityPm <
+ b.second.capability.get<Capability::environmentalReverb>().maxDensityPm;
+ });
+ if (max == descList.end()) {
+ return {0};
+ }
+ int maxDensityPm =
+ max->second.capability.get<Capability::environmentalReverb>().maxDensityPm;
+ return {-1, 0, maxDensityPm >> 1, maxDensityPm - 1, maxDensityPm, maxDensityPm + 1};
}
private:
@@ -310,7 +432,7 @@
EnvironmentalReverbTest, EnvironmentalReverbRoomLevelTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(kRoomLevelValues)),
+ testing::ValuesIn(EnvironmentalReverbHelper::getRoomLevelValues())),
[](const testing::TestParamInfo<EnvironmentalReverbRoomLevelTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string roomLevel = std::to_string(std::get<1>(info.param));
@@ -347,7 +469,7 @@
EnvironmentalReverbTest, EnvironmentalReverbRoomHfLevelTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(kRoomHfLevelValues)),
+ testing::ValuesIn(EnvironmentalReverbHelper::getRoomHfLevelValues())),
[](const testing::TestParamInfo<EnvironmentalReverbRoomHfLevelTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string roomHfLevel = std::to_string(std::get<1>(info.param));
@@ -384,7 +506,7 @@
EnvironmentalReverbTest, EnvironmentalReverbDecayTimeTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(kDecayTimeValues)),
+ testing::ValuesIn(EnvironmentalReverbHelper::getDecayTimeValues())),
[](const testing::TestParamInfo<EnvironmentalReverbDecayTimeTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string decayTime = std::to_string(std::get<1>(info.param));
@@ -421,7 +543,7 @@
EnvironmentalReverbTest, EnvironmentalReverbDecayHfRatioTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(kDecayHfRatioValues)),
+ testing::ValuesIn(EnvironmentalReverbHelper::getDecayHfRatioValues())),
[](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string decayHfRatio = std::to_string(std::get<1>(info.param));
@@ -459,7 +581,7 @@
EnvironmentalReverbTest, EnvironmentalReverbLevelTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(kLevelValues)),
+ testing::ValuesIn(EnvironmentalReverbHelper::getLevelValues())),
[](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string level = std::to_string(std::get<1>(info.param));
@@ -496,7 +618,7 @@
EnvironmentalReverbTest, EnvironmentalReverbDelayTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(kDelayValues)),
+ testing::ValuesIn(EnvironmentalReverbHelper::getDelayValues())),
[](const testing::TestParamInfo<EnvironmentalReverbDelayTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string delay = std::to_string(std::get<1>(info.param));
@@ -533,7 +655,7 @@
EnvironmentalReverbTest, EnvironmentalReverbDiffusionTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(kDiffusionValues)),
+ testing::ValuesIn(EnvironmentalReverbHelper::getDiffusionValues())),
[](const testing::TestParamInfo<EnvironmentalReverbDiffusionTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string diffusion = std::to_string(std::get<1>(info.param));
@@ -570,7 +692,7 @@
EnvironmentalReverbTest, EnvironmentalReverbDensityTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(kDensityValues)),
+ testing::ValuesIn(EnvironmentalReverbHelper::getDensityValues())),
[](const testing::TestParamInfo<EnvironmentalReverbDensityTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string density = std::to_string(std::get<1>(info.param));
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h
index d828cee..3741a64 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.h
+++ b/camera/provider/aidl/vts/camera_aidl_test.h
@@ -17,7 +17,10 @@
#ifndef HARDWARE_INTERFACES_CAMERA_PROVIDER_AIDL_VTS_CAMERA_AIDL_TEST_H_
#define HARDWARE_INTERFACES_CAMERA_PROVIDER_AIDL_VTS_CAMERA_AIDL_TEST_H_
+// TODO: LOG_TAG should not be in header
+#ifndef LOG_TAG
#define LOG_TAG "camera_aidl_hal_test"
+#endif
#include <string>
#include <unordered_map>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 71afee3..76ed220 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -1,12 +1,4 @@
<compatibility-matrix version="1.0" type="framework" level="8">
- <hal format="hidl" optional="true">
- <name>android.hardware.atrace</name>
- <version>1.0</version>
- <interface>
- <name>IAtraceDevice</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="hidl" optional="false">
<name>android.hardware.audio</name>
<version>6.0</version>
@@ -277,14 +269,6 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.gatekeeper</name>
- <version>1.0</version>
- <interface>
- <name>IGatekeeper</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.gatekeeper</name>
<version>1</version>
@@ -359,6 +343,7 @@
<instance>default</instance>
</interface>
</hal>
+ <!-- Either the native or the HIDL mapper HAL must exist on the device -->
<hal format="hidl" optional="true">
<name>android.hardware.graphics.mapper</name>
<!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
@@ -716,23 +701,23 @@
</interface>
</hal>
<hal format="aidl" optional="true">
- <name>android.hardware.tv.cec</name>
+ <name>android.hardware.tv.hdmi.cec</name>
<interface>
<name>IHdmiCec</name>
<instance>default</instance>
</interface>
</hal>
<hal format="aidl" optional="true">
- <name>android.hardware.tv.earc</name>
+ <name>android.hardware.tv.hdmi.earc</name>
<interface>
<name>IEArc</name>
<instance>default</instance>
</interface>
</hal>
<hal format="aidl" optional="true">
- <name>android.hardware.tv.hdmi</name>
+ <name>android.hardware.tv.hdmi.connection</name>
<interface>
- <name>IHdmi</name>
+ <name>IHdmiConnection</name>
<instance>default</instance>
</interface>
</hal>
@@ -846,9 +831,10 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="native">
+ <!-- Either the native or the HIDL mapper HAL must exist on the device -->
+ <hal format="native" optional="true">
<name>mapper</name>
- <version>1.0</version>
+ <version>5.0</version>
<interface>
<name>I</name>
<regex-instance>.*</regex-instance>
diff --git a/contexthub/1.0/default/OWNERS b/contexthub/1.0/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/contexthub/1.0/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/contexthub/1.1/default/OWNERS b/contexthub/1.1/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/contexthub/1.1/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/contexthub/1.1/vts/functional/OWNERS b/contexthub/1.1/vts/functional/OWNERS
deleted file mode 100644
index 2cf5bca..0000000
--- a/contexthub/1.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 156070
-include ../../../1.0/vts/functional/OWNERS
diff --git a/contexthub/1.2/default/OWNERS b/contexthub/1.2/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/contexthub/1.2/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/contexthub/1.2/vts/functional/OWNERS b/contexthub/1.2/vts/functional/OWNERS
deleted file mode 100644
index 2cf5bca..0000000
--- a/contexthub/1.2/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 156070
-include ../../../1.0/vts/functional/OWNERS
diff --git a/contexthub/1.0/vts/functional/OWNERS b/contexthub/OWNERS
similarity index 81%
rename from contexthub/1.0/vts/functional/OWNERS
rename to contexthub/OWNERS
index f254cd5..d5cfc2e 100644
--- a/contexthub/1.0/vts/functional/OWNERS
+++ b/contexthub/OWNERS
@@ -1,5 +1,4 @@
# Bug component: 156070
-#Context Hub team
arthuri@google.com
bduddie@google.com
stange@google.com
diff --git a/contexthub/aidl/vts/OWNERS b/contexthub/aidl/vts/OWNERS
deleted file mode 100644
index 150818d..0000000
--- a/contexthub/aidl/vts/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-file:/contexthub/common/vts/OWNERS
diff --git a/contexthub/common/default/1.X/OWNERS b/contexthub/common/default/1.X/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/contexthub/common/default/1.X/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/contexthub/common/vts/OWNERS b/contexthub/common/vts/OWNERS
deleted file mode 100644
index 161b2f0..0000000
--- a/contexthub/common/vts/OWNERS
+++ /dev/null
@@ -1,8 +0,0 @@
-#Context Hub team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-#VTS team
-dshi@google.com
-trong@google.com
diff --git a/drm/aidl/vts/drm_hal_test.cpp b/drm/aidl/vts/drm_hal_test.cpp
index 14b3acf..847a4dc 100644
--- a/drm/aidl/vts/drm_hal_test.cpp
+++ b/drm/aidl/vts/drm_hal_test.cpp
@@ -198,6 +198,18 @@
EXPECT_NE(keySetId, keySetId2.keySetId);
}
+ for (auto level : {kHwSecureAll, kSwSecureCrypto}) {
+ Status err = Status::OK;
+ auto sid = openSession(level, &err);
+ if (err == Status::OK) {
+ closeSession(sid);
+ } else if (err == Status::ERROR_DRM_CANNOT_HANDLE) {
+ continue;
+ } else {
+ EXPECT_EQ(Status::ERROR_DRM_NOT_PROVISIONED, err);
+ provision();
+ }
+ }
ret = drmPlugin->removeOfflineLicense({keySetId});
EXPECT_TXN(ret);
EXPECT_EQ(Status::BAD_VALUE, DrmErr(ret));
diff --git a/graphics/Android.bp b/graphics/Android.bp
index 4c51454..4ae7ec7 100644
--- a/graphics/Android.bp
+++ b/graphics/Android.bp
@@ -21,6 +21,9 @@
static_libs: [
"android.hardware.graphics.allocator-V2-ndk",
],
+ defaults: [
+ "android.hardware.graphics.common-ndk_static",
+ ],
}
cc_defaults {
@@ -28,6 +31,9 @@
shared_libs: [
"android.hardware.graphics.allocator-V2-ndk",
],
+ defaults: [
+ "android.hardware.graphics.common-ndk_shared",
+ ],
}
cc_defaults {
diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl
index 6e7b739..e50d170 100644
--- a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl
@@ -34,7 +34,7 @@
package android.hardware.graphics.allocator;
@Backing(type="int") @VintfStability
enum AllocationError {
- BAD_DESCRIPTOR = 0,
- NO_RESOURCES = 1,
- UNSUPPORTED = 2,
+ BAD_DESCRIPTOR,
+ NO_RESOURCES,
+ UNSUPPORTED,
}
diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
index 980e246..49c2497 100644
--- a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
@@ -41,4 +41,5 @@
android.hardware.graphics.common.PixelFormat format = android.hardware.graphics.common.PixelFormat.UNSPECIFIED;
android.hardware.graphics.common.BufferUsage usage = android.hardware.graphics.common.BufferUsage.CPU_READ_NEVER;
long reservedSize;
+ android.hardware.graphics.common.ExtendableType[] additionalOptions;
}
diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl
index 48bef16..66e49a7 100644
--- a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl
@@ -35,7 +35,7 @@
@VintfStability
interface IAllocator {
/**
- * @deprecated As of android.hardware.graphics.allocator-V2, this is deprecated & replaced with allocate2
+ * @deprecated As of android.hardware.graphics.allocator-V2 in combination with AIMAPPER_VERSION_5 this is deprecated & replaced with allocate2. If android.hardware.graphics.mapper@4 is still in use, however, this is still required to be implemented.
*/
android.hardware.graphics.allocator.AllocationResult allocate(in byte[] descriptor, in int count);
android.hardware.graphics.allocator.AllocationResult allocate2(in android.hardware.graphics.allocator.BufferDescriptorInfo descriptor, in int count);
diff --git a/graphics/allocator/aidl/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl b/graphics/allocator/aidl/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
index ffc50b8..50aa2b7 100644
--- a/graphics/allocator/aidl/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
+++ b/graphics/allocator/aidl/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
@@ -17,6 +17,7 @@
package android.hardware.graphics.allocator;
import android.hardware.graphics.common.BufferUsage;
+import android.hardware.graphics.common.ExtendableType;
import android.hardware.graphics.common.PixelFormat;
@VintfStability
@@ -54,6 +55,9 @@
/**
* Buffer usage mask; valid flags can be found in the definition of
* BufferUsage.aidl in graphics/common
+ *
+ * The allocator must report isSupported() == false and reject any allocations
+ * with unrecognized buffer usages.
*/
BufferUsage usage = BufferUsage.CPU_READ_NEVER;
@@ -62,4 +66,16 @@
* See getReservedRegion for more information.
*/
long reservedSize;
+
+ /**
+ * Extensible additional options that can be set.
+ *
+ * This is intended for options that do not change the overall usage, but which do impact
+ * how a buffer is allocated. An example of this is compression level, such as for
+ * the EGL_EXT_surface_compression extension.
+ *
+ * The allocator must report isSupported() == false and reject any allocations
+ * with unrecognized options.
+ */
+ ExtendableType[] additionalOptions;
}
diff --git a/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl b/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl
index 71cebd6..2277bae 100644
--- a/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl
+++ b/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl
@@ -32,8 +32,10 @@
* @param count The number of buffers to allocate.
* @return An AllocationResult containing the result of the allocation
* @throws AllocationError on failure
- * @deprecated As of android.hardware.graphics.allocator-V2, this is deprecated & replaced with
- * allocate2
+ * @deprecated As of android.hardware.graphics.allocator-V2 in combination with
+ * AIMAPPER_VERSION_5 this is deprecated & replaced with allocate2.
+ * If android.hardware.graphics.mapper@4 is still in use, however, this is
+ * still required to be implemented.
*/
AllocationResult allocate(in byte[] descriptor, in int count);
diff --git a/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp b/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp
index 09f1c15..4778020 100644
--- a/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp
+++ b/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp
@@ -217,6 +217,8 @@
}
return ret;
}
+
+ int32_t allocatorVersion() const { return mIAllocatorVersion; }
};
BufferHandle::~BufferHandle() {
@@ -309,6 +311,62 @@
EXPECT_GE(buffer->stride(), 64);
}
+TEST_P(GraphicsAllocatorAidlTests, RejectsUnknownUsages) {
+ if (allocatorVersion() < 2) {
+ GTEST_SKIP() << "Must be version 2+";
+ return;
+ }
+
+ constexpr auto FirstInvalidV2Usage = static_cast<BufferUsage>(1LL << 33);
+
+ BufferUsage invalidUsage;
+ if (allocatorVersion() == 2) {
+ invalidUsage = FirstInvalidV2Usage;
+ } else {
+ GTEST_FAIL() << "Unknown version " << allocatorVersion();
+ }
+
+ BufferDescriptorInfo info{
+ .name = {"CPU_8888"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::RGBA_8888,
+ .usage = BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN,
+ .reservedSize = 0,
+ };
+
+ // First make sure we can allocate a known usage buffer as expected
+ EXPECT_TRUE(isSupported(info));
+ EXPECT_TRUE(allocate(info));
+
+ // Now add the unknown bit and verify it's rejected
+ info.usage |= invalidUsage;
+ EXPECT_FALSE(isSupported(info)) << "isSupported() returned true for unknown-to-HAL usage";
+ EXPECT_FALSE(allocate(info)) << "allocate succeeded for unknown-to-HAL usage";
+}
+
+TEST_P(GraphicsAllocatorAidlTests, RejectsUnknownOptions) {
+ if (allocatorVersion() < 2) {
+ GTEST_SKIP() << "Must be version 2+";
+ return;
+ }
+
+ BufferDescriptorInfo info{
+ .name = {"CPU_8888"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::RGBA_8888,
+ .usage = BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN,
+ .reservedSize = 0,
+ };
+ info.additionalOptions.push_back({"android.hardware.graphics.common.NotARealOption", 1});
+
+ EXPECT_FALSE(isSupported(info)) << "isSupported() returned true for unknown-to-HAL option";
+ EXPECT_FALSE(allocate(info)) << "allocate succeeded for unknown-to-HAL option";
+}
+
TEST_P(GraphicsFrontBufferTests, FrontBufferGpuToCpu) {
BufferDescriptorInfo info{
.name = {"CPU_8888"},
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.cpp b/graphics/composer/aidl/vts/VtsComposerClient.cpp
index 5bc7296..dd4161e 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.cpp
+++ b/graphics/composer/aidl/vts/VtsComposerClient.cpp
@@ -393,14 +393,31 @@
return {std::move(configs.first), vtsDisplays};
}
for (int config : configs.second) {
- auto status = updateDisplayProperties(&vtsDisplay, config);
+ auto status = addDisplayConfig(&vtsDisplay, config);
if (!status.isOk()) {
- ALOGE("Unable to get the displays for test, failed to update the properties "
+ ALOGE("Unable to get the displays for test, failed to add config "
"for display %" PRId64,
display);
return {std::move(status), vtsDisplays};
}
}
+
+ auto config = getActiveConfig(display);
+ if (!config.first.isOk()) {
+ ALOGE("Unable to get the displays for test, failed to get active config "
+ "for display %" PRId64, display);
+ return {std::move(config.first), vtsDisplays};
+ }
+
+ auto status = updateDisplayProperties(&vtsDisplay, config.second);
+ if (!status.isOk()) {
+ ALOGE("Unable to get the displays for test, "
+ "failed to update the properties "
+ "for display %" PRId64,
+ display);
+ return {std::move(status), vtsDisplays};
+ }
+
vtsDisplays.emplace_back(vtsDisplay);
addDisplayToDisplayResources(display, /*isVirtual*/ false);
}
@@ -409,7 +426,7 @@
}
}
-ScopedAStatus VtsComposerClient::updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config) {
+ScopedAStatus VtsComposerClient::addDisplayConfig(VtsDisplay* vtsDisplay, int32_t config) {
const auto width =
getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::WIDTH);
const auto height =
@@ -420,7 +437,6 @@
getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::CONFIG_GROUP);
if (width.first.isOk() && height.first.isOk() && vsyncPeriod.first.isOk() &&
configGroup.first.isOk()) {
- vtsDisplay->setDimensions(width.second, height.second);
vtsDisplay->addDisplayConfig(config, {vsyncPeriod.second, configGroup.second});
return ScopedAStatus::ok();
}
@@ -431,6 +447,21 @@
return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
}
+ScopedAStatus VtsComposerClient::updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config) {
+ const auto width =
+ getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::WIDTH);
+ const auto height =
+ getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::HEIGHT);
+ if (width.first.isOk() && height.first.isOk()) {
+ vtsDisplay->setDimensions(width.second, height.second);
+ return ScopedAStatus::ok();
+ }
+
+ LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk()
+ << ", height: " << height.first.isOk();
+ return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
+}
+
ScopedAStatus VtsComposerClient::addDisplayToDisplayResources(int64_t display, bool isVirtual) {
if (mDisplayResources.insert({display, DisplayResource(isVirtual)}).second) {
return ScopedAStatus::ok();
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.h b/graphics/composer/aidl/vts/VtsComposerClient.h
index 3625c8c..74c5da5 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.h
+++ b/graphics/composer/aidl/vts/VtsComposerClient.h
@@ -173,6 +173,7 @@
std::pair<ScopedAStatus, std::vector<VtsDisplay>> getDisplays();
private:
+ ScopedAStatus addDisplayConfig(VtsDisplay* vtsDisplay, int32_t config);
ScopedAStatus updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config);
ScopedAStatus addDisplayToDisplayResources(int64_t display, bool isVirtual);
diff --git a/graphics/mapper/stable-c/README.md b/graphics/mapper/stable-c/README.md
new file mode 100644
index 0000000..30f3ccc
--- /dev/null
+++ b/graphics/mapper/stable-c/README.md
@@ -0,0 +1,110 @@
+# IMapper "stable-c" HAL
+
+Starting with gralloc version 5, IMapper is now exposed as a C API instead of through HIDL or AIDL.
+This is due to HIDL being deprecated, and AIDL not wanting to support a pass-through mode & pointers
+for just a couple of clients such as IMapper. So instead a stable C API is used to fill this gap.
+
+## Implementing
+
+To provide an implementation a library implementing the AIMapper API interface should be provided
+in `/vendor/lib[64]/hw/mapper.<imapper_suffix>.so`. The `<imapper_suffix>` should be specified
+as the `<instance>` in the VINTF manifest `<interface>` section. For example:
+```xml
+<manifest version="1.0" type="device">
+ <hal format="native">
+ <name>mapper</name>
+ <version>5.0</version>
+ <interface>
+ <name>I</name>
+ <instance>minigbm</instance>
+ </interface>
+ </hal>
+</manifest>
+```
+defines that the IMapper 5.0 library is provided by `/vendor/lib[64]/hw/mapper.minigbm.so`.
+
+This library must export the following `extern "C"` symbols:
+
+### `ANDROID_HAL_STABLEC_VERSION`
+
+This is a uint32_t that should simply be set to the exported AIMapper version. For example:
+```c++
+extern "C" uint32_t ANDROID_HAL_STABLEC_VERSION = AIMAPPER_VERSION_5;
+```
+
+### `AIMapper_loadIMapper`
+
+This is what should actually load the HAL interface. The full type signature is
+```c++
+extern "C" AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation)
+```
+
+See `include/android/hardware/graphics/mapper/IMapper.h` for complete documentation on what
+this function must return.
+
+To make it easier to implement this C API, a header-only helper library is provided called
+`libimapper_providerutils`. This library handles mapping from the C API struct to a C++ class
+as well as provides helpers for encoding & decoding metadata, largely replacing the role that
+`libgralloctypes` filled with IMapper 4.
+
+To use this library, create a class that extends from `IMapperV5Impl` and use `IMapperProvider` to
+implement `AIMapper_loadIMapper`:
+
+```c++
+// The IMapper interface itself
+#include <android/hardware/graphics/mapper/IMapper.h>
+// Helpers for reading & writing metadata
+#include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
+// Helper for providing the implementation interface
+#include <android/hardware/graphics/mapper/utils/IMapperProvider.h>
+
+// Define an IMapperV5 implementation
+class CrosGrallocMapperV5 final : public vendor::mapper::IMapperV5Impl {
+ // Override all the methods of IMapperV5Impl
+ AIMapper_Error importBuffer(const native_handle_t* _Nonnull handle,
+ buffer_handle_t _Nullable* _Nonnull outBufferHandle) override;
+ [etc...]
+};
+
+// Expose the required C symbols
+
+extern "C" uint32_t ANDROID_HAL_STABLEC_VERSION = AIMAPPER_VERSION_5;
+
+extern "C" AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation) {
+ // Define an IMapperProvider for our V5 implementation
+ static vendor::mapper::IMapperProvider<CrosGrallocMapperV5> provider;
+ return provider.load(outImplementation);
+}
+```
+
+A complete example, including using IMapperMetadataTypes, can be found in the cuttlefish
+implementation in `//external/minigbm/cros_gralloc/mapper_stablec`
+
+### Testing
+
+As with HIDL & AIDL HALs, a VTS test is provided to validate the implementation. It is found in the
+`vts` folder and may be run using `$ atest VtsHalGraphicsMapperStableC_TargetTest`
+
+## Using
+
+It is strongly recommended that clients use either the `AHardwareBuffer` (preferred) or
+`GraphicBufferMapper` (from libui) APIs to use the mapper HAL rather than attempting to use
+`AIMapper` directly.
+
+## Version changes
+
+### Version 5
+
+* Initial introduction of this HAL interface
+* Largely feature-equivalent to IMapper4
+* Requires allocator-V2
+* Removes `BufferDescriptorInfo`;
+* IsSupported has moved to IAllocator
+* Removes `validateBufferSize`, validation is instead handled by clients using metadata queries
+* Getting the following StandardMetadataType is now mandatory:
+ * STRIDE
+* Setting the following StandardMetadataTypes is now mandatory:
+ * DATASPACE
+ * SMPTE2086
+ * CTA861_3
+ * BLEND_MODE
diff --git a/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h b/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
index 0f6d146..0de88cd 100644
--- a/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
+++ b/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
@@ -241,7 +241,9 @@
* acceptable.
*
* 1D buffers (width = size in bytes, height = 1, pixel_format = BLOB) must
- * "lock in place". The buffers must be directly accessible via mapping.
+ * "lock in place" and behave similar to shared memory. That is, multiple threads or processes
+ * may lock the buffer for reading & writing and the results must follow the device's memory
+ * model.
*
* The client must not modify the content of the buffer outside of
* @p accessRegion, and the device need not guarantee that content outside
diff --git a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
index e29d16e..2c06353 100644
--- a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
+++ b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
@@ -154,6 +154,7 @@
std::shared_ptr<IAllocator> mAllocator;
AIMapper* mIMapper = nullptr;
AIMapper_loadIMapperFn mIMapperLoader;
+ int32_t* mIMapperHALVersion = nullptr;
protected:
void Initialize(std::shared_ptr<IAllocator> allocator) {
@@ -171,10 +172,12 @@
ASSERT_NE(nullptr, mIMapperLoader) << "AIMapper_locaIMapper missing from " << lib_name;
ASSERT_EQ(AIMAPPER_ERROR_NONE, mIMapperLoader(&mIMapper));
ASSERT_NE(mIMapper, nullptr);
+ mIMapperHALVersion = (int32_t*)dlsym(so, "ANDROID_HAL_MAPPER_VERSION");
}
public:
AIMapper_loadIMapperFn getIMapperLoader() const { return mIMapperLoader; }
+ int32_t* getHalVersion() const { return mIMapperHALVersion; }
std::unique_ptr<BufferAllocation> allocate(const BufferDescriptorInfo& descriptorInfo) {
AllocationResult result;
@@ -557,6 +560,15 @@
void TearDown() override {}
};
+TEST_P(GraphicsMapperStableCTests, VersionChecks) {
+ ASSERT_NE(nullptr, getHalVersion()) << "Resolving ANDROID_HAL_MAPPER_VERSION symbol failed";
+ int32_t halVersion = *getHalVersion();
+ EXPECT_EQ(halVersion, AIMAPPER_VERSION_5) << "Unrecognized ANDROID_HAL_MAPPER_VERSION";
+ EXPECT_EQ(mapper()->version, AIMAPPER_VERSION_5) << "Unrecognized AIMapper::version";
+ EXPECT_EQ(halVersion, mapper()->version)
+ << "AIMapper version & ANDROID_HAL_MAPPER_VERSION don't agree";
+}
+
TEST_P(GraphicsMapperStableCTests, AllV5CallbacksDefined) {
ASSERT_GE(mapper()->version, AIMAPPER_VERSION_5);
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index a4d4ace..64d83f3 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -46,8 +46,8 @@
}
-cc_library {
- name: "android.hardware.health-translate-ndk",
+cc_defaults {
+ name: "android.hardware.health-translate-ndk_defaults",
vendor_available: true,
recovery_available: true,
host_supported: true,
@@ -55,7 +55,6 @@
shared_libs: [
"libbinder_ndk",
"libhidlbase",
- "android.hardware.health-V1-ndk",
"android.hardware.health@2.0",
"android.hardware.health@2.1",
],
@@ -71,6 +70,23 @@
},
}
+cc_library {
+ name: "android.hardware.health-translate-ndk",
+ defaults: ["android.hardware.health-translate-ndk_defaults"],
+ shared_libs: [
+ "android.hardware.health-V1-ndk",
+ ],
+}
+
+// TODO(b/251425963): remove when android.hardware.health is upgraded to V2.
+cc_library {
+ name: "android.hardware.health-translate-V1-ndk",
+ defaults: ["android.hardware.health-translate-ndk_defaults"],
+ shared_libs: [
+ "android.hardware.health-V1-ndk",
+ ],
+}
+
java_library {
name: "android.hardware.health-translate-java",
srcs: ["android/hardware/health/Translate.java"],
diff --git a/radio/aidl/vts/VtsHalRadioTargetTest.cpp b/radio/aidl/vts/VtsHalRadioTargetTest.cpp
index 03d3c5a..ccd4427 100644
--- a/radio/aidl/vts/VtsHalRadioTargetTest.cpp
+++ b/radio/aidl/vts/VtsHalRadioTargetTest.cpp
@@ -55,7 +55,7 @@
testing::ValuesIn(android::getAidlHalInstanceNames(IRadioNetwork::descriptor)),
android::PrintInstanceNameToString);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioSapTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SapTest);
INSTANTIATE_TEST_SUITE_P(PerInstance, SapTest,
testing::ValuesIn(android::getAidlHalInstanceNames(ISap::descriptor)),
android::PrintInstanceNameToString);
diff --git a/tv/cec/aidl/Android.bp b/tv/cec/aidl/Android.bp
deleted file mode 100644
index 0b0e7cf..0000000
--- a/tv/cec/aidl/Android.bp
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-aidl_interface {
- name: "android.hardware.tv.cec",
- vendor_available: true,
- srcs: ["android/hardware/tv/cec/*.aidl"],
- stability: "vintf",
- backend: {
- java: {
- sdk_version: "module_current",
- },
- },
-}
diff --git a/tv/cec/aidl/OWNERS b/tv/cec/aidl/OWNERS
deleted file mode 100644
index d9c6783..0000000
--- a/tv/cec/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 826094
-include platform/frameworks/base:/core/java/android/hardware/hdmi/OWNERS
\ No newline at end of file
diff --git a/tv/cec/aidl/default/android.hardware.tv.cec-service.rc b/tv/cec/aidl/default/android.hardware.tv.cec-service.rc
deleted file mode 100644
index c79520c..0000000
--- a/tv/cec/aidl/default/android.hardware.tv.cec-service.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service vendor.cec-default /vendor/bin/hw/android.hardware.tv.cec-service
- interface aidl android.hardware.tv.cec.IHdmiCec/default
- class hal
- user system
- group system
diff --git a/tv/cec/aidl/vts/functional/Android.bp b/tv/cec/aidl/vts/functional/Android.bp
deleted file mode 100644
index 37fbaf0..0000000
--- a/tv/cec/aidl/vts/functional/Android.bp
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_test {
- name: "VtsHalTvCecAidlTargetTest",
- defaults: [
- "VtsHalTargetTestDefaults",
- "use_libaidlvintf_gtest_helper_static",
- ],
- srcs: ["VtsHalTvCecAidlTargetTest.cpp"],
- static_libs: [
- "android.hardware.tv.cec-V1-ndk",
- "android.hardware.tv.hdmi-V1-ndk",
- ],
- shared_libs: [
- "libbinder_ndk",
- ],
- test_suites: [
- "general-tests",
- "vts",
- ],
- disable_framework: true,
-}
diff --git a/tv/earc/aidl/default/android.hardware.tv.earc-service.rc b/tv/earc/aidl/default/android.hardware.tv.earc-service.rc
deleted file mode 100644
index 0d9063e..0000000
--- a/tv/earc/aidl/default/android.hardware.tv.earc-service.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service vendor.earc-default /vendor/bin/hw/android.hardware.tv.earc-service
- interface aidl android.hardware.tv.earc.IEArc/default
- class hal
- user system
- group system
diff --git a/tv/hdmi/aidl/default/Android.bp b/tv/hdmi/aidl/default/Android.bp
deleted file mode 100644
index 3e466a0..0000000
--- a/tv/hdmi/aidl/default/Android.bp
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_binary {
- name: "android.hardware.tv.hdmi-service",
- vintf_fragments: ["android.hardware.tv.hdmi-service.xml"],
- relative_install_path: "hw",
- vendor: true,
- cflags: [
- "-Wall",
- "-Wextra",
- ],
- init_rc: ["android.hardware.tv.hdmi-service.rc"],
- srcs: [
- "serviceMock.cpp",
- "HdmiMock.cpp",
- ],
- shared_libs: [
- "libbinder_ndk",
- "liblog",
- "libbase",
- "libutils",
- "libhardware",
- "libhidlbase",
- "android.hardware.tv.hdmi-V1-ndk",
- ],
-}
-
-cc_fuzz {
- name: "android.hardware.tv.hdmi-service_fuzzer",
- defaults: ["service_fuzzer_defaults"],
- static_libs: [
- "android.hardware.tv.hdmi-V1-ndk",
- "liblog",
- ],
- srcs: [
- "fuzzer.cpp",
- "HdmiMock.cpp",
- ],
- fuzz_config: {
- componentid: 826094,
- },
-}
diff --git a/tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.rc b/tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.rc
deleted file mode 100644
index c926221..0000000
--- a/tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service vendor.hdmi-default /vendor/bin/hw/android.hardware.tv.hdmi-service
- interface aidl android.hardware.tv.hdmi.IHdmi/default
- class hal
- user system
- group system
diff --git a/tv/hdmi/aidl/vts/functional/Android.bp b/tv/hdmi/aidl/vts/functional/Android.bp
deleted file mode 100644
index f9af58d..0000000
--- a/tv/hdmi/aidl/vts/functional/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_test {
- name: "VtsHalTvHdmiAidlTargetTest",
- defaults: [
- "VtsHalTargetTestDefaults",
- "use_libaidlvintf_gtest_helper_static",
- ],
- srcs: ["VtsHalTvHdmiAidlTargetTest.cpp"],
- static_libs: [
- "android.hardware.tv.hdmi-V1-ndk",
- ],
- shared_libs: [
- "libbinder_ndk",
- ],
- test_suites: [
- "general-tests",
- "vts",
- ],
- disable_framework: true,
-}
diff --git a/tv/hdmi/aidl/Android.bp b/tv/hdmi/cec/aidl/Android.bp
similarity index 90%
rename from tv/hdmi/aidl/Android.bp
rename to tv/hdmi/cec/aidl/Android.bp
index d8c6e5f..1bd9e41 100644
--- a/tv/hdmi/aidl/Android.bp
+++ b/tv/hdmi/cec/aidl/Android.bp
@@ -17,9 +17,9 @@
}
aidl_interface {
- name: "android.hardware.tv.hdmi",
+ name: "android.hardware.tv.hdmi.cec",
vendor_available: true,
- srcs: ["android/hardware/tv/hdmi/*.aidl"],
+ srcs: ["android/hardware/tv/hdmi/cec/*.aidl"],
stability: "vintf",
backend: {
java: {
diff --git a/tv/hdmi/aidl/OWNERS b/tv/hdmi/cec/aidl/OWNERS
similarity index 100%
rename from tv/hdmi/aidl/OWNERS
rename to tv/hdmi/cec/aidl/OWNERS
diff --git a/tv/hdmi/cec/aidl/TEST_MAPPING b/tv/hdmi/cec/aidl/TEST_MAPPING
new file mode 100644
index 0000000..17d6bca
--- /dev/null
+++ b/tv/hdmi/cec/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "VtsHalTvHdmiCecAidlTargetTest"
+ }
+ ]
+}
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/AbortReason.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/AbortReason.aidl
similarity index 97%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/AbortReason.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/AbortReason.aidl
index 7377d81..45b973a 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/AbortReason.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/AbortReason.aidl
@@ -31,7 +31,7 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
@Backing(type="int") @VintfStability
enum AbortReason {
UNRECOGNIZED_MODE = 0,
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecDeviceType.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
similarity index 97%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecDeviceType.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
index 4d991cd..08dc1ee 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecDeviceType.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
@@ -31,7 +31,7 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
@Backing(type="byte") @VintfStability
enum CecDeviceType {
INACTIVE = -1,
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecLogicalAddress.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
similarity index 97%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecLogicalAddress.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
index a36935b..1fc9fb7 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecLogicalAddress.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
@@ -31,7 +31,7 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
@Backing(type="byte") @VintfStability
enum CecLogicalAddress {
TV = 0,
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecMessage.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessage.aidl
similarity index 91%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecMessage.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessage.aidl
index 5ce5ce8..9de07ec 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecMessage.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessage.aidl
@@ -31,11 +31,11 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
@VintfStability
parcelable CecMessage {
- android.hardware.tv.cec.CecLogicalAddress initiator;
- android.hardware.tv.cec.CecLogicalAddress destination;
+ android.hardware.tv.hdmi.cec.CecLogicalAddress initiator;
+ android.hardware.tv.hdmi.cec.CecLogicalAddress destination;
byte[] body;
const int MAX_MESSAGE_BODY_LENGTH = 15;
}
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecMessageType.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessageType.aidl
similarity index 98%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecMessageType.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessageType.aidl
index 61ebb94..31ca895 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/CecMessageType.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessageType.aidl
@@ -31,7 +31,7 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
@Backing(type="int") @VintfStability
enum CecMessageType {
FEATURE_ABORT = 0,
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCec.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
similarity index 85%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCec.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
index cf8425e..0881489 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCec.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
@@ -31,17 +31,17 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
@VintfStability
interface IHdmiCec {
- android.hardware.tv.cec.Result addLogicalAddress(in android.hardware.tv.cec.CecLogicalAddress addr);
+ android.hardware.tv.hdmi.cec.Result addLogicalAddress(in android.hardware.tv.hdmi.cec.CecLogicalAddress addr);
void clearLogicalAddress();
void enableAudioReturnChannel(in int portId, in boolean enable);
int getCecVersion();
int getPhysicalAddress();
int getVendorId();
- android.hardware.tv.cec.SendMessageResult sendMessage(in android.hardware.tv.cec.CecMessage message);
- void setCallback(in android.hardware.tv.cec.IHdmiCecCallback callback);
+ android.hardware.tv.hdmi.cec.SendMessageResult sendMessage(in android.hardware.tv.hdmi.cec.CecMessage message);
+ void setCallback(in android.hardware.tv.hdmi.cec.IHdmiCecCallback callback);
void setLanguage(in String language);
void enableWakeupByOtp(in boolean value);
void enableCec(in boolean value);
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCecCallback.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
similarity index 93%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCecCallback.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
index 1918765..43fdfbd 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/IHdmiCecCallback.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
@@ -31,8 +31,8 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
@VintfStability
interface IHdmiCecCallback {
- oneway void onCecMessage(in android.hardware.tv.cec.CecMessage message);
+ oneway void onCecMessage(in android.hardware.tv.hdmi.cec.CecMessage message);
}
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/Result.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/Result.aidl
similarity index 97%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/Result.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/Result.aidl
index a5ba276..c6828ef 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/Result.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/Result.aidl
@@ -31,7 +31,7 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
@Backing(type="byte") @VintfStability
enum Result {
SUCCESS = 0,
diff --git a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/SendMessageResult.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
similarity index 97%
rename from tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/SendMessageResult.aidl
rename to tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
index 58206c8..87b50c9 100644
--- a/tv/cec/aidl/aidl_api/android.hardware.tv.cec/current/android/hardware/tv/cec/SendMessageResult.aidl
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
@@ -31,7 +31,7 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
@Backing(type="byte") @VintfStability
enum SendMessageResult {
SUCCESS = 0,
diff --git a/tv/cec/aidl/android/hardware/tv/cec/AbortReason.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/AbortReason.aidl
similarity index 95%
rename from tv/cec/aidl/android/hardware/tv/cec/AbortReason.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/AbortReason.aidl
index 3ae23ec..297094d 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/AbortReason.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/AbortReason.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
/**
* Operand description [Abort Reason]
diff --git a/tv/cec/aidl/android/hardware/tv/cec/CecDeviceType.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
similarity index 94%
rename from tv/cec/aidl/android/hardware/tv/cec/CecDeviceType.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
index 16dfbec..8727a1d 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/CecDeviceType.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
@VintfStability
@Backing(type="byte")
diff --git a/tv/cec/aidl/android/hardware/tv/cec/CecLogicalAddress.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
similarity index 95%
rename from tv/cec/aidl/android/hardware/tv/cec/CecLogicalAddress.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
index fbf5328..e7e08a6 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/CecLogicalAddress.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
@VintfStability
@Backing(type="byte")
diff --git a/tv/cec/aidl/android/hardware/tv/cec/CecMessage.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessage.aidl
similarity index 92%
rename from tv/cec/aidl/android/hardware/tv/cec/CecMessage.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessage.aidl
index b126045..14a1bc7 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/CecMessage.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessage.aidl
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
-import android.hardware.tv.cec.CecLogicalAddress;
+import android.hardware.tv.hdmi.cec.CecLogicalAddress;
@VintfStability
parcelable CecMessage {
diff --git a/tv/cec/aidl/android/hardware/tv/cec/CecMessageType.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessageType.aidl
similarity index 98%
rename from tv/cec/aidl/android/hardware/tv/cec/CecMessageType.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessageType.aidl
index b544a91..becfea1 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/CecMessageType.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessageType.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
@VintfStability
@Backing(type="int")
diff --git a/tv/cec/aidl/android/hardware/tv/cec/IHdmiCec.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
similarity index 94%
rename from tv/cec/aidl/android/hardware/tv/cec/IHdmiCec.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
index dbf7139..577c377 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/IHdmiCec.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
-import android.hardware.tv.cec.CecLogicalAddress;
-import android.hardware.tv.cec.CecMessage;
-import android.hardware.tv.cec.IHdmiCecCallback;
-import android.hardware.tv.cec.Result;
-import android.hardware.tv.cec.SendMessageResult;
+import android.hardware.tv.hdmi.cec.CecLogicalAddress;
+import android.hardware.tv.hdmi.cec.CecMessage;
+import android.hardware.tv.hdmi.cec.IHdmiCecCallback;
+import android.hardware.tv.hdmi.cec.Result;
+import android.hardware.tv.hdmi.cec.SendMessageResult;
/**
* HDMI-CEC HAL interface definition.
diff --git a/tv/cec/aidl/android/hardware/tv/cec/IHdmiCecCallback.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
similarity index 91%
rename from tv/cec/aidl/android/hardware/tv/cec/IHdmiCecCallback.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
index 4934a64..ef73dd7 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/IHdmiCecCallback.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
-import android.hardware.tv.cec.CecMessage;
+import android.hardware.tv.hdmi.cec.CecMessage;
/**
* Callbacks from the HAL implementation to notify the system of new events.
diff --git a/tv/cec/aidl/android/hardware/tv/cec/Result.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/Result.aidl
similarity index 95%
rename from tv/cec/aidl/android/hardware/tv/cec/Result.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/Result.aidl
index 3184c46..1b1cd08 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/Result.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/Result.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
@VintfStability
@Backing(type="byte")
diff --git a/tv/cec/aidl/android/hardware/tv/cec/SendMessageResult.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
similarity index 94%
rename from tv/cec/aidl/android/hardware/tv/cec/SendMessageResult.aidl
rename to tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
index 8cb98bc..8f609d5 100644
--- a/tv/cec/aidl/android/hardware/tv/cec/SendMessageResult.aidl
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.tv.cec;
+package android.hardware.tv.hdmi.cec;
/**
* error code used for send_message.
diff --git a/tv/cec/aidl/default/Android.bp b/tv/hdmi/cec/aidl/default/Android.bp
similarity index 79%
rename from tv/cec/aidl/default/Android.bp
rename to tv/hdmi/cec/aidl/default/Android.bp
index 5479601..ea4bb94 100644
--- a/tv/cec/aidl/default/Android.bp
+++ b/tv/hdmi/cec/aidl/default/Android.bp
@@ -17,15 +17,15 @@
}
cc_binary {
- name: "android.hardware.tv.cec-service",
- vintf_fragments: ["android.hardware.tv.cec-service.xml"],
+ name: "android.hardware.tv.hdmi.cec-service",
+ vintf_fragments: ["android.hardware.tv.hdmi.cec-service.xml"],
relative_install_path: "hw",
vendor: true,
cflags: [
"-Wall",
"-Wextra",
],
- init_rc: ["android.hardware.tv.cec-service.rc"],
+ init_rc: ["android.hardware.tv.hdmi.cec-service.rc"],
srcs: [
"serviceMock.cpp",
"HdmiCecMock.cpp",
@@ -37,15 +37,15 @@
"libutils",
"libhardware",
"libhidlbase",
- "android.hardware.tv.cec-V1-ndk",
+ "android.hardware.tv.hdmi.cec-V1-ndk",
],
}
cc_fuzz {
- name: "android.hardware.tv.cec-service_fuzzer",
+ name: "android.hardware.tv.hdmi.cec-service_fuzzer",
defaults: ["service_fuzzer_defaults"],
static_libs: [
- "android.hardware.tv.cec-V1-ndk",
+ "android.hardware.tv.hdmi.cec-V1-ndk",
"liblog",
],
srcs: [
diff --git a/tv/cec/aidl/default/HdmiCecMock.cpp b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
similarity index 98%
rename from tv/cec/aidl/default/HdmiCecMock.cpp
rename to tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
index d8d655b..0212e7e 100644
--- a/tv/cec/aidl/default/HdmiCecMock.cpp
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "android.hardware.tv.cec"
+#define LOG_TAG "android.hardware.tv.hdmi.cec"
#include <android-base/logging.h>
#include <fcntl.h>
#include <utils/Log.h>
@@ -28,6 +28,7 @@
namespace android {
namespace hardware {
namespace tv {
+namespace hdmi {
namespace cec {
namespace implementation {
@@ -261,6 +262,7 @@
} // namespace implementation
} // namespace cec
+} // namespace hdmi
} // namespace tv
} // namespace hardware
} // namespace android
diff --git a/tv/cec/aidl/default/HdmiCecMock.h b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
similarity index 85%
rename from tv/cec/aidl/default/HdmiCecMock.h
rename to tv/hdmi/cec/aidl/default/HdmiCecMock.h
index 08f4d6f..aca0581 100644
--- a/tv/cec/aidl/default/HdmiCecMock.h
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <aidl/android/hardware/tv/cec/BnHdmiCec.h>
+#include <aidl/android/hardware/tv/hdmi/cec/BnHdmiCec.h>
#include <algorithm>
#include <vector>
@@ -23,16 +23,17 @@
namespace android {
namespace hardware {
namespace tv {
+namespace hdmi {
namespace cec {
namespace implementation {
-using ::aidl::android::hardware::tv::cec::BnHdmiCec;
-using ::aidl::android::hardware::tv::cec::CecLogicalAddress;
-using ::aidl::android::hardware::tv::cec::CecMessage;
-using ::aidl::android::hardware::tv::cec::IHdmiCec;
-using ::aidl::android::hardware::tv::cec::IHdmiCecCallback;
-using ::aidl::android::hardware::tv::cec::Result;
-using ::aidl::android::hardware::tv::cec::SendMessageResult;
+using ::aidl::android::hardware::tv::hdmi::cec::BnHdmiCec;
+using ::aidl::android::hardware::tv::hdmi::cec::CecLogicalAddress;
+using ::aidl::android::hardware::tv::hdmi::cec::CecMessage;
+using ::aidl::android::hardware::tv::hdmi::cec::IHdmiCec;
+using ::aidl::android::hardware::tv::hdmi::cec::IHdmiCecCallback;
+using ::aidl::android::hardware::tv::hdmi::cec::Result;
+using ::aidl::android::hardware::tv::hdmi::cec::SendMessageResult;
#define CEC_MSG_IN_FIFO "/dev/cec_aidl_in_pipe"
#define CEC_MSG_OUT_FIFO "/dev/cec_aidl_out_pipe"
@@ -89,6 +90,7 @@
};
} // namespace implementation
} // namespace cec
+} // namespace hdmi
} // namespace tv
} // namespace hardware
} // namespace android
diff --git a/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.rc b/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.rc
new file mode 100644
index 0000000..f4c9fcf
--- /dev/null
+++ b/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.rc
@@ -0,0 +1,5 @@
+service vendor.cec-default /vendor/bin/hw/android.hardware.tv.hdmi.cec-service
+ interface aidl android.hardware.tv.hdmi.cec.IHdmiCec/default
+ class hal
+ user system
+ group system
diff --git a/tv/cec/aidl/default/android.hardware.tv.cec-service.xml b/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.xml
similarity index 81%
rename from tv/cec/aidl/default/android.hardware.tv.cec-service.xml
rename to tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.xml
index e68450d..d48565c 100644
--- a/tv/cec/aidl/default/android.hardware.tv.cec-service.xml
+++ b/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.xml
@@ -1,6 +1,6 @@
<manifest version="1.0" type="device">
<hal format="aidl">
- <name>android.hardware.tv.cec</name>
+ <name>android.hardware.tv.hdmi.cec</name>
<version>1</version>
<interface>
<name>IHdmiCec</name>
diff --git a/tv/cec/aidl/default/fuzzer.cpp b/tv/hdmi/cec/aidl/default/fuzzer.cpp
similarity index 93%
rename from tv/cec/aidl/default/fuzzer.cpp
rename to tv/hdmi/cec/aidl/default/fuzzer.cpp
index 9f6a9ac..33453dc 100644
--- a/tv/cec/aidl/default/fuzzer.cpp
+++ b/tv/hdmi/cec/aidl/default/fuzzer.cpp
@@ -18,7 +18,7 @@
#include <fuzzer/FuzzedDataProvider.h>
using android::fuzzService;
-using android::hardware::tv::cec::implementation::HdmiCecMock;
+using android::hardware::tv::hdmi::cec::implementation::HdmiCecMock;
using ndk::SharedRefBase;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
diff --git a/tv/cec/aidl/default/serviceMock.cpp b/tv/hdmi/cec/aidl/default/serviceMock.cpp
similarity index 90%
rename from tv/cec/aidl/default/serviceMock.cpp
rename to tv/hdmi/cec/aidl/default/serviceMock.cpp
index ab86c3f..cbf85e5 100644
--- a/tv/cec/aidl/default/serviceMock.cpp
+++ b/tv/hdmi/cec/aidl/default/serviceMock.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "android.hardware.tv.cec-service-shim"
+#define LOG_TAG "android.hardware.tv.hdmi.cec-service-shim"
#include <android-base/logging.h>
#include <android/binder_manager.h>
@@ -23,7 +23,7 @@
#include <utils/Log.h>
#include "HdmiCecMock.h"
-using android::hardware::tv::cec::implementation::HdmiCecMock;
+using android::hardware::tv::hdmi::cec::implementation::HdmiCecMock;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(1);
diff --git a/tv/earc/aidl/vts/functional/Android.bp b/tv/hdmi/cec/aidl/vts/functional/Android.bp
similarity index 83%
copy from tv/earc/aidl/vts/functional/Android.bp
copy to tv/hdmi/cec/aidl/vts/functional/Android.bp
index 797547e..5c86d3f 100644
--- a/tv/earc/aidl/vts/functional/Android.bp
+++ b/tv/hdmi/cec/aidl/vts/functional/Android.bp
@@ -17,14 +17,15 @@
}
cc_test {
- name: "VtsHalTvEArcAidlTargetTest",
+ name: "VtsHalTvHdmiCecAidlTargetTest",
defaults: [
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
- srcs: ["VtsHalTvEArcAidlTargetTest.cpp"],
+ srcs: ["VtsHalTvHdmiCecAidlTargetTest.cpp"],
static_libs: [
- "android.hardware.tv.earc-V1-ndk",
+ "android.hardware.tv.hdmi.cec-V1-ndk",
+ "android.hardware.tv.hdmi.connection-V1-ndk",
],
shared_libs: [
"libbinder_ndk",
diff --git a/tv/hdmi/cec/aidl/vts/functional/AndroidTest.xml b/tv/hdmi/cec/aidl/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..63e7763
--- /dev/null
+++ b/tv/hdmi/cec/aidl/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 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 VtsHalTvHdmiCecAidlTargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalTvHdmiCecAidlTargetTest->/data/local/tmp/VtsHalTvHdmiCecAidlTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalTvHdmiCecAidlTargetTest" />
+ <option name="native-test-timeout" value="30m" />
+ </test>
+</configuration>
diff --git a/tv/cec/aidl/vts/functional/VtsHalTvCecAidlTargetTest.cpp b/tv/hdmi/cec/aidl/vts/functional/VtsHalTvHdmiCecAidlTargetTest.cpp
similarity index 86%
rename from tv/cec/aidl/vts/functional/VtsHalTvCecAidlTargetTest.cpp
rename to tv/hdmi/cec/aidl/vts/functional/VtsHalTvHdmiCecAidlTargetTest.cpp
index 69c209f..a2fb0f8 100644
--- a/tv/cec/aidl/vts/functional/VtsHalTvCecAidlTargetTest.cpp
+++ b/tv/hdmi/cec/aidl/vts/functional/VtsHalTvHdmiCecAidlTargetTest.cpp
@@ -18,10 +18,10 @@
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
-#include <aidl/android/hardware/tv/cec/BnHdmiCec.h>
-#include <aidl/android/hardware/tv/cec/BnHdmiCecCallback.h>
-#include <aidl/android/hardware/tv/cec/CecDeviceType.h>
-#include <aidl/android/hardware/tv/hdmi/BnHdmi.h>
+#include <aidl/android/hardware/tv/hdmi/cec/BnHdmiCec.h>
+#include <aidl/android/hardware/tv/hdmi/cec/BnHdmiCecCallback.h>
+#include <aidl/android/hardware/tv/hdmi/cec/CecDeviceType.h>
+#include <aidl/android/hardware/tv/hdmi/connection/BnHdmiConnection.h>
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
@@ -30,15 +30,15 @@
#include <sstream>
#include <vector>
-using ::aidl::android::hardware::tv::cec::BnHdmiCecCallback;
-using ::aidl::android::hardware::tv::cec::CecDeviceType;
-using ::aidl::android::hardware::tv::cec::CecLogicalAddress;
-using ::aidl::android::hardware::tv::cec::CecMessage;
-using ::aidl::android::hardware::tv::cec::IHdmiCec;
-using ::aidl::android::hardware::tv::cec::IHdmiCecCallback;
-using ::aidl::android::hardware::tv::cec::Result;
-using ::aidl::android::hardware::tv::cec::SendMessageResult;
-using ::aidl::android::hardware::tv::hdmi::HdmiPortInfo;
+using ::aidl::android::hardware::tv::hdmi::cec::BnHdmiCecCallback;
+using ::aidl::android::hardware::tv::hdmi::cec::CecDeviceType;
+using ::aidl::android::hardware::tv::hdmi::cec::CecLogicalAddress;
+using ::aidl::android::hardware::tv::hdmi::cec::CecMessage;
+using ::aidl::android::hardware::tv::hdmi::cec::IHdmiCec;
+using ::aidl::android::hardware::tv::hdmi::cec::IHdmiCecCallback;
+using ::aidl::android::hardware::tv::hdmi::cec::Result;
+using ::aidl::android::hardware::tv::hdmi::cec::SendMessageResult;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortInfo;
using ::ndk::SpAIBinder;
#define CEC_VERSION 0x05
diff --git a/tv/earc/aidl/Android.bp b/tv/hdmi/connection/aidl/Android.bp
similarity index 88%
rename from tv/earc/aidl/Android.bp
rename to tv/hdmi/connection/aidl/Android.bp
index 5db6032..b342c52 100644
--- a/tv/earc/aidl/Android.bp
+++ b/tv/hdmi/connection/aidl/Android.bp
@@ -17,9 +17,9 @@
}
aidl_interface {
- name: "android.hardware.tv.earc",
+ name: "android.hardware.tv.hdmi.connection",
vendor_available: true,
- srcs: ["android/hardware/tv/earc/*.aidl"],
+ srcs: ["android/hardware/tv/hdmi/connection/*.aidl"],
stability: "vintf",
backend: {
java: {
diff --git a/tv/hdmi/aidl/OWNERS b/tv/hdmi/connection/aidl/OWNERS
similarity index 100%
copy from tv/hdmi/aidl/OWNERS
copy to tv/hdmi/connection/aidl/OWNERS
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortInfo.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
similarity index 94%
rename from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortInfo.aidl
rename to tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
index 25c3be1..ac35c99 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortInfo.aidl
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
@@ -31,10 +31,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
@VintfStability
parcelable HdmiPortInfo {
- android.hardware.tv.hdmi.HdmiPortType type;
+ android.hardware.tv.hdmi.connection.HdmiPortType type;
int portId;
boolean cecSupported;
boolean arcSupported;
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortType.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
similarity index 97%
rename from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortType.aidl
rename to tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
index af5f0f7..fc2d7e5 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortType.aidl
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
@@ -31,7 +31,7 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
@Backing(type="byte") @VintfStability
enum HdmiPortType {
INPUT = 0,
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HpdSignal.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HpdSignal.aidl
similarity index 97%
rename from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HpdSignal.aidl
rename to tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HpdSignal.aidl
index eef4025..697da29 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HpdSignal.aidl
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HpdSignal.aidl
@@ -31,7 +31,7 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
@Backing(type="byte") @VintfStability
enum HpdSignal {
HDMI_HPD_PHYSICAL = 0,
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
similarity index 81%
rename from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl
rename to tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
index 809d392..98d1452 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
@@ -31,12 +31,12 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
@VintfStability
-interface IHdmi {
- android.hardware.tv.hdmi.HdmiPortInfo[] getPortInfo();
+interface IHdmiConnection {
+ android.hardware.tv.hdmi.connection.HdmiPortInfo[] getPortInfo();
boolean isConnected(in int portId);
- void setCallback(in android.hardware.tv.hdmi.IHdmiCallback callback);
- void setHpdSignal(android.hardware.tv.hdmi.HpdSignal signal);
- android.hardware.tv.hdmi.HpdSignal getHpdSignal();
+ void setCallback(in android.hardware.tv.hdmi.connection.IHdmiConnectionCallback callback);
+ void setHpdSignal(android.hardware.tv.hdmi.connection.HpdSignal signal);
+ android.hardware.tv.hdmi.connection.HpdSignal getHpdSignal();
}
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmiCallback.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
similarity index 94%
rename from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmiCallback.aidl
rename to tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
index 05fe623..f9f6856 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmiCallback.aidl
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
@@ -31,8 +31,8 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
@VintfStability
-interface IHdmiCallback {
+interface IHdmiConnectionCallback {
oneway void onHotplugEvent(in boolean connected, in int portId);
}
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/Result.aidl
similarity index 97%
rename from tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl
rename to tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/Result.aidl
index b6b0eb3..93182c5 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/Result.aidl
@@ -31,7 +31,7 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
@VintfStability
enum Result {
SUCCESS = 0,
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortInfo.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
similarity index 90%
rename from tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortInfo.aidl
rename to tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
index 2e2c858..c8a10d1 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortInfo.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
-import android.hardware.tv.hdmi.HdmiPortType;
+import android.hardware.tv.hdmi.connection.HdmiPortType;
/**
* HDMI port descriptor
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortType.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
similarity index 93%
rename from tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortType.aidl
rename to tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
index 59c0d42..4ec58ee 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortType.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
/**
* HDMI port type.
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/HpdSignal.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HpdSignal.aidl
similarity index 94%
rename from tv/hdmi/aidl/android/hardware/tv/hdmi/HpdSignal.aidl
rename to tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HpdSignal.aidl
index 05963f2..554dcf6 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/HpdSignal.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HpdSignal.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
/**
* HPD (Hotplug Detection) Signal Types
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
similarity index 71%
rename from tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl
rename to tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
index 457234d..c8759f2 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
-import android.hardware.tv.hdmi.HdmiPortInfo;
-import android.hardware.tv.hdmi.HpdSignal;
-import android.hardware.tv.hdmi.IHdmiCallback;
+import android.hardware.tv.hdmi.connection.HdmiPortInfo;
+import android.hardware.tv.hdmi.connection.HpdSignal;
+import android.hardware.tv.hdmi.connection.IHdmiConnectionCallback;
/**
- * HDMI HAL interface definition.
+ * HDMI Connection HAL interface definition.
*/
@VintfStability
-interface IHdmi {
+interface IHdmiConnection {
/**
* Gets the hdmi port information of underlying hardware.
*
@@ -48,13 +48,18 @@
* previously registered callback must be replaced with this one.
* setCallback(null) should deregister the callback.
*/
- void setCallback(in IHdmiCallback callback);
+ void setCallback(in IHdmiConnectionCallback callback);
/**
* Method to set the HPD (Hot Plug Detection) signal the HAL should use for HPD signaling (e.g.
* signaling EDID updates). By default, the HAL will use {@code HDMI_HPD_PHYSICAL} (the physical
* hotplug signal). When set to {@code HDMI_HPD_STATUS_BIT} the HAL should use the HDP status
* bit.
+ * @throws ServiceSpecificException with error code set to
+ * {@code Result::FAILURE_NOT_SUPPORTED} if the signal type is not supported.
+ * {@code Result::FAILURE_INVALID_ARGS} if the signal type is invalid.
+ * {@code Result::FAILURE_UNKNOWN} if the signal type could not be set because of an
+ * unknown failure.
*/
void setHpdSignal(HpdSignal signal);
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmiCallback.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
similarity index 90%
rename from tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmiCallback.aidl
rename to tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
index 51275b0..8b001fb 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmiCallback.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
/**
* Callbacks from the HDMI HAL implementation to notify the system of new events.
*/
@VintfStability
-oneway interface IHdmiCallback {
+oneway interface IHdmiConnectionCallback {
/**
* The callback function that must be called by HAL implementation to notify
* the system of new hotplug event.
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/Result.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/Result.aidl
similarity index 96%
rename from tv/hdmi/aidl/android/hardware/tv/hdmi/Result.aidl
rename to tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/Result.aidl
index d2a1fef..edaa0a0 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/Result.aidl
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/Result.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.tv.hdmi;
+package android.hardware.tv.hdmi.connection;
/**
* Result enum for return values. Used by the HDMI related AIDL.
diff --git a/tv/earc/aidl/default/Android.bp b/tv/hdmi/connection/aidl/default/Android.bp
similarity index 73%
copy from tv/earc/aidl/default/Android.bp
copy to tv/hdmi/connection/aidl/default/Android.bp
index 399f029..5e7e330 100644
--- a/tv/earc/aidl/default/Android.bp
+++ b/tv/hdmi/connection/aidl/default/Android.bp
@@ -17,18 +17,18 @@
}
cc_binary {
- name: "android.hardware.tv.earc-service",
- vintf_fragments: ["android.hardware.tv.earc-service.xml"],
+ name: "android.hardware.tv.hdmi.connection-service",
+ vintf_fragments: ["android.hardware.tv.hdmi.connection-service.xml"],
relative_install_path: "hw",
vendor: true,
cflags: [
"-Wall",
"-Wextra",
],
- init_rc: ["android.hardware.tv.earc-service.rc"],
+ init_rc: ["android.hardware.tv.hdmi.connection-service.rc"],
srcs: [
"serviceMock.cpp",
- "EArcMock.cpp",
+ "HdmiConnectionMock.cpp",
],
shared_libs: [
"libbinder_ndk",
@@ -37,20 +37,20 @@
"libutils",
"libhardware",
"libhidlbase",
- "android.hardware.tv.earc-V1-ndk",
+ "android.hardware.tv.hdmi.connection-V1-ndk",
],
}
cc_fuzz {
- name: "android.hardware.tv.earc-service_fuzzer",
+ name: "android.hardware.tv.hdmi.connection-service_fuzzer",
defaults: ["service_fuzzer_defaults"],
static_libs: [
- "android.hardware.tv.earc-V1-ndk",
+ "android.hardware.tv.hdmi.connection-V1-ndk",
"liblog",
],
srcs: [
"fuzzer.cpp",
- "EArcMock.cpp",
+ "HdmiConnectionMock.cpp",
],
fuzz_config: {
componentid: 826094,
diff --git a/tv/hdmi/aidl/default/HdmiMock.cpp b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
similarity index 81%
rename from tv/hdmi/aidl/default/HdmiMock.cpp
rename to tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
index 7cd9bb7..db9f4c1 100644
--- a/tv/hdmi/aidl/default/HdmiMock.cpp
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-#define LOG_TAG "android.hardware.tv.hdmi"
+#define LOG_TAG "android.hardware.tv.hdmi.connection"
#include <android-base/logging.h>
#include <fcntl.h>
#include <utils/Log.h>
-#include "HdmiMock.h"
+#include "HdmiConnectionMock.h"
using ndk::ScopedAStatus;
@@ -27,20 +27,21 @@
namespace hardware {
namespace tv {
namespace hdmi {
+namespace connection {
namespace implementation {
-void HdmiMock::serviceDied(void* cookie) {
- ALOGE("HdmiMock died");
- auto hdmi = static_cast<HdmiMock*>(cookie);
+void HdmiConnectionMock::serviceDied(void* cookie) {
+ ALOGE("HdmiConnectionMock died");
+ auto hdmi = static_cast<HdmiConnectionMock*>(cookie);
hdmi->mHdmiThreadRun = false;
}
-ScopedAStatus HdmiMock::getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) {
+ScopedAStatus HdmiConnectionMock::getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) {
*_aidl_return = mPortInfos;
return ScopedAStatus::ok();
}
-ScopedAStatus HdmiMock::isConnected(int32_t portId, bool* _aidl_return) {
+ScopedAStatus HdmiConnectionMock::isConnected(int32_t portId, bool* _aidl_return) {
// Maintain port connection status and update on hotplug event
if (portId <= mTotalPorts && portId >= 1) {
*_aidl_return = mPortConnectionStatus[portId];
@@ -51,7 +52,8 @@
return ScopedAStatus::ok();
}
-ScopedAStatus HdmiMock::setCallback(const std::shared_ptr<IHdmiCallback>& callback) {
+ScopedAStatus HdmiConnectionMock::setCallback(
+ const std::shared_ptr<IHdmiConnectionCallback>& callback) {
if (mCallback != nullptr) {
mCallback = nullptr;
}
@@ -67,7 +69,7 @@
return ScopedAStatus::ok();
}
-ScopedAStatus HdmiMock::setHpdSignal(HpdSignal signal) {
+ScopedAStatus HdmiConnectionMock::setHpdSignal(HpdSignal signal) {
if (mHdmiThreadRun) {
mHpdSignal = signal;
return ScopedAStatus::ok();
@@ -77,18 +79,18 @@
}
}
-ScopedAStatus HdmiMock::getHpdSignal(HpdSignal* _aidl_return) {
+ScopedAStatus HdmiConnectionMock::getHpdSignal(HpdSignal* _aidl_return) {
*_aidl_return = mHpdSignal;
return ScopedAStatus::ok();
}
-void* HdmiMock::__threadLoop(void* user) {
- HdmiMock* const self = static_cast<HdmiMock*>(user);
+void* HdmiConnectionMock::__threadLoop(void* user) {
+ HdmiConnectionMock* const self = static_cast<HdmiConnectionMock*>(user);
self->threadLoop();
return 0;
}
-int HdmiMock::readMessageFromFifo(unsigned char* buf, int msgCount) {
+int HdmiConnectionMock::readMessageFromFifo(unsigned char* buf, int msgCount) {
if (msgCount <= 0 || !buf) {
return 0;
}
@@ -104,7 +106,7 @@
return ret;
}
-void HdmiMock::printEventBuf(const char* msg_buf, int len) {
+void HdmiConnectionMock::printEventBuf(const char* msg_buf, int len) {
int i, size = 0;
const int bufSize = MESSAGE_BODY_MAX_LENGTH * 3;
// Use 2 characters for each byte in the message plus 1 space
@@ -117,7 +119,7 @@
ALOGD("[halimp_aidl] %s, msg:%.*s", __FUNCTION__, size, buf);
}
-void HdmiMock::handleHotplugMessage(unsigned char* msgBuf) {
+void HdmiConnectionMock::handleHotplugMessage(unsigned char* msgBuf) {
bool connected = ((msgBuf[3]) & 0xf) > 0;
int32_t portId = static_cast<uint32_t>(msgBuf[0] & 0xf);
@@ -140,7 +142,7 @@
}
}
-void HdmiMock::threadLoop() {
+void HdmiConnectionMock::threadLoop() {
ALOGD("[halimp_aidl] threadLoop start.");
unsigned char msgBuf[MESSAGE_BODY_MAX_LENGTH];
int r = -1;
@@ -172,7 +174,7 @@
ALOGD("[halimp_aidl] thread end.");
}
-HdmiMock::HdmiMock() {
+HdmiConnectionMock::HdmiConnectionMock() {
ALOGE("[halimp_aidl] Opening a virtual HDMI HAL for testing and virtual machine.");
mCallback = nullptr;
mPortInfos.resize(mTotalPorts);
@@ -188,6 +190,7 @@
}
} // namespace implementation
+} // namespace connection
} // namespace hdmi
} // namespace tv
} // namespace hardware
diff --git a/tv/hdmi/aidl/default/HdmiMock.h b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
similarity index 69%
rename from tv/hdmi/aidl/default/HdmiMock.h
rename to tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
index 51abaff..b879e51 100644
--- a/tv/hdmi/aidl/default/HdmiMock.h
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#include <aidl/android/hardware/tv/hdmi/BnHdmi.h>
-#include <aidl/android/hardware/tv/hdmi/Result.h>
+#include <aidl/android/hardware/tv/hdmi/connection/BnHdmiConnection.h>
+#include <aidl/android/hardware/tv/hdmi/connection/Result.h>
#include <algorithm>
#include <vector>
@@ -25,25 +25,27 @@
namespace hardware {
namespace tv {
namespace hdmi {
+namespace connection {
namespace implementation {
-using ::aidl::android::hardware::tv::hdmi::BnHdmi;
-using ::aidl::android::hardware::tv::hdmi::HdmiPortInfo;
-using ::aidl::android::hardware::tv::hdmi::HdmiPortType;
-using ::aidl::android::hardware::tv::hdmi::HpdSignal;
-using ::aidl::android::hardware::tv::hdmi::IHdmi;
-using ::aidl::android::hardware::tv::hdmi::IHdmiCallback;
-using ::aidl::android::hardware::tv::hdmi::Result;
+using ::aidl::android::hardware::tv::hdmi::connection::BnHdmiConnection;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortInfo;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortType;
+using ::aidl::android::hardware::tv::hdmi::connection::HpdSignal;
+using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnection;
+using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnectionCallback;
+using ::aidl::android::hardware::tv::hdmi::connection::Result;
#define HDMI_MSG_IN_FIFO "/dev/hdmi_in_pipe"
#define MESSAGE_BODY_MAX_LENGTH 4
-struct HdmiMock : public BnHdmi {
- HdmiMock();
+struct HdmiConnectionMock : public BnHdmiConnection {
+ HdmiConnectionMock();
::ndk::ScopedAStatus getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) override;
::ndk::ScopedAStatus isConnected(int32_t portId, bool* _aidl_return) override;
- ::ndk::ScopedAStatus setCallback(const std::shared_ptr<IHdmiCallback>& callback) override;
+ ::ndk::ScopedAStatus setCallback(
+ const std::shared_ptr<IHdmiConnectionCallback>& callback) override;
::ndk::ScopedAStatus setHpdSignal(HpdSignal signal) override;
::ndk::ScopedAStatus getHpdSignal(HpdSignal* _aidl_return) override;
@@ -57,7 +59,7 @@
private:
static void serviceDied(void* cookie);
- std::shared_ptr<IHdmiCallback> mCallback;
+ std::shared_ptr<IHdmiConnectionCallback> mCallback;
// Variables for the virtual HDMI hal impl
std::vector<HdmiPortInfo> mPortInfos;
@@ -79,6 +81,7 @@
::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
};
} // namespace implementation
+} // namespace connection
} // namespace hdmi
} // Namespace tv
} // namespace hardware
diff --git a/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.rc b/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.rc
new file mode 100644
index 0000000..9e37e61
--- /dev/null
+++ b/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.rc
@@ -0,0 +1,5 @@
+service vendor.hdmi-default /vendor/bin/hw/android.hardware.tv.hdmi.connection-service
+ interface aidl android.hardware.tv.hdmi.connection.IHdmiConnection/default
+ class hal
+ user system
+ group system
diff --git a/tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.xml b/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.xml
similarity index 66%
rename from tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.xml
rename to tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.xml
index a03c199..144fef1 100644
--- a/tv/hdmi/aidl/default/android.hardware.tv.hdmi-service.xml
+++ b/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.xml
@@ -1,9 +1,9 @@
<manifest version="1.0" type="device">
<hal format="aidl">
- <name>android.hardware.tv.hdmi</name>
+ <name>android.hardware.tv.hdmi.connection</name>
<version>1</version>
<interface>
- <name>IHdmi</name>
+ <name>IHdmiConnection</name>
<instance>default</instance>
</interface>
</hal>
diff --git a/tv/hdmi/aidl/default/fuzzer.cpp b/tv/hdmi/connection/aidl/default/fuzzer.cpp
similarity index 83%
rename from tv/hdmi/aidl/default/fuzzer.cpp
rename to tv/hdmi/connection/aidl/default/fuzzer.cpp
index 06a2bc0..c5e33fa 100644
--- a/tv/hdmi/aidl/default/fuzzer.cpp
+++ b/tv/hdmi/connection/aidl/default/fuzzer.cpp
@@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include <HdmiMock.h>
+#include <HdmiConnectionMock.h>
#include <fuzzbinder/libbinder_ndk_driver.h>
#include <fuzzer/FuzzedDataProvider.h>
using android::fuzzService;
-using android::hardware::tv::hdmi::implementation::HdmiMock;
+using android::hardware::tv::hdmi::connection::implementation::HdmiConnectionMock;
using ndk::SharedRefBase;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- auto hdmiAidl = SharedRefBase::make<HdmiMock>();
+ auto hdmiAidl = SharedRefBase::make<HdmiConnectionMock>();
fuzzService(hdmiAidl->asBinder().get(), FuzzedDataProvider(data, size));
diff --git a/tv/hdmi/aidl/default/serviceMock.cpp b/tv/hdmi/connection/aidl/default/serviceMock.cpp
similarity index 74%
rename from tv/hdmi/aidl/default/serviceMock.cpp
rename to tv/hdmi/connection/aidl/default/serviceMock.cpp
index 1d8bf51..223c578 100644
--- a/tv/hdmi/aidl/default/serviceMock.cpp
+++ b/tv/hdmi/connection/aidl/default/serviceMock.cpp
@@ -14,23 +14,23 @@
* limitations under the License.
*/
-#define LOG_TAG "android.hardware.tv.hdmi-service-shim"
+#define LOG_TAG "android.hardware.tv.hdmi.connection-service-shim"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <hidl/HidlTransportSupport.h>
#include <utils/Log.h>
-#include "HdmiMock.h"
+#include "HdmiConnectionMock.h"
-using android::hardware::tv::hdmi::implementation::HdmiMock;
+using android::hardware::tv::hdmi::connection::implementation::HdmiConnectionMock;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(1);
ABinderProcess_startThreadPool();
- std::shared_ptr<HdmiMock> hdmiAidl = ndk::SharedRefBase::make<HdmiMock>();
- const std::string instance = std::string() + HdmiMock::descriptor + "/default";
+ std::shared_ptr<HdmiConnectionMock> hdmiAidl = ndk::SharedRefBase::make<HdmiConnectionMock>();
+ const std::string instance = std::string() + HdmiConnectionMock::descriptor + "/default";
binder_status_t status =
AServiceManager_addService(hdmiAidl->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
diff --git a/tv/earc/aidl/vts/functional/Android.bp b/tv/hdmi/connection/aidl/vts/functional/Android.bp
similarity index 85%
copy from tv/earc/aidl/vts/functional/Android.bp
copy to tv/hdmi/connection/aidl/vts/functional/Android.bp
index 797547e..fc8e2f7 100644
--- a/tv/earc/aidl/vts/functional/Android.bp
+++ b/tv/hdmi/connection/aidl/vts/functional/Android.bp
@@ -17,14 +17,14 @@
}
cc_test {
- name: "VtsHalTvEArcAidlTargetTest",
+ name: "VtsHalTvHdmiConnectionAidlTargetTest",
defaults: [
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
- srcs: ["VtsHalTvEArcAidlTargetTest.cpp"],
+ srcs: ["VtsHalTvHdmiConnectionAidlTargetTest.cpp"],
static_libs: [
- "android.hardware.tv.earc-V1-ndk",
+ "android.hardware.tv.hdmi.connection-V1-ndk",
],
shared_libs: [
"libbinder_ndk",
diff --git a/tv/hdmi/connection/aidl/vts/functional/VtsHalTvHdmiConnectionAidlTargetTest.cpp b/tv/hdmi/connection/aidl/vts/functional/VtsHalTvHdmiConnectionAidlTargetTest.cpp
new file mode 100644
index 0000000..69f7ef5
--- /dev/null
+++ b/tv/hdmi/connection/aidl/vts/functional/VtsHalTvHdmiConnectionAidlTargetTest.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Hdmi_Connection_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/tv/hdmi/connection/BnHdmiConnection.h>
+#include <aidl/android/hardware/tv/hdmi/connection/BnHdmiConnectionCallback.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gtest/gtest.h>
+#include <log/log.h>
+#include <sstream>
+#include <vector>
+
+using ::aidl::android::hardware::tv::hdmi::connection::BnHdmiConnectionCallback;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortInfo;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortType;
+using ::aidl::android::hardware::tv::hdmi::connection::HpdSignal;
+using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnection;
+using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnectionCallback;
+using ::ndk::SpAIBinder;
+
+#define INCORRECT_VENDOR_ID 0x00
+#define TV_PHYSICAL_ADDRESS 0x0000
+
+// The main test class for TV HDMI Connection HAL.
+class HdmiConnectionTest : public ::testing::TestWithParam<std::string> {
+ static void serviceDied(void* /* cookie */) {
+ ALOGE("VtsHalTvHdmiConnectionAidlTargetTest died");
+ }
+
+ public:
+ void SetUp() override {
+ hdmiConnection = IHdmiConnection::fromBinder(
+ SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+ ASSERT_NE(hdmiConnection, nullptr);
+ ALOGI("%s: getService() for hdmiConnection is %s", __func__,
+ hdmiConnection->isRemote() ? "remote" : "local");
+
+ hdmiConnectionCallback = ::ndk::SharedRefBase::make<HdmiConnectionCallback>();
+ ASSERT_NE(hdmiConnectionCallback, nullptr);
+ hdmiConnectionDeathRecipient =
+ ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(&serviceDied));
+ ASSERT_EQ(AIBinder_linkToDeath(hdmiConnection->asBinder().get(),
+ hdmiConnectionDeathRecipient.get(), 0),
+ STATUS_OK);
+ }
+
+ class HdmiConnectionCallback : public BnHdmiConnectionCallback {
+ public:
+ ::ndk::ScopedAStatus onHotplugEvent(bool connected __unused, int32_t portId __unused) {
+ return ::ndk::ScopedAStatus::ok();
+ };
+ };
+
+ std::shared_ptr<IHdmiConnection> hdmiConnection;
+ std::shared_ptr<IHdmiConnectionCallback> hdmiConnectionCallback;
+ ::ndk::ScopedAIBinder_DeathRecipient hdmiConnectionDeathRecipient;
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HdmiConnectionTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, HdmiConnectionTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IHdmiConnection::descriptor)),
+ android::PrintInstanceNameToString);
+
+TEST_P(HdmiConnectionTest, SetCallback) {
+ ASSERT_TRUE(hdmiConnection->setCallback(::ndk::SharedRefBase::make<HdmiConnectionCallback>())
+ .isOk());
+}
+
+TEST_P(HdmiConnectionTest, GetPortInfo) {
+ std::vector<HdmiPortInfo> ports;
+ ASSERT_TRUE(hdmiConnection->getPortInfo(&ports).isOk());
+
+ bool cecSupportedOnDevice = false;
+ for (size_t i = 0; i < ports.size(); ++i) {
+ EXPECT_TRUE((ports[i].type == HdmiPortType::OUTPUT) ||
+ (ports[i].type == HdmiPortType::INPUT));
+ if (ports[i].portId == 0) {
+ ALOGW("%s: Port id should start from 1", __func__);
+ }
+ cecSupportedOnDevice = cecSupportedOnDevice | ports[i].cecSupported;
+ }
+ EXPECT_NE(cecSupportedOnDevice, false) << "At least one port should support CEC";
+}
+
+TEST_P(HdmiConnectionTest, IsConnected) {
+ std::vector<HdmiPortInfo> ports;
+ ASSERT_TRUE(hdmiConnection->getPortInfo(&ports).isOk());
+ for (size_t i = 0; i < ports.size(); ++i) {
+ bool connected;
+ ASSERT_TRUE(hdmiConnection->isConnected(ports[i].portId, &connected).isOk());
+ }
+}
+
+TEST_P(HdmiConnectionTest, HdpSignal) {
+ HpdSignal originalSignal;
+ HpdSignal signal = HpdSignal::HDMI_HPD_STATUS_BIT;
+ HpdSignal readSignal;
+ ASSERT_TRUE(hdmiConnection->getHpdSignal(&originalSignal).isOk());
+ ASSERT_TRUE(hdmiConnection->setHpdSignal(signal).isOk());
+ ASSERT_TRUE(hdmiConnection->getHpdSignal(&readSignal).isOk());
+ EXPECT_EQ(readSignal, signal);
+ signal = HpdSignal::HDMI_HPD_PHYSICAL;
+ ASSERT_TRUE(hdmiConnection->setHpdSignal(signal).isOk());
+ ASSERT_TRUE(hdmiConnection->getHpdSignal(&readSignal).isOk());
+ EXPECT_EQ(readSignal, signal);
+ ASSERT_TRUE(hdmiConnection->setHpdSignal(originalSignal).isOk());
+}
diff --git a/tv/earc/aidl/Android.bp b/tv/hdmi/earc/aidl/Android.bp
similarity index 84%
copy from tv/earc/aidl/Android.bp
copy to tv/hdmi/earc/aidl/Android.bp
index 5db6032..d76cc1b 100644
--- a/tv/earc/aidl/Android.bp
+++ b/tv/hdmi/earc/aidl/Android.bp
@@ -17,9 +17,10 @@
}
aidl_interface {
- name: "android.hardware.tv.earc",
+ name: "android.hardware.tv.hdmi.earc",
vendor_available: true,
- srcs: ["android/hardware/tv/earc/*.aidl"],
+ srcs: ["android/hardware/tv/hdmi/earc/*.aidl"],
+ imports: ["android.hardware.tv.hdmi.connection-V1"],
stability: "vintf",
backend: {
java: {
diff --git a/tv/earc/aidl/OWNERS b/tv/hdmi/earc/aidl/OWNERS
similarity index 100%
rename from tv/earc/aidl/OWNERS
rename to tv/hdmi/earc/aidl/OWNERS
diff --git a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArc.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArc.aidl
similarity index 90%
rename from tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArc.aidl
rename to tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArc.aidl
index 552bb46..1ea7df7 100644
--- a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArc.aidl
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArc.aidl
@@ -31,12 +31,12 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
@VintfStability
interface IEArc {
void setEArcEnabled(in boolean enabled);
boolean isEArcEnabled();
- void setCallback(in android.hardware.tv.earc.IEArcCallback callback);
- android.hardware.tv.earc.IEArcStatus getState(in int portId);
+ void setCallback(in android.hardware.tv.hdmi.earc.IEArcCallback callback);
+ android.hardware.tv.hdmi.earc.IEArcStatus getState(in int portId);
byte[] getLastReportedAudioCapabilities(in int portId);
}
diff --git a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcCallback.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
similarity index 92%
rename from tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcCallback.aidl
rename to tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
index ef99824..1730dcf 100644
--- a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcCallback.aidl
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
@@ -31,9 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
@VintfStability
interface IEArcCallback {
- oneway void onStateChange(in android.hardware.tv.earc.IEArcStatus status, in int portId);
+ oneway void onStateChange(in android.hardware.tv.hdmi.earc.IEArcStatus status, in int portId);
oneway void onCapabilitiesReported(in byte[] rawCapabilities, in int portId);
}
diff --git a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcStatus.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
similarity index 97%
rename from tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcStatus.aidl
rename to tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
index 729c657..29d4ea9 100644
--- a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/IEArcStatus.aidl
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
@@ -31,7 +31,7 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
@Backing(type="byte") @VintfStability
enum IEArcStatus {
STATUS_IDLE = 0,
diff --git a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/Result.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/Result.aidl
similarity index 97%
rename from tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/Result.aidl
rename to tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/Result.aidl
index 3679d3b..b248f41 100644
--- a/tv/earc/aidl/aidl_api/android.hardware.tv.earc/current/android/hardware/tv/earc/Result.aidl
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/Result.aidl
@@ -31,7 +31,7 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
@VintfStability
enum Result {
SUCCESS = 0,
diff --git a/tv/earc/aidl/android/hardware/tv/earc/IEArc.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArc.aidl
similarity index 75%
rename from tv/earc/aidl/android/hardware/tv/earc/IEArc.aidl
rename to tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArc.aidl
index bb8dabf..a2dde6a 100644
--- a/tv/earc/aidl/android/hardware/tv/earc/IEArc.aidl
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArc.aidl
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
-import android.hardware.tv.earc.IEArcCallback;
-import android.hardware.tv.earc.IEArcStatus;
+import android.hardware.tv.hdmi.earc.IEArcCallback;
+import android.hardware.tv.hdmi.earc.IEArcStatus;
/**
* eARC HAL interface definition
@@ -30,11 +30,13 @@
* updates with IEArcCallback callbacks. If disabled, the driver and HAL shall not attempt to
* establish an eARC connection and shall not send any IEArcCallback callbacks to the Android
* framework.
- * The error status is set to
- * {@code SUCCESS} if the setting could be changed to the value passed.
- * {@code FAILURE_NOT_SUPPORTED} if the setting is not supported.
- * {@code FAILURE_INVALID_ARGS} if the setting value is invalid.
- * {@code FAILURE_UNKNOWN} if there was an unknown failure.
+ * @throws ServiceSpecificException with error code set to
+ * {@code Result::FAILURE_NOT_SUPPORTED} if the eARC enabled setting could not be set
+ * because this is not supported.
+ * {@code Result::FAILURE_INVALID_ARGS} if the eARC enabled setting could not be set
+ * because the method argument is invalid.
+ * {@code Result::FAILURE_UNKNOWN} if the eARC enabled setting could not be set because
+ * there was an unknown failure.
*/
void setEArcEnabled(in boolean enabled);
diff --git a/tv/earc/aidl/android/hardware/tv/earc/IEArcCallback.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
similarity index 95%
rename from tv/earc/aidl/android/hardware/tv/earc/IEArcCallback.aidl
rename to tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
index c70191f..a11924b 100644
--- a/tv/earc/aidl/android/hardware/tv/earc/IEArcCallback.aidl
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
-import android.hardware.tv.earc.IEArcStatus;
+import android.hardware.tv.hdmi.earc.IEArcStatus;
/**
* eARC HAL callback methods
diff --git a/tv/earc/aidl/android/hardware/tv/earc/IEArcStatus.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
similarity index 95%
rename from tv/earc/aidl/android/hardware/tv/earc/IEArcStatus.aidl
rename to tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
index ecb1c85..de1aaf1 100644
--- a/tv/earc/aidl/android/hardware/tv/earc/IEArcStatus.aidl
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
/**
* eARC HAL connection states
diff --git a/tv/earc/aidl/android/hardware/tv/earc/Result.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/Result.aidl
similarity index 96%
rename from tv/earc/aidl/android/hardware/tv/earc/Result.aidl
rename to tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/Result.aidl
index 054518a..268610d 100644
--- a/tv/earc/aidl/android/hardware/tv/earc/Result.aidl
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/Result.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.tv.earc;
+package android.hardware.tv.hdmi.earc;
/**
* Result enum for return values. Used by the HDMI related AIDL.
diff --git a/tv/earc/aidl/default/Android.bp b/tv/hdmi/earc/aidl/default/Android.bp
similarity index 79%
rename from tv/earc/aidl/default/Android.bp
rename to tv/hdmi/earc/aidl/default/Android.bp
index 399f029..5d56c2a 100644
--- a/tv/earc/aidl/default/Android.bp
+++ b/tv/hdmi/earc/aidl/default/Android.bp
@@ -17,15 +17,15 @@
}
cc_binary {
- name: "android.hardware.tv.earc-service",
- vintf_fragments: ["android.hardware.tv.earc-service.xml"],
+ name: "android.hardware.tv.hdmi.earc-service",
+ vintf_fragments: ["android.hardware.tv.hdmi.earc-service.xml"],
relative_install_path: "hw",
vendor: true,
cflags: [
"-Wall",
"-Wextra",
],
- init_rc: ["android.hardware.tv.earc-service.rc"],
+ init_rc: ["android.hardware.tv.hdmi.earc-service.rc"],
srcs: [
"serviceMock.cpp",
"EArcMock.cpp",
@@ -37,15 +37,15 @@
"libutils",
"libhardware",
"libhidlbase",
- "android.hardware.tv.earc-V1-ndk",
+ "android.hardware.tv.hdmi.earc-V1-ndk",
],
}
cc_fuzz {
- name: "android.hardware.tv.earc-service_fuzzer",
+ name: "android.hardware.tv.hdmi.earc-service_fuzzer",
defaults: ["service_fuzzer_defaults"],
static_libs: [
- "android.hardware.tv.earc-V1-ndk",
+ "android.hardware.tv.hdmi.earc-V1-ndk",
"liblog",
],
srcs: [
diff --git a/tv/earc/aidl/default/EArcMock.cpp b/tv/hdmi/earc/aidl/default/EArcMock.cpp
similarity index 97%
rename from tv/earc/aidl/default/EArcMock.cpp
rename to tv/hdmi/earc/aidl/default/EArcMock.cpp
index 9bccc18..3578999 100644
--- a/tv/earc/aidl/default/EArcMock.cpp
+++ b/tv/hdmi/earc/aidl/default/EArcMock.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "android.hardware.tv.earc"
+#define LOG_TAG "android.hardware.tv.hdmi.earc"
#include <android-base/logging.h>
#include <fcntl.h>
#include <utils/Log.h>
@@ -26,6 +26,7 @@
namespace android {
namespace hardware {
namespace tv {
+namespace hdmi {
namespace earc {
namespace implementation {
@@ -114,6 +115,7 @@
} // namespace implementation
} // namespace earc
+} // namespace hdmi
} // namespace tv
} // namespace hardware
} // namespace android
diff --git a/tv/earc/aidl/default/EArcMock.h b/tv/hdmi/earc/aidl/default/EArcMock.h
similarity index 82%
rename from tv/earc/aidl/default/EArcMock.h
rename to tv/hdmi/earc/aidl/default/EArcMock.h
index 9081950..fc4c828 100644
--- a/tv/earc/aidl/default/EArcMock.h
+++ b/tv/hdmi/earc/aidl/default/EArcMock.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#include <aidl/android/hardware/tv/earc/BnEArc.h>
-#include <aidl/android/hardware/tv/earc/Result.h>
+#include <aidl/android/hardware/tv/hdmi/earc/BnEArc.h>
+#include <aidl/android/hardware/tv/hdmi/earc/Result.h>
#include <algorithm>
#include <vector>
@@ -24,14 +24,15 @@
namespace android {
namespace hardware {
namespace tv {
+namespace hdmi {
namespace earc {
namespace implementation {
-using ::aidl::android::hardware::tv::earc::BnEArc;
-using ::aidl::android::hardware::tv::earc::IEArc;
-using ::aidl::android::hardware::tv::earc::IEArcCallback;
-using ::aidl::android::hardware::tv::earc::IEArcStatus;
-using ::aidl::android::hardware::tv::earc::Result;
+using ::aidl::android::hardware::tv::hdmi::earc::BnEArc;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArc;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcCallback;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcStatus;
+using ::aidl::android::hardware::tv::hdmi::earc::Result;
struct EArcMock : public BnEArc {
EArcMock();
@@ -69,6 +70,7 @@
};
} // namespace implementation
} // namespace earc
+} // Namespace hdmi
} // Namespace tv
} // namespace hardware
} // namespace android
diff --git a/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.rc b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.rc
new file mode 100644
index 0000000..53bec04
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.rc
@@ -0,0 +1,5 @@
+service vendor.earc-default /vendor/bin/hw/android.hardware.tv.hdmi.earc-service
+ interface aidl android.hardware.tv.hdmi.earc.IEArc/default
+ class hal
+ user system
+ group system
diff --git a/tv/earc/aidl/default/android.hardware.tv.earc-service.xml b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.xml
similarity index 81%
rename from tv/earc/aidl/default/android.hardware.tv.earc-service.xml
rename to tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.xml
index 4d66d98..6f8d03d 100644
--- a/tv/earc/aidl/default/android.hardware.tv.earc-service.xml
+++ b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.xml
@@ -1,6 +1,6 @@
<manifest version="1.0" type="device">
<hal format="aidl">
- <name>android.hardware.tv.earc</name>
+ <name>android.hardware.tv.hdmi.earc</name>
<version>1</version>
<interface>
<name>IEArc</name>
diff --git a/tv/earc/aidl/default/fuzzer.cpp b/tv/hdmi/earc/aidl/default/fuzzer.cpp
similarity index 93%
rename from tv/earc/aidl/default/fuzzer.cpp
rename to tv/hdmi/earc/aidl/default/fuzzer.cpp
index 5036853..25264ae 100644
--- a/tv/earc/aidl/default/fuzzer.cpp
+++ b/tv/hdmi/earc/aidl/default/fuzzer.cpp
@@ -18,7 +18,7 @@
#include <fuzzer/FuzzedDataProvider.h>
using android::fuzzService;
-using android::hardware::tv::earc::implementation::EArcMock;
+using android::hardware::tv::hdmi::earc::implementation::EArcMock;
using ndk::SharedRefBase;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
diff --git a/tv/earc/aidl/default/serviceMock.cpp b/tv/hdmi/earc/aidl/default/serviceMock.cpp
similarity index 90%
rename from tv/earc/aidl/default/serviceMock.cpp
rename to tv/hdmi/earc/aidl/default/serviceMock.cpp
index 1ea7262..0878e76 100644
--- a/tv/earc/aidl/default/serviceMock.cpp
+++ b/tv/hdmi/earc/aidl/default/serviceMock.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "android.hardware.tv.earc-service-shim"
+#define LOG_TAG "android.hardware.tv.hdmi.earc-service-shim"
#include <android-base/logging.h>
#include <android/binder_manager.h>
@@ -23,7 +23,7 @@
#include <utils/Log.h>
#include "EArcMock.h"
-using android::hardware::tv::earc::implementation::EArcMock;
+using android::hardware::tv::hdmi::earc::implementation::EArcMock;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(1);
diff --git a/tv/earc/aidl/vts/functional/Android.bp b/tv/hdmi/earc/aidl/vts/functional/Android.bp
similarity index 87%
rename from tv/earc/aidl/vts/functional/Android.bp
rename to tv/hdmi/earc/aidl/vts/functional/Android.bp
index 797547e..36fbf56 100644
--- a/tv/earc/aidl/vts/functional/Android.bp
+++ b/tv/hdmi/earc/aidl/vts/functional/Android.bp
@@ -17,14 +17,14 @@
}
cc_test {
- name: "VtsHalTvEArcAidlTargetTest",
+ name: "VtsHalTvHdmiEArcAidlTargetTest",
defaults: [
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
- srcs: ["VtsHalTvEArcAidlTargetTest.cpp"],
+ srcs: ["VtsHalTvHdmiEArcAidlTargetTest.cpp"],
static_libs: [
- "android.hardware.tv.earc-V1-ndk",
+ "android.hardware.tv.hdmi.earc-V1-ndk",
],
shared_libs: [
"libbinder_ndk",
diff --git a/tv/earc/aidl/vts/functional/VtsHalTvEArcAidlTargetTest.cpp b/tv/hdmi/earc/aidl/vts/functional/VtsHalTvHdmiEArcAidlTargetTest.cpp
similarity index 88%
rename from tv/earc/aidl/vts/functional/VtsHalTvEArcAidlTargetTest.cpp
rename to tv/hdmi/earc/aidl/vts/functional/VtsHalTvHdmiEArcAidlTargetTest.cpp
index 12f48c3..3cd8577 100644
--- a/tv/earc/aidl/vts/functional/VtsHalTvEArcAidlTargetTest.cpp
+++ b/tv/hdmi/earc/aidl/vts/functional/VtsHalTvHdmiEArcAidlTargetTest.cpp
@@ -18,9 +18,9 @@
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
-#include <aidl/android/hardware/tv/earc/BnEArcCallback.h>
-#include <aidl/android/hardware/tv/earc/IEArc.h>
-#include <aidl/android/hardware/tv/earc/IEArcStatus.h>
+#include <aidl/android/hardware/tv/hdmi/earc/BnEArcCallback.h>
+#include <aidl/android/hardware/tv/hdmi/earc/IEArc.h>
+#include <aidl/android/hardware/tv/hdmi/earc/IEArcStatus.h>
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
@@ -29,10 +29,10 @@
#include <sstream>
#include <vector>
-using ::aidl::android::hardware::tv::earc::BnEArcCallback;
-using ::aidl::android::hardware::tv::earc::IEArc;
-using ::aidl::android::hardware::tv::earc::IEArcCallback;
-using ::aidl::android::hardware::tv::earc::IEArcStatus;
+using ::aidl::android::hardware::tv::hdmi::earc::BnEArcCallback;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArc;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcCallback;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcStatus;
using ::ndk::SpAIBinder;
// The main test class for TV EARC HAL.