Merge "Update doc for subscribing unavailable props."
diff --git a/audio/aidl/TEST_MAPPING b/audio/aidl/TEST_MAPPING
index cafbf59..2e84d95 100644
--- a/audio/aidl/TEST_MAPPING
+++ b/audio/aidl/TEST_MAPPING
@@ -28,6 +28,9 @@
"name": "VtsHalVisualizerTargetTest"
},
{
+ "name": "VtsHalVolumeTargetTest"
+ },
+ {
"name": "VtsHalAECTargetTest"
},
{
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl
index 9ee19f0..25f0b73 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl
@@ -38,7 +38,7 @@
android.hardware.audio.effect.VendorExtension vendor;
android.hardware.audio.effect.Visualizer.GetOnlyParameters getOnlyParameters;
android.hardware.audio.effect.Visualizer.SetOnlyParameters setOnlyParameters;
- int captureSizeBytes;
+ int captureSamples;
android.hardware.audio.effect.Visualizer.ScalingMode scalingMode;
android.hardware.audio.effect.Visualizer.MeasurementMode measurementMode;
@VintfStability
@@ -52,12 +52,12 @@
parcelable Capability {
android.hardware.audio.effect.VendorExtension extension;
int maxLatencyMs;
- android.hardware.audio.effect.Visualizer.CaptureSizeRange captureSizeRange;
+ android.hardware.audio.effect.Visualizer.CaptureSamplesRange captureSampleRange;
}
@VintfStability
- parcelable CaptureSizeRange {
- int minBytes;
- int maxBytes;
+ parcelable CaptureSamplesRange {
+ int min;
+ int max;
}
@VintfStability
enum ScalingMode {
@@ -72,7 +72,7 @@
@VintfStability
union GetOnlyParameters {
android.hardware.audio.effect.Visualizer.GetOnlyParameters.Measurement measurement;
- byte[] captureBytes;
+ byte[] captureSampleBuffer;
@VintfStability
parcelable Measurement {
int rms;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl
index 8c836b0..ccd32e8 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl
@@ -37,6 +37,9 @@
android.hardware.audio.effect.VendorExtension vendor;
int levelDb;
boolean mute;
+ // TODO(b/263416041) Move to Capability
+ const int MIN_LEVEL_DB = -9600;
+ const int MAX_LEVEL_DB = 0;
@VintfStability
union Id {
int vendorExtensionTag;
diff --git a/audio/aidl/android/hardware/audio/effect/IEffect.aidl b/audio/aidl/android/hardware/audio/effect/IEffect.aidl
index 3b957d7..6097f34 100644
--- a/audio/aidl/android/hardware/audio/effect/IEffect.aidl
+++ b/audio/aidl/android/hardware/audio/effect/IEffect.aidl
@@ -34,12 +34,10 @@
/**
* One of Binder STATUS_* statuses:
* - STATUS_OK: the command has completed successfully;
- * - STATUS_BAD_VALUE: invalid value in the 'Command' structure;
- * - STATUS_INVALID_OPERATION: the mix port is not connected
- * to any producer or consumer, thus
- * positions can not be reported;
- * - STATUS_NOT_ENOUGH_DATA: a read or write error has
- * occurred for the 'audio.fmq' queue;
+ * - STATUS_BAD_VALUE: invalid parameters or state detected in effects;
+ * - STATUS_INVALID_OPERATION: an internal error happens in effect audio buffer processing;
+ * - STATUS_NOT_ENOUGH_DATA: a read or write error has occurred for the 'inputDataMQ' or
+ * 'outputDataMQ';
*
*/
int status;
diff --git a/audio/aidl/android/hardware/audio/effect/Visualizer.aidl b/audio/aidl/android/hardware/audio/effect/Visualizer.aidl
index 4c1b71a..dfe29c8 100644
--- a/audio/aidl/android/hardware/audio/effect/Visualizer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Visualizer.aidl
@@ -63,16 +63,16 @@
/**
* Capture size range.
*/
- CaptureSizeRange captureSizeRange;
+ CaptureSamplesRange captureSampleRange;
}
/**
- * Supported capture size range in bytes.
+ * Supported capture size range in samples.
*/
@VintfStability
- parcelable CaptureSizeRange {
- int minBytes;
- int maxBytes;
+ parcelable CaptureSamplesRange {
+ int min;
+ int max;
}
/**
@@ -131,9 +131,9 @@
Measurement measurement;
/**
- * Gets the latest PCM capture, size of returned vector equals to @c captureSize.
+ * Get the latest captureSamples of PCM samples (8 bits per sample).
*/
- byte[] captureBytes;
+ byte[] captureSampleBuffer;
}
GetOnlyParameters getOnlyParameters;
@@ -152,10 +152,10 @@
SetOnlyParameters setOnlyParameters;
/**
- * Current capture size in bytes. The capture size must be a power of 2 in the range
+ * Current capture size in number of samples. The capture size must be inside
* Capability.captureSizeRange.
*/
- int captureSizeBytes;
+ int captureSamples;
/**
* Visualizer capture mode
*/
diff --git a/audio/aidl/android/hardware/audio/effect/Volume.aidl b/audio/aidl/android/hardware/audio/effect/Volume.aidl
index a3ce2f6..a9f8371 100644
--- a/audio/aidl/android/hardware/audio/effect/Volume.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Volume.aidl
@@ -57,6 +57,18 @@
int maxLevel;
}
+ // TODO(b/263416041) Move to Capability
+ /**
+ * Minimal level in dB.
+ */
+ const int MIN_LEVEL_DB = -9600;
+
+ /**
+ * Maximum level in dB.
+ */
+ const int MAX_LEVEL_DB = 0;
+
+ /**
/**
* Current level in dB.
*/
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
index 990cff9..8f0c986 100644
--- a/audio/aidl/common/include/Utils.h
+++ b/audio/aidl/common/include/Utils.h
@@ -48,7 +48,8 @@
}
constexpr size_t getChannelCount(
- const ::aidl::android::media::audio::common::AudioChannelLayout& layout) {
+ const ::aidl::android::media::audio::common::AudioChannelLayout& layout,
+ int32_t mask = std::numeric_limits<int32_t>::max()) {
using Tag = ::aidl::android::media::audio::common::AudioChannelLayout::Tag;
switch (layout.getTag()) {
case Tag::none:
@@ -56,11 +57,11 @@
case Tag::invalid:
return 0;
case Tag::indexMask:
- return __builtin_popcount(layout.get<Tag::indexMask>());
+ return __builtin_popcount(layout.get<Tag::indexMask>() & mask);
case Tag::layoutMask:
- return __builtin_popcount(layout.get<Tag::layoutMask>());
+ return __builtin_popcount(layout.get<Tag::layoutMask>() & mask);
case Tag::voiceMask:
- return __builtin_popcount(layout.get<Tag::voiceMask>());
+ return __builtin_popcount(layout.get<Tag::voiceMask>() & mask);
}
return 0;
}
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index a938551..8f0b4bd 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -155,12 +155,12 @@
"libdynamicsprocessingsw",
"libenvreverbsw",
"libequalizersw",
- "libhapticgeneratorsw",
+ "libhapticgeneratoraidl",
"libloudnessenhanceraidl",
"libpresetreverbsw",
"libtinyxml2",
"libvirtualizersw",
- "libvisualizersw",
+ "libvisualizeraidl",
"libvolumesw",
],
srcs: [
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 139f262..b24ca63 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -21,6 +21,7 @@
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::PcmType;
extern "C" binder_exception_t destroyEffect(const std::shared_ptr<IEffect>& instanceSp) {
State state;
@@ -40,6 +41,10 @@
const std::optional<Parameter::Specific>& specific,
OpenEffectReturn* ret) {
LOG(DEBUG) << __func__;
+ // effect only support 32bits float
+ RETURN_IF(common.input.base.format.pcm != common.output.base.format.pcm ||
+ common.input.base.format.pcm != PcmType::FLOAT_32_BIT,
+ EX_ILLEGAL_ARGUMENT, "dataMustBe32BitsFloat");
RETURN_OK_IF(mState != State::INIT);
auto context = createContext(common);
RETURN_IF(!context, EX_NULL_POINTER, "createContextFailed");
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index a958eaf..9670e9c 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -35,13 +35,13 @@
<library name="downmix" path="libdownmixaidl.so"/>
<library name="dynamics_processingsw" path="libdynamicsprocessingsw.so"/>
<library name="equalizersw" path="libequalizersw.so"/>
- <library name="haptic_generatorsw" path="libhapticgeneratorsw.so"/>
+ <library name="haptic_generator" path="libhapticgeneratoraidl.so"/>
<library name="loudness_enhancer" path="libloudnessenhanceraidl.so"/>
<library name="nssw" path="libnssw.so"/>
<library name="env_reverbsw" path="libenvreverbsw.so"/>
<library name="preset_reverbsw" path="libpresetreverbsw.so"/>
<library name="virtualizersw" path="libvirtualizersw.so"/>
- <library name="visualizersw" path="libvisualizersw.so"/>
+ <library name="visualizer" path="libvisualizeraidl.so"/>
<library name="volumesw" path="libvolumesw.so"/>
</libraries>
@@ -73,7 +73,7 @@
</effectProxy>
<effect name="downmix" library="downmix" uuid="93f04452-e4fe-41cc-91f9-e475b6d1d69f"/>
<effect name="dynamics_processing" library="dynamics_processingsw" uuid="fa818d78-588b-11ed-9b6a-0242ac120002"/>
- <effect name="haptic_generator" library="haptic_generatorsw" uuid="fa819110-588b-11ed-9b6a-0242ac120002"/>
+ <effect name="haptic_generator" library="haptic_generator" uuid="97c4acd1-8b82-4f2f-832e-c2fe5d7a9931"/>
<effect name="loudness_enhancer" library="loudness_enhancer" uuid="fa415329-2034-4bea-b5dc-5b381c8d1e2c"/>
<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"/>
@@ -82,8 +82,8 @@
<libsw library="virtualizersw" uuid="fa819d86-588b-11ed-9b6a-0242ac120002"/>
<libsw library="bundle" uuid="1d4033c0-8557-11df-9f2d-0002a5d5c51b"/>
</effectProxy>
- <effect name="visualizer" library="visualizersw" uuid="fa81a0f6-588b-11ed-9b6a-0242ac120002"/>
- <effect name="volume" library="volumesw" uuid="fa81a718-588b-11ed-9b6a-0242ac120002"/>
+ <effect name="visualizer" library="visualizer" uuid="d069d9e0-8329-11df-9168-0002a5d5c51b"/>
+ <effect name="volume" library="bundle" uuid="119341a0-8469-11df-81f9-0002a5d5c51b"/>
<effectProxy name="equalizer" uuid="c8e70ecd-48ca-456e-8a4f-0002a5d5c51b">
<libsw library="equalizersw" uuid="0bed4300-847d-11df-bb17-0002a5d5c51b"/>
<libsw library="bundle" uuid="ce772f20-847d-11df-bb17-0002a5d5c51b"/>
diff --git a/audio/aidl/default/include/effect-impl/EffectUUID.h b/audio/aidl/default/include/effect-impl/EffectUUID.h
index 951007d..6eec29e 100644
--- a/audio/aidl/default/include/effect-impl/EffectUUID.h
+++ b/audio/aidl/default/include/effect-impl/EffectUUID.h
@@ -147,6 +147,12 @@
0x11ed,
0x9b6a,
{0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// 97c4acd1-8b82-4f2f-832e-c2fe5d7a9931
+static const AudioUuid kHapticGeneratorImplUUID = {static_cast<int32_t>(0x97c4acd1),
+ 0x8b82,
+ 0x4f2f,
+ 0x832e,
+ {0xc2, 0xfe, 0x5d, 0x7a, 0x99, 0x31}};
// fe3199be-aed0-413f-87bb-11260eb63cf1
static const AudioUuid kLoudnessEnhancerTypeUUID = {static_cast<int32_t>(0xfe3199be),
0xaed0,
@@ -237,6 +243,13 @@
0x11ed,
0x9b6a,
{0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// d069d9e0-8329-11df-9168-0002a5d5c51b
+// {0xd069d9e0, 0x8329, 0x11df, 0x9168, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
+static const AudioUuid kVisualizerImplUUID = {static_cast<int32_t>(0xd069d9e0),
+ 0x8329,
+ 0x11df,
+ 0x9168,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
// fa81a2b8-588b-11ed-9b6a-0242ac120002
static const AudioUuid kVolumeTypeUUID = {static_cast<int32_t>(0xfa81a2b8),
0x588b,
@@ -249,6 +262,12 @@
0x11ed,
0x9b6a,
{0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// 119341a0-8469-11df-81f9-0002a5d5c51b
+static const AudioUuid kVolumeBundleImplUUID = {static_cast<int32_t>(0x119341a0),
+ 0x8469,
+ 0x11df,
+ 0x81f9,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
/**
* @brief A map between effect name and effect type UUID.
diff --git a/audio/aidl/default/visualizer/VisualizerSw.cpp b/audio/aidl/default/visualizer/VisualizerSw.cpp
index 37eb30b..735180e 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.cpp
+++ b/audio/aidl/default/visualizer/VisualizerSw.cpp
@@ -56,9 +56,12 @@
const std::string VisualizerSw::kEffectName = "VisualizerSw";
/* capabilities */
-const Visualizer::CaptureSizeRange mCaptureSizeRange = {MIN_CAPTURE_SIZE, MAX_CAPTURE_SIZE};
-const Visualizer::Capability VisualizerSw::kCapability = {.maxLatencyMs = MAX_LATENCY,
- .captureSizeRange = mCaptureSizeRange};
+const Visualizer::CaptureSamplesRange VisualizerSwContext::kCaptureSamplesRange = {
+ VisualizerSwContext::kMinCaptureSize, VisualizerSwContext::kMaxCaptureSize};
+const Visualizer::Capability VisualizerSw::kCapability = {
+ .maxLatencyMs = VisualizerSwContext::kMaxLatencyMs,
+ .captureSampleRange = VisualizerSwContext::kCaptureSamplesRange};
+
const Descriptor VisualizerSw::kDescriptor = {
.common = {.id = {.type = kVisualizerTypeUUID,
.uuid = kVisualizerSwImplUUID,
@@ -84,8 +87,8 @@
auto tag = vsParam.getTag();
switch (tag) {
- case Visualizer::captureSizeBytes: {
- RETURN_IF(mContext->setVsCaptureSize(vsParam.get<Visualizer::captureSizeBytes>()) !=
+ case Visualizer::captureSamples: {
+ RETURN_IF(mContext->setVsCaptureSize(vsParam.get<Visualizer::captureSamples>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "captureSizeNotSupported");
return ndk::ScopedAStatus::ok();
@@ -159,8 +162,8 @@
Visualizer vsParam;
switch (tag) {
- case Visualizer::captureSizeBytes: {
- vsParam.set<Visualizer::captureSizeBytes>(mContext->getVsCaptureSize());
+ case Visualizer::captureSamples: {
+ vsParam.set<Visualizer::captureSamples>(mContext->getVsCaptureSize());
break;
}
case Visualizer::scalingMode: {
@@ -190,9 +193,9 @@
mContext->getVsMeasurement());
break;
}
- case Visualizer::GetOnlyParameters::captureBytes: {
- getOnlyParam.set<Visualizer::GetOnlyParameters::captureBytes>(
- mContext->getVsCaptureBytes());
+ case Visualizer::GetOnlyParameters::captureSampleBuffer: {
+ getOnlyParam.set<Visualizer::GetOnlyParameters::captureSampleBuffer>(
+ mContext->getVsCaptureSampleBuffer());
break;
}
default: {
diff --git a/audio/aidl/default/visualizer/VisualizerSw.h b/audio/aidl/default/visualizer/VisualizerSw.h
index a95537c..edaf123 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.h
+++ b/audio/aidl/default/visualizer/VisualizerSw.h
@@ -22,24 +22,24 @@
#include "effect-impl/EffectImpl.h"
#include "effect-impl/EffectUUID.h"
-#define MIN_CAPTURE_SIZE 128
-#define MAX_CAPTURE_SIZE 1024
-#define MAX_LATENCY 3000
-#define CAPTURE_BUF_SIZE 65536
-
namespace aidl::android::hardware::audio::effect {
class VisualizerSwContext final : public EffectContext {
public:
+ static const int kMinCaptureSize = 0x80;
+ static const int kMaxCaptureSize = 0x400;
+ static const int kMaxLatencyMs = 3000;
+ static const int kMaxCaptureBufSize = 0xffff;
+ static const Visualizer::CaptureSamplesRange kCaptureSamplesRange;
VisualizerSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
- mCaptureBytes.resize(CAPTURE_BUF_SIZE);
- fill(mCaptureBytes.begin(), mCaptureBytes.end(), 0x80);
+ mCaptureSampleBuffer.resize(kMaxCaptureBufSize);
+ fill(mCaptureSampleBuffer.begin(), mCaptureSampleBuffer.end(), 0x80);
}
RetCode setVsCaptureSize(int captureSize) {
- if (captureSize < MIN_CAPTURE_SIZE || captureSize > MAX_CAPTURE_SIZE) {
+ if (captureSize < kMinCaptureSize || captureSize > kMaxCaptureSize) {
LOG(ERROR) << __func__ << " invalid captureSize " << captureSize;
return RetCode::ERROR_ILLEGAL_PARAMETER;
}
@@ -64,7 +64,7 @@
Visualizer::MeasurementMode getVsMeasurementMode() const { return mMeasurementMode; }
RetCode setVsLatency(int latency) {
- if (latency < 0 || latency > MAX_LATENCY) {
+ if (latency < 0 || latency > kMaxLatencyMs) {
LOG(ERROR) << __func__ << " invalid latency " << latency;
return RetCode::ERROR_ILLEGAL_PARAMETER;
}
@@ -74,15 +74,15 @@
}
Visualizer::GetOnlyParameters::Measurement getVsMeasurement() const { return mMeasurement; }
- std::vector<uint8_t> getVsCaptureBytes() const { return mCaptureBytes; }
+ std::vector<uint8_t> getVsCaptureSampleBuffer() const { return mCaptureSampleBuffer; }
private:
- int mCaptureSize = MAX_CAPTURE_SIZE;
+ int mCaptureSize = kMaxCaptureSize;
Visualizer::ScalingMode mScalingMode = Visualizer::ScalingMode::NORMALIZED;
Visualizer::MeasurementMode mMeasurementMode = Visualizer::MeasurementMode::NONE;
int mLatency;
const Visualizer::GetOnlyParameters::Measurement mMeasurement = {0, 0};
- std::vector<uint8_t> mCaptureBytes;
+ std::vector<uint8_t> mCaptureSampleBuffer;
};
class VisualizerSw final : public EffectImpl {
diff --git a/audio/aidl/default/volume/VolumeSw.cpp b/audio/aidl/default/volume/VolumeSw.cpp
index 6fce16e..24e1e1d 100644
--- a/audio/aidl/default/volume/VolumeSw.cpp
+++ b/audio/aidl/default/volume/VolumeSw.cpp
@@ -60,7 +60,7 @@
namespace aidl::android::hardware::audio::effect {
const std::string VolumeSw::kEffectName = "VolumeSw";
-const Volume::Capability VolumeSw::kCapability;
+const Volume::Capability VolumeSw::kCapability = {.maxLevel = Volume::MAX_LEVEL_DB};
const Descriptor VolumeSw::kDescriptor = {
.common = {.id = {.type = kVolumeTypeUUID,
.uuid = kVolumeSwImplUUID,
@@ -82,16 +82,66 @@
RETURN_IF(Parameter::Specific::volume != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
- mSpecificParam = specific.get<Parameter::Specific::volume>();
- LOG(DEBUG) << __func__ << " success with: " << specific.toString();
- return ndk::ScopedAStatus::ok();
+ auto& volParam = specific.get<Parameter::Specific::volume>();
+ auto tag = volParam.getTag();
+
+ switch (tag) {
+ case Volume::levelDb: {
+ RETURN_IF(mContext->setVolLevel(volParam.get<Volume::levelDb>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "LevelNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ case Volume::mute: {
+ RETURN_IF(mContext->setVolMute(volParam.get<Volume::mute>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "MuteNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "VolumeTagNotSupported");
+ }
+ }
}
ndk::ScopedAStatus VolumeSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::volumeTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
- specific->set<Parameter::Specific::volume>(mSpecificParam);
+ auto volId = id.get<Parameter::Id::volumeTag>();
+ auto volIdTag = volId.getTag();
+ switch (volIdTag) {
+ case Volume::Id::commonTag:
+ return getParameterVolume(volId.get<Volume::Id::commonTag>(), specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "VolumeTagNotSupported");
+ }
+}
+
+ndk::ScopedAStatus VolumeSw::getParameterVolume(const Volume::Tag& tag,
+ Parameter::Specific* specific) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ Volume volParam;
+ switch (tag) {
+ case Volume::levelDb: {
+ volParam.set<Volume::levelDb>(mContext->getVolLevel());
+ break;
+ }
+ case Volume::mute: {
+ volParam.set<Volume::mute>(mContext->getVolMute());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "VolumeTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::volume>(volParam);
return ndk::ScopedAStatus::ok();
}
diff --git a/audio/aidl/default/volume/VolumeSw.h b/audio/aidl/default/volume/VolumeSw.h
index 3bd29b9..a101c59 100644
--- a/audio/aidl/default/volume/VolumeSw.h
+++ b/audio/aidl/default/volume/VolumeSw.h
@@ -32,7 +32,30 @@
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
- // TODO: add specific context here
+
+ RetCode setVolLevel(int level) {
+ if (level < Volume::MIN_LEVEL_DB || level > Volume::MAX_LEVEL_DB) {
+ LOG(ERROR) << __func__ << " invalid level " << level;
+ return RetCode::ERROR_ILLEGAL_PARAMETER;
+ }
+ // TODO : Add implementation to apply new level
+ mLevel = level;
+ return RetCode::SUCCESS;
+ }
+
+ int getVolLevel() const { return mLevel; }
+
+ RetCode setVolMute(bool mute) {
+ // TODO : Add implementation to modify mute
+ mMute = mute;
+ return RetCode::SUCCESS;
+ }
+
+ bool getVolMute() const { return mMute; }
+
+ private:
+ int mLevel = 0;
+ bool mMute = false;
};
class VolumeSw final : public EffectImpl {
@@ -60,7 +83,7 @@
private:
std::shared_ptr<VolumeSwContext> mContext;
- /* parameters */
- Volume mSpecificParam;
+
+ ndk::ScopedAStatus getParameterVolume(const Volume::Tag& tag, Parameter::Specific* specific);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index 8a5a25c..2b4692e 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -110,6 +110,12 @@
}
cc_test {
+ name: "VtsHalVolumeTargetTest",
+ defaults: ["VtsHalAudioTargetTestDefaults"],
+ srcs: ["VtsHalVolumeTargetTest.cpp"],
+}
+
+cc_test {
name: "VtsHalAECTargetTest",
defaults: ["VtsHalAudioTargetTestDefaults"],
srcs: ["VtsHalAECTargetTest.cpp"],
diff --git a/audio/aidl/vts/VtsHalAECTargetTest.cpp b/audio/aidl/vts/VtsHalAECTargetTest.cpp
index a06ab42..eb92ef8 100644
--- a/audio/aidl/vts/VtsHalAECTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAECTargetTest.cpp
@@ -14,12 +14,13 @@
* limitations under the License.
*/
+#include <Utils.h>
#include <aidl/Vintf.h>
#include <algorithm>
+#include <unordered_set>
#define LOG_TAG "VtsHalAECParamTest"
-#include <Utils.h>
#include "EffectHelper.h"
using namespace android;
@@ -70,8 +71,8 @@
}
static const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList;
- static const std::vector<int> kEchoDelayValues;
- static const std::vector<bool> kMobileModeValues;
+ static const std::unordered_set<int> kEchoDelayValues;
+ static const std::unordered_set<bool> kMobileModeValues;
static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
std::shared_ptr<IFactory> mFactory;
@@ -155,7 +156,7 @@
}
}
- static std::vector<int> getEchoDelayTestValues() {
+ static std::unordered_set<int> getEchoDelayTestValues() {
const auto max = std::max_element(
kFactoryDescList.begin(), kFactoryDescList.end(),
[](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
@@ -181,8 +182,9 @@
const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> AECParamTest::kFactoryDescList =
EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
kAcousticEchoCancelerTypeUUID);
-const std::vector<int> AECParamTest::kEchoDelayValues = AECParamTest::getEchoDelayTestValues();
-const std::vector<bool> AECParamTest::kMobileModeValues = {true, false};
+const std::unordered_set<int> AECParamTest::kEchoDelayValues =
+ AECParamTest::getEchoDelayTestValues();
+const std::unordered_set<bool> AECParamTest::kMobileModeValues = {true, false};
TEST_P(AECParamTest, SetAndGetEchoDelay) {
EXPECT_NO_FATAL_FAILURE(addEchoDelayParam(mEchoDelay));
diff --git a/audio/aidl/vts/VtsHalAGCTargetTest.cpp b/audio/aidl/vts/VtsHalAGCTargetTest.cpp
index ea3654f..484cc84 100644
--- a/audio/aidl/vts/VtsHalAGCTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGCTargetTest.cpp
@@ -14,11 +14,13 @@
* limitations under the License.
*/
+#include <Utils.h>
#include <aidl/Vintf.h>
+#include <android/binder_enums.h>
+#include <unordered_set>
#define LOG_TAG "VtsHalAGCParamTest"
-#include <Utils.h>
#include "EffectHelper.h"
using namespace android;
@@ -78,9 +80,9 @@
static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
static const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList;
- static const std::vector<int> kDigitalGainValues;
- static const std::vector<int> kSaturationMarginValues;
- static const std::vector<AutomaticGainControl::LevelEstimator> kLevelEstimatorValues;
+ static const std::unordered_set<int> kDigitalGainValues;
+ static const std::unordered_set<int> kSaturationMarginValues;
+ static const std::unordered_set<AutomaticGainControl::LevelEstimator> kLevelEstimatorValues;
std::shared_ptr<IFactory> mFactory;
std::shared_ptr<IEffect> mEffect;
@@ -158,7 +160,7 @@
return false;
}
}
- static std::vector<int> getDigitalGainValues() {
+ static std::unordered_set<int> getDigitalGainValues() {
const auto max = std::max_element(
kFactoryDescList.begin(), kFactoryDescList.end(),
[](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
@@ -175,7 +177,7 @@
.maxFixedDigitalGainMb;
return {-1, 0, maxGain - 1, maxGain, maxGain + 1};
}
- static std::vector<int> getSaturationMarginValues() {
+ static std::unordered_set<int> getSaturationMarginValues() {
const auto max = std::max_element(
kFactoryDescList.begin(), kFactoryDescList.end(),
[](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
@@ -201,11 +203,13 @@
const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> AGCParamTest::kFactoryDescList =
EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
kAutomaticGainControlTypeUUID);
-const std::vector<int> AGCParamTest::kDigitalGainValues = AGCParamTest::getDigitalGainValues();
-const std::vector<int> AGCParamTest::kSaturationMarginValues =
+const std::unordered_set<int> AGCParamTest::kDigitalGainValues =
+ AGCParamTest::getDigitalGainValues();
+const std::unordered_set<int> AGCParamTest::kSaturationMarginValues =
AGCParamTest::getSaturationMarginValues();
-const std::vector<AutomaticGainControl::LevelEstimator> AGCParamTest::kLevelEstimatorValues = {
- AutomaticGainControl::LevelEstimator::RMS, AutomaticGainControl::LevelEstimator::PEAK};
+const std::unordered_set<AutomaticGainControl::LevelEstimator> AGCParamTest::kLevelEstimatorValues =
+ {ndk::enum_range<AutomaticGainControl::LevelEstimator>().begin(),
+ ndk::enum_range<AutomaticGainControl::LevelEstimator>().end()};
TEST_P(AGCParamTest, SetAndGetDigitalGainParam) {
EXPECT_NO_FATAL_FAILURE(addDigitalGainParam(mGain));
diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index a1daec2..d1f3b97 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -18,6 +18,9 @@
#include <Utils.h>
#include <aidl/Vintf.h>
+#include <android/binder_enums.h>
+#include <unordered_set>
+
#include "EffectHelper.h"
using namespace android;
@@ -61,9 +64,8 @@
const std::vector<int> kHapticScaleIdValues = {MIN_ID, 0, MAX_ID};
const std::vector<HapticGenerator::VibratorScale> kVibratorScaleValues = {
- HapticGenerator::VibratorScale::MUTE, HapticGenerator::VibratorScale::VERY_LOW,
- HapticGenerator::VibratorScale::LOW, HapticGenerator::VibratorScale::NONE,
- HapticGenerator::VibratorScale::HIGH, HapticGenerator::VibratorScale::VERY_HIGH};
+ ndk::enum_range<HapticGenerator::VibratorScale>().begin(),
+ ndk::enum_range<HapticGenerator::VibratorScale>().end()};
const std::vector<float> kResonantFrequencyValues = {MIN_FLOAT, 100, MAX_FLOAT};
const std::vector<float> kQFactorValues = {MIN_FLOAT, 100, MAX_FLOAT};
diff --git a/audio/aidl/vts/VtsHalNSTargetTest.cpp b/audio/aidl/vts/VtsHalNSTargetTest.cpp
index 186cb68..2845225 100644
--- a/audio/aidl/vts/VtsHalNSTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalNSTargetTest.cpp
@@ -19,6 +19,7 @@
#define LOG_TAG "VtsHalNSParamTest"
#include <Utils.h>
+#include <unordered_set>
#include "EffectHelper.h"
using namespace android;
@@ -69,7 +70,7 @@
static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
static const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList;
- static const std::vector<NoiseSuppression::Level> kLevelValues;
+ static const std::unordered_set<NoiseSuppression::Level> kLevelValues;
std::shared_ptr<IFactory> mFactory;
std::shared_ptr<IEffect> mEffect;
@@ -122,9 +123,9 @@
const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList =
EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
kNoiseSuppressionTypeUUID);
-const std::vector<NoiseSuppression::Level> NSParamTest::kLevelValues = {
- NoiseSuppression::Level::LOW, NoiseSuppression::Level::MEDIUM,
- NoiseSuppression::Level::HIGH};
+const std::unordered_set<NoiseSuppression::Level> NSParamTest::kLevelValues = {
+ ndk::enum_range<NoiseSuppression::Level>().begin(),
+ ndk::enum_range<NoiseSuppression::Level>().end()};
TEST_P(NSParamTest, SetAndGetLevel) {
EXPECT_NO_FATAL_FAILURE(addLevelParam(mLevel));
diff --git a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
index a7834fb..47d6755 100644
--- a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
@@ -19,6 +19,9 @@
#define LOG_TAG "VtsHalVisualizerTest"
#include <Utils.h>
+#include <android/binder_enums.h>
+#include <unordered_set>
+
#include "EffectHelper.h"
using namespace android;
@@ -46,18 +49,6 @@
std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int, Visualizer::ScalingMode,
Visualizer::MeasurementMode, int>;
-const int MIN_CAPTURE_SIZE = 128;
-const int MAX_CAPTURE_SIZE = 1024;
-const int MAX_LATENCY = 3000;
-
-const std::vector<int> kCaptureSizeValues = {MIN_CAPTURE_SIZE - 1, MIN_CAPTURE_SIZE,
- MAX_CAPTURE_SIZE, MAX_CAPTURE_SIZE + 1};
-const std::vector<Visualizer::ScalingMode> kScalingModeValues = {
- Visualizer::ScalingMode::NORMALIZED, Visualizer::ScalingMode::AS_PLAYED};
-const std::vector<Visualizer::MeasurementMode> kMeasurementModeValues = {
- Visualizer::MeasurementMode::NONE, Visualizer::MeasurementMode::PEAK_RMS};
-const std::vector<int> kLatencyValues = {-1, 0, MAX_LATENCY, MAX_LATENCY + 1};
-
class VisualizerParamTest : public ::testing::TestWithParam<VisualizerParamTestParam>,
public EffectHelper {
public:
@@ -86,19 +77,25 @@
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
}
-
Parameter::Specific getDefaultParamSpecific() {
- Visualizer vs = Visualizer::make<Visualizer::captureSizeBytes>(MIN_CAPTURE_SIZE);
+ Visualizer vs = Visualizer::make<Visualizer::captureSamples>(
+ mDescriptor.capability.get<Capability::visualizer>().captureSampleRange.max);
Parameter::Specific specific =
Parameter::Specific::make<Parameter::Specific::visualizer>(vs);
return specific;
}
+ static const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList;
+ static const std::unordered_set<Visualizer::ScalingMode> kScalingModeValues;
+ static const std::unordered_set<Visualizer::MeasurementMode> kMeasurementModeValues;
+ static const std::unordered_set<int> kLatencyValues;
+ static const std::unordered_set<int> kCaptureSizeValues;
+
static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
std::shared_ptr<IFactory> mFactory;
std::shared_ptr<IEffect> mEffect;
Descriptor mDescriptor;
- int mCaptureSize = MAX_CAPTURE_SIZE;
+ int mCaptureSize;
Visualizer::ScalingMode mScalingMode = Visualizer::ScalingMode::NORMALIZED;
Visualizer::MeasurementMode mMeasurementMode = Visualizer::MeasurementMode::NONE;
int mLatency = 0;
@@ -184,8 +181,8 @@
void addCaptureSizeParam(int captureSize) {
Visualizer vs;
- vs.set<Visualizer::captureSizeBytes>(captureSize);
- mCommonTags.push_back({Visualizer::captureSizeBytes, vs});
+ vs.set<Visualizer::captureSamples>(captureSize);
+ mCommonTags.push_back({Visualizer::captureSamples, vs});
}
void addScalingModeParam(Visualizer::ScalingMode scalingMode) {
@@ -213,15 +210,15 @@
}
void addCaptureBytesTag() {
- mGetOnlyParamTags.push_back(Visualizer::GetOnlyParameters::captureBytes);
+ mGetOnlyParamTags.push_back(Visualizer::GetOnlyParameters::captureSampleBuffer);
}
bool isTagInRange(const Visualizer::Tag& tag, const Visualizer& vs,
const Descriptor& desc) const {
const Visualizer::Capability& vsCap = desc.capability.get<Capability::visualizer>();
switch (tag) {
- case Visualizer::captureSizeBytes: {
- int captureSize = vs.get<Visualizer::captureSizeBytes>();
+ case Visualizer::captureSamples: {
+ int captureSize = vs.get<Visualizer::captureSamples>();
return isCaptureSizeInRange(vsCap, captureSize);
}
case Visualizer::scalingMode:
@@ -243,14 +240,45 @@
}
bool isCaptureSizeInRange(const Visualizer::Capability& cap, int captureSize) const {
- return (captureSize >= cap.captureSizeRange.minBytes &&
- captureSize <= cap.captureSizeRange.maxBytes);
+ return (captureSize >= cap.captureSampleRange.min &&
+ captureSize <= cap.captureSampleRange.max);
}
bool isLatencyInRange(const Visualizer::Capability& cap, int latency) const {
return (latency >= 0 && latency <= cap.maxLatencyMs);
}
+ static std::unordered_set<int> getCaptureSizeValues() {
+ int minCaptureSize = std::numeric_limits<int>::max();
+ int maxCaptureSize = std::numeric_limits<int>::min();
+ for (const auto& it : kFactoryDescList) {
+ maxCaptureSize = std::max(
+ it.second.capability.get<Capability::visualizer>().captureSampleRange.max,
+ maxCaptureSize);
+ minCaptureSize = std::min(
+ it.second.capability.get<Capability ::visualizer>().captureSampleRange.min,
+ minCaptureSize);
+ }
+ return {std::numeric_limits<int>::min(), minCaptureSize - 1, minCaptureSize,
+ (minCaptureSize + maxCaptureSize) >> 1, maxCaptureSize, maxCaptureSize + 1,
+ std::numeric_limits<int>::max()};
+ }
+
+ static std::unordered_set<int> getLatencyValues() {
+ const auto max = std::max_element(
+ kFactoryDescList.begin(), kFactoryDescList.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::visualizer>().maxLatencyMs <
+ b.second.capability.get<Capability::visualizer>().maxLatencyMs;
+ });
+ if (max == kFactoryDescList.end()) {
+ return {0};
+ }
+ int maxDelay = max->second.capability.get<Capability::visualizer>().maxLatencyMs;
+ return {-1, 0, maxDelay >> 1, maxDelay - 1, maxDelay, maxDelay + 1};
+ }
+
private:
std::vector<std::pair<Visualizer::Tag, Visualizer>> mCommonTags;
std::vector<std::pair<Visualizer::SetOnlyParameters::Tag, Visualizer>> mSetOnlyParamTags;
@@ -262,6 +290,20 @@
}
};
+const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>>
+ VisualizerParamTest::kFactoryDescList = EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kVisualizerTypeUUID);
+const std::unordered_set<int> VisualizerParamTest::kCaptureSizeValues =
+ VisualizerParamTest::getCaptureSizeValues();
+const std::unordered_set<Visualizer::MeasurementMode> VisualizerParamTest::kMeasurementModeValues(
+ ndk::enum_range<Visualizer::MeasurementMode>().begin(),
+ ndk::enum_range<Visualizer::MeasurementMode>().end());
+const std::unordered_set<Visualizer::ScalingMode> VisualizerParamTest::kScalingModeValues(
+ ndk::enum_range<Visualizer::ScalingMode>().begin(),
+ ndk::enum_range<Visualizer::ScalingMode>().end());
+const std::unordered_set<int> VisualizerParamTest::kLatencyValues =
+ VisualizerParamTest::getLatencyValues();
+
TEST_P(VisualizerParamTest, SetAndGetCaptureSize) {
EXPECT_NO_FATAL_FAILURE(addCaptureSizeParam(mCaptureSize));
SetAndGetCommonParameters();
@@ -293,13 +335,13 @@
}
INSTANTIATE_TEST_SUITE_P(
- VisualizerTest, VisualizerParamTest,
+ VisualizerParamTest, VisualizerParamTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kVisualizerTypeUUID)),
- testing::ValuesIn(kCaptureSizeValues),
- testing::ValuesIn(kScalingModeValues),
- testing::ValuesIn(kMeasurementModeValues),
- testing::ValuesIn(kLatencyValues)),
+ testing::ValuesIn(VisualizerParamTest::kCaptureSizeValues),
+ testing::ValuesIn(VisualizerParamTest::kScalingModeValues),
+ testing::ValuesIn(VisualizerParamTest::kMeasurementModeValues),
+ testing::ValuesIn(VisualizerParamTest::kLatencyValues)),
[](const testing::TestParamInfo<VisualizerParamTest::ParamType>& info) {
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
std::string captureSize = std::to_string(std::get<PARAM_CAPTURE_SIZE>(info.param));
diff --git a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
new file mode 100644
index 0000000..3e82854
--- /dev/null
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -0,0 +1,186 @@
+/*
+ * 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 "VtsHalVolumeTest"
+
+#include <Utils.h>
+#include <aidl/Vintf.h>
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Capability;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::kVolumeTypeUUID;
+using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Volume;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL_DB, PARAM_MUTE };
+using VolumeParamTestParam =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int, bool>;
+
+const std::vector<int> kLevelValues = {Volume::MIN_LEVEL_DB - 1, Volume::MIN_LEVEL_DB, -100,
+ Volume::MAX_LEVEL_DB, Volume::MAX_LEVEL_DB + 1};
+
+class VolumeParamTest : public ::testing::TestWithParam<VolumeParamTestParam>, public EffectHelper {
+ public:
+ VolumeParamTest()
+ : mParamLevel(std::get<PARAM_LEVEL_DB>(GetParam())),
+ mParamMute(std::get<PARAM_MUTE>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+ }
+
+ void SetUp() override {
+ ASSERT_NE(nullptr, mFactory);
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+ Parameter::Specific specific = getDefaultParamSpecific();
+ Parameter::Common common = EffectHelper::createParamCommon(
+ 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+ kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+ IEffect::OpenEffectReturn ret;
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+ ASSERT_NE(nullptr, mEffect);
+ }
+ void TearDown() override {
+ ASSERT_NO_FATAL_FAILURE(close(mEffect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+ }
+
+ Parameter::Specific getDefaultParamSpecific() {
+ Volume vol = Volume::make<Volume::levelDb>(Volume::MIN_LEVEL_DB);
+ Parameter::Specific specific = Parameter::Specific::make<Parameter::Specific::volume>(vol);
+ return specific;
+ }
+
+ static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+ std::shared_ptr<IFactory> mFactory;
+ std::shared_ptr<IEffect> mEffect;
+ Descriptor mDescriptor;
+ int mParamLevel = 0;
+ bool mParamMute = false;
+
+ void SetAndGetParameters() {
+ for (auto& it : mTags) {
+ auto& tag = it.first;
+ auto& vol = it.second;
+
+ // validate parameter
+ Descriptor desc;
+ ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+ const bool valid = isTagInRange(it.first, it.second, desc);
+ const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+ // set parameter
+ Parameter expectParam;
+ Parameter::Specific specific;
+ specific.set<Parameter::Specific::volume>(vol);
+ expectParam.set<Parameter::specific>(specific);
+ EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+ // only get if parameter in range and set success
+ if (expected == EX_NONE) {
+ Parameter getParam;
+ Parameter::Id id;
+ Volume::Id volId;
+ volId.set<Volume::Id::commonTag>(tag);
+ id.set<Parameter::Id::volumeTag>(volId);
+ EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+
+ EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+ << "\ngetParam:" << getParam.toString();
+ }
+ }
+ }
+
+ void addLevelParam(int level) {
+ Volume vol;
+ vol.set<Volume::levelDb>(level);
+ mTags.push_back({Volume::levelDb, vol});
+ }
+
+ void addMuteParam(bool mute) {
+ Volume vol;
+ vol.set<Volume::mute>(mute);
+ mTags.push_back({Volume::mute, vol});
+ }
+
+ bool isTagInRange(const Volume::Tag& tag, const Volume& vol, const Descriptor& desc) const {
+ const Volume::Capability& volCap = desc.capability.get<Capability::volume>();
+ switch (tag) {
+ case Volume::levelDb: {
+ int level = vol.get<Volume::levelDb>();
+ return isLevelInRange(volCap, level);
+ }
+ case Volume::mute:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool isLevelInRange(const Volume::Capability& cap, int level) const {
+ return level >= Volume::MIN_LEVEL_DB && level <= Volume::MAX_LEVEL_DB &&
+ level <= cap.maxLevel;
+ }
+
+ private:
+ std::vector<std::pair<Volume::Tag, Volume>> mTags;
+ void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(VolumeParamTest, SetAndGetLevel) {
+ EXPECT_NO_FATAL_FAILURE(addLevelParam(mParamLevel));
+ SetAndGetParameters();
+}
+
+TEST_P(VolumeParamTest, SetAndGetMute) {
+ EXPECT_NO_FATAL_FAILURE(addMuteParam(mParamMute));
+ SetAndGetParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ VolumeTest, VolumeParamTest,
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kVolumeTypeUUID)),
+ testing::ValuesIn(kLevelValues), testing::Bool()),
+ [](const testing::TestParamInfo<VolumeParamTest::ParamType>& info) {
+ auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+ std::string level = std::to_string(std::get<PARAM_LEVEL_DB>(info.param));
+ std::string mute = std::to_string(std::get<PARAM_MUTE>(info.param));
+ std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+ descriptor.common.name + "_UUID_" +
+ descriptor.common.id.uuid.toString() + "_level" + level + "_mute" +
+ mute;
+ std::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VolumeParamTest);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index 719f752..c4c18a4 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -687,7 +687,12 @@
InputStreamTest::TearDown();
}
- bool canQueryCapturePosition() const { return !xsd::isTelephonyDevice(address.deviceType); }
+ bool canQueryCapturePosition() const {
+ // See b/263305254 and b/259636577. Must use the device initially passed in
+ // as a parameter, not 'address' which gets adjusted during test setup for
+ // the telephony case.
+ return !xsd::isTelephonyDevice(getAttachedDeviceAddress().deviceType);
+ }
void createPatchIfNeeded() {
if (areAudioPatchesSupported()) {
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
index 0b1634c..c17a2e2 100644
--- a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -1976,7 +1976,8 @@
"maxFloatValue": 28.0
}
],
- "comment": "minFloatValue and maxFloatValue in area config should match corresponding values in configArray",
+ "comment":
+ "minFloatValue and maxFloatValue in area config should match corresponding values in configArray",
"configArray": [
160,
280,
diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.xml b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.xml
index ea7adc9..6010c60 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.xml
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.xml
@@ -24,8 +24,10 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="run-command" value="settings put global ble_scan_always_enabled 0" />
- <option name="run-command" value="su u$(am get-current-user)_system svc bluetooth disable" />
- <option name="teardown-command" value="su u$(am get-current-user)_system svc bluetooth enable" />
+ <option name="run-command" value="cmd bluetooth_manager disable" />
+ <option name="run-command" value="cmd bluetooth_manager wait-for-state:STATE_OFF" />
+ <option name="teardown-command" value="cmd bluetooth_manager enable" />
+ <option name="teardown-command" value="cmd bluetooth_manager wait-for-state:STATE_ON" />
<option name="teardown-command" value="settings put global ble_scan_always_enabled 1" />
</target_preparer>
diff --git a/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.xml b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.xml
index 98b62ef..0234dc8 100644
--- a/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.xml
+++ b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.xml
@@ -22,8 +22,10 @@
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="run-command" value="settings put global ble_scan_always_enabled 0" />
- <option name="run-command" value="su u$(am get-current-user)_system svc bluetooth disable" />
- <option name="teardown-command" value="su u$(am get-current-user)_system svc bluetooth enable" />
+ <option name="run-command" value="cmd bluetooth_manager disable" />
+ <option name="run-command" value="cmd bluetooth_manager wait-for-state:STATE_OFF" />
+ <option name="teardown-command" value="cmd bluetooth_manager enable" />
+ <option name="teardown-command" value="cmd bluetooth_manager wait-for-state:STATE_ON" />
<option name="teardown-command" value="settings put global ble_scan_always_enabled 1" />
</target_preparer>
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl
index 0484d02..646c502 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl
@@ -110,10 +110,11 @@
HD_STATION_NAME,
/**
- * 28bit compound primary identifier for Digital Audio Broadcasting.
+ * 44bit compound primary identifier for Digital Audio Broadcasting and
+ * Digital Multimeida Broadcasting.
*
* Consists of (from the LSB):
- * - 16bit: SId;
+ * - 32bit: SId;
* - 8bit: ECC code;
* - 4bit: SCIdS.
*
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl
index 3e2c9cc..d650239 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl
@@ -120,7 +120,7 @@
*
* Only physical identifiers are valid:
* - AMFM_FREQUENCY_KHZ;
- * - DAB_ENSEMBLE;
+ * - DAB_FREQUENCY_KHZ;
* - DRMO_FREQUENCY_KHZ;
* - SXM_CHANNEL;
* - VENDOR_*;
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl
index 8bd3fd4..93b0e12 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl
@@ -51,7 +51,8 @@
* - analogue AM/FM: AMFM_FREQUENCY_KHZ;
* - FM RDS: RDS_PI;
* - HD Radio: HD_STATION_ID_EXT;
- * - DAB: DAB_SID_EXT;
+ * - DAB/DMB: DAB_SID_EXT (when used, DAB_ENSEMBLE and DAB_FREQUENCY_KHZ
+ * must present in secondaryIds);
* - Digital Radio Mondiale: DRMO_SERVICE_ID;
* - SiriusXM: SXM_SERVICE_ID;
* - vendor-specific: VENDOR_START..VENDOR_END.
diff --git a/broadcastradio/aidl/default/BroadcastRadio.cpp b/broadcastradio/aidl/default/BroadcastRadio.cpp
index 42e550e..36520fb 100644
--- a/broadcastradio/aidl/default/BroadcastRadio.cpp
+++ b/broadcastradio/aidl/default/BroadcastRadio.cpp
@@ -589,22 +589,28 @@
}
ProgramSelector sel = {};
if (isDab) {
- if (numArgs != 4) {
+ if (numArgs != 5) {
dprintf(fd,
- "Invalid number of arguments: please provide --tune dab <SID> <ENSEMBLE>\n");
+ "Invalid number of arguments: please provide "
+ "--tune dab <SID> <ENSEMBLE> <FREQUENCY>\n");
return STATUS_BAD_VALUE;
}
int sid;
if (!utils::parseArgInt(string(args[2]), &sid)) {
- dprintf(fd, "Non-integer sid provided with tune: %s\n", string(args[2]).c_str());
+ dprintf(fd, "Non-integer sid provided with tune: %s\n", args[2]);
return STATUS_BAD_VALUE;
}
int ensemble;
if (!utils::parseArgInt(string(args[3]), &ensemble)) {
- dprintf(fd, "Non-integer ensemble provided with tune: %s\n", string(args[3]).c_str());
+ dprintf(fd, "Non-integer ensemble provided with tune: %s\n", args[3]);
return STATUS_BAD_VALUE;
}
- sel = utils::makeSelectorDab(sid, ensemble);
+ int freq;
+ if (!utils::parseArgInt(string(args[4]), &freq)) {
+ dprintf(fd, "Non-integer frequency provided with tune: %s\n", args[4]);
+ return STATUS_BAD_VALUE;
+ }
+ sel = utils::makeSelectorDab(sid, ensemble, freq);
} else {
if (numArgs != 3) {
dprintf(fd, "Invalid number of arguments: please provide --tune amfm <FREQUENCY>\n");
@@ -612,7 +618,7 @@
}
int freq;
if (!utils::parseArgInt(string(args[2]), &freq)) {
- dprintf(fd, "Non-integer frequency provided with tune: %s\n", string(args[2]).c_str());
+ dprintf(fd, "Non-integer frequency provided with tune: %s\n", args[2]);
return STATUS_BAD_VALUE;
}
sel = utils::makeSelectorAmfm(freq);
diff --git a/broadcastradio/aidl/default/VirtualProgram.cpp b/broadcastradio/aidl/default/VirtualProgram.cpp
index 0df0a82..4fe6567 100644
--- a/broadcastradio/aidl/default/VirtualProgram.cpp
+++ b/broadcastradio/aidl/default/VirtualProgram.cpp
@@ -53,7 +53,7 @@
break;
case IdentifierType::DAB_SID_EXT:
info.logicallyTunedTo = selectId(IdentifierType::DAB_SID_EXT);
- info.physicallyTunedTo = selectId(IdentifierType::DAB_ENSEMBLE);
+ info.physicallyTunedTo = selectId(IdentifierType::DAB_FREQUENCY_KHZ);
break;
case IdentifierType::DRMO_SERVICE_ID:
info.logicallyTunedTo = selectId(IdentifierType::DRMO_SERVICE_ID);
diff --git a/broadcastradio/aidl/default/VirtualRadio.cpp b/broadcastradio/aidl/default/VirtualRadio.cpp
index 851543b..126bcff 100644
--- a/broadcastradio/aidl/default/VirtualRadio.cpp
+++ b/broadcastradio/aidl/default/VirtualRadio.cpp
@@ -53,15 +53,18 @@
static VirtualRadio amFmRadioMock(
"AM/FM radio mock",
{
- {makeSelectorAmfm(94900), "Wild 94.9", "Drake ft. Rihanna", "Too Good"},
- {makeSelectorAmfm(96500), "KOIT", "Celine Dion", "All By Myself"},
- {makeSelectorAmfm(97300), "Alice@97.3", "Drops of Jupiter", "Train"},
- {makeSelectorAmfm(99700), "99.7 Now!", "The Chainsmokers", "Closer"},
- {makeSelectorAmfm(101300), "101-3 KISS-FM", "Justin Timberlake", "Rock Your Body"},
- {makeSelectorAmfm(103700), "iHeart80s @ 103.7", "Michael Jackson", "Billie Jean"},
- {makeSelectorAmfm(106100), "106 KMEL", "Drake", "Marvins Room"},
- {makeSelectorAmfm(700), "700 AM", "Artist700", "Title700"},
- {makeSelectorAmfm(1700), "1700 AM", "Artist1700", "Title1700"},
+ {makeSelectorAmfm(/* frequency= */ 94900), "Wild 94.9", "Drake ft. Rihanna",
+ "Too Good"},
+ {makeSelectorAmfm(/* frequency= */ 96500), "KOIT", "Celine Dion", "All By Myself"},
+ {makeSelectorAmfm(/* frequency= */ 97300), "Alice@97.3", "Drops of Jupiter", "Train"},
+ {makeSelectorAmfm(/* frequency= */ 99700), "99.7 Now!", "The Chainsmokers", "Closer"},
+ {makeSelectorAmfm(/* frequency= */ 101300), "101-3 KISS-FM", "Justin Timberlake",
+ "Rock Your Body"},
+ {makeSelectorAmfm(/* frequency= */ 103700), "iHeart80s @ 103.7", "Michael Jackson",
+ "Billie Jean"},
+ {makeSelectorAmfm(/* frequency= */ 106100), "106 KMEL", "Drake", "Marvins Room"},
+ {makeSelectorAmfm(/* frequency= */ 700), "700 AM", "Artist700", "Title700"},
+ {makeSelectorAmfm(/* frequency= */ 1700), "1700 AM", "Artist1700", "Title1700"},
});
// clang-format on
return amFmRadioMock;
@@ -73,9 +76,14 @@
static VirtualRadio dabRadioMock(
"DAB radio mock",
{
- {makeSelectorDab(0xA00001u, 0x0001u), "BBC Radio 1", "Khalid", "Talk"},
- {makeSelectorDab(0xB00001u, 0x1001u), "Classic FM", "Jean Sibelius", "Andante Festivo"},
- {makeSelectorDab(0xB00002u, 0x1001u), "Absolute Radio", "Coldplay", "Clocks"},
+ {makeSelectorDab(/* sidExt= */ 0xA000000001u, /* ensemble= */ 0x0001u,
+ /* freq= */ 225648), "BBC Radio 1", "Khalid", "Talk"},
+ {makeSelectorDab(/* sidExt= */ 0xB000000001u, /* ensemble= */ 0x1001u,
+ /* freq= */ 222064), "Classic FM", "Jean Sibelius", "Andante Festivo"},
+ {makeSelectorDab(/* sidExt= */ 0xB000000002u, /* ensemble= */ 0x1002u,
+ /* freq= */ 227360), "Absolute Radio", "Coldplay", "Clocks"},
+ {makeSelectorDab(/* sidExt= */ 0xB000000002u, /* ensemble= */ 0x1002u,
+ /* freq= */ 222064), "Absolute Radio", "Coldplay", "Clocks"},
});
// clang-format on
return dabRadioMock;
diff --git a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
index 5a56846..356673f 100644
--- a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
+++ b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
@@ -46,6 +46,7 @@
using ::aidl::android::hardware::broadcastradio::utils::makeIdentifier;
using ::aidl::android::hardware::broadcastradio::utils::makeSelectorAmfm;
+using ::aidl::android::hardware::broadcastradio::utils::makeSelectorDab;
using ::aidl::android::hardware::broadcastradio::utils::resultToInt;
using ::ndk::ScopedAStatus;
using ::ndk::SharedRefBase;
@@ -110,8 +111,7 @@
class TunerCallbackMock : public BnTunerCallback {
public:
TunerCallbackMock();
-
- MOCK_METHOD2(onTuneFailed, ScopedAStatus(Result, const ProgramSelector&));
+ ScopedAStatus onTuneFailed(Result result, const ProgramSelector& selector) override;
MOCK_TIMEOUT_METHOD1(onCurrentProgramInfoChangedMock, ScopedAStatus(const ProgramInfo&));
ScopedAStatus onCurrentProgramInfoChanged(const ProgramInfo& info) override;
ScopedAStatus onProgramListUpdated(const ProgramListChunk& chunk) override;
@@ -154,6 +154,12 @@
EXPECT_CALL(*this, onAntennaStateChange(false)).Times(0);
}
+ScopedAStatus TunerCallbackMock::onTuneFailed(Result result, const ProgramSelector& selector) {
+ LOG(DEBUG) << "Tune failed for selector" << selector.toString();
+ EXPECT_TRUE(result == Result::CANCELED);
+ return ndk::ScopedAStatus::ok();
+}
+
ScopedAStatus TunerCallbackMock::onCurrentProgramInfoChanged(const ProgramInfo& info) {
for (const auto& id : info.selector) {
EXPECT_NE(id.type, IdentifierType::INVALID);
@@ -175,7 +181,7 @@
IdentifierType physically = info.physicallyTunedTo.type;
// ditto (see "logically" above)
EXPECT_TRUE(physically == IdentifierType::AMFM_FREQUENCY_KHZ ||
- physically == IdentifierType::DAB_ENSEMBLE ||
+ physically == IdentifierType::DAB_FREQUENCY_KHZ ||
physically == IdentifierType::DRMO_FREQUENCY_KHZ ||
physically == IdentifierType::SXM_CHANNEL ||
(physically >= IdentifierType::VENDOR_START &&
@@ -593,10 +599,43 @@
ASSERT_TRUE(halResult.isOk());
ASSERT_NE(config.size(), 0U);
- // TODO(245787803): use a DAB frequency that can actually be tuned to.
+ auto programList = getProgramList();
+
+ if (!programList) {
+ printSkipped("Empty DAB station list, tune cannot be performed");
+ return;
+ }
+
ProgramSelector sel = {};
- int64_t freq = config[config.size() / 2].frequencyKhz;
- sel.primaryId = makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, freq);
+ uint64_t freq = 0;
+ bool dabStationPresent = false;
+ for (auto&& programInfo : *programList) {
+ if (!utils::hasId(programInfo.selector, IdentifierType::DAB_FREQUENCY_KHZ)) {
+ continue;
+ }
+ for (auto&& config_entry : config) {
+ if (config_entry.frequencyKhz ==
+ utils::getId(programInfo.selector, IdentifierType::DAB_FREQUENCY_KHZ, 0)) {
+ freq = config_entry.frequencyKhz;
+ break;
+ }
+ }
+ // Do not trigger a tune request if the programList entry does not contain
+ // a valid DAB frequency.
+ if (freq == 0) {
+ continue;
+ }
+ int64_t dabSidExt = utils::getId(programInfo.selector, IdentifierType::DAB_SID_EXT, 0);
+ int64_t dabEns = utils::getId(programInfo.selector, IdentifierType::DAB_ENSEMBLE, 0);
+ sel = makeSelectorDab(dabSidExt, (int32_t)dabEns, freq);
+ dabStationPresent = true;
+ break;
+ }
+
+ if (!dabStationPresent) {
+ printSkipped("No DAB stations in the list, tune cannot be performed");
+ return;
+ }
// try tuning
ProgramInfo infoCb = {};
@@ -623,7 +662,6 @@
vector<int> freqs = bcutils::getAllIds(infoCb.selector, IdentifierType::DAB_FREQUENCY_KHZ);
EXPECT_NE(freqs.end(), find(freqs.begin(), freqs.end(), freq))
<< "DAB freq " << freq << " kHz is not sent back by callback.";
- ;
}
/**
diff --git a/broadcastradio/common/utilsaidl/Utils.cpp b/broadcastradio/common/utilsaidl/Utils.cpp
index 52c7b40..ad82366 100644
--- a/broadcastradio/common/utilsaidl/Utils.cpp
+++ b/broadcastradio/common/utilsaidl/Utils.cpp
@@ -136,7 +136,9 @@
return getHdSubchannel(b) == 0 &&
haveEqualIds(a, b, IdentifierType::AMFM_FREQUENCY_KHZ);
case IdentifierType::DAB_SID_EXT:
- return haveEqualIds(a, b, IdentifierType::DAB_SID_EXT);
+ return haveEqualIds(a, b, IdentifierType::DAB_SID_EXT) &&
+ haveEqualIds(a, b, IdentifierType::DAB_ENSEMBLE) &&
+ haveEqualIds(a, b, IdentifierType::DAB_FREQUENCY_KHZ);
case IdentifierType::DRMO_SERVICE_ID:
return haveEqualIds(a, b, IdentifierType::DRMO_SERVICE_ID);
case IdentifierType::SXM_SERVICE_ID:
@@ -241,8 +243,8 @@
break;
}
case IdentifierType::DAB_SID_EXT: {
- int64_t sid = val & 0xFFFF; // 16bit
- val >>= 16;
+ int64_t sid = val & 0xFFFFFFFF; // 32bit
+ val >>= 32;
int64_t ecc = val & 0xFF; // 8bit
expect(sid != 0u, "DAB SId != 0");
expect(ecc >= 0xA0u && ecc <= 0xF6u, "Invalid ECC, see ETSI TS 101 756 V2.1.1");
@@ -277,13 +279,35 @@
}
bool isValid(const ProgramSelector& sel) {
- // iterate through primaryId and secondaryIds
- for (auto it = begin(sel); it != end(sel); it++) {
+ if (sel.primaryId.type != IdentifierType::AMFM_FREQUENCY_KHZ &&
+ sel.primaryId.type != IdentifierType::RDS_PI &&
+ sel.primaryId.type != IdentifierType::HD_STATION_ID_EXT &&
+ sel.primaryId.type != IdentifierType::DAB_SID_EXT &&
+ sel.primaryId.type != IdentifierType::DRMO_SERVICE_ID &&
+ sel.primaryId.type != IdentifierType::SXM_SERVICE_ID &&
+ (sel.primaryId.type < IdentifierType::VENDOR_START ||
+ sel.primaryId.type > IdentifierType::VENDOR_END)) {
+ return false;
+ }
+ if (!isValid(sel.primaryId)) {
+ return false;
+ }
+
+ bool isDab = sel.primaryId.type == IdentifierType::DAB_SID_EXT;
+ bool hasDabEnsemble = false;
+ bool hasDabFrequency = false;
+ for (auto it = sel.secondaryIds.begin(); it != sel.secondaryIds.end(); it++) {
if (!isValid(*it)) {
return false;
}
+ if (isDab && it->type == IdentifierType::DAB_ENSEMBLE) {
+ hasDabEnsemble = true;
+ }
+ if (isDab && it->type == IdentifierType::DAB_FREQUENCY_KHZ) {
+ hasDabFrequency = true;
+ }
}
- return true;
+ return !isDab || (hasDabEnsemble && hasDabFrequency);
}
ProgramIdentifier makeIdentifier(IdentifierType type, int64_t value) {
@@ -296,16 +320,12 @@
return sel;
}
-ProgramSelector makeSelectorDab(int32_t sidExt, int32_t ensemble) {
+ProgramSelector makeSelectorDab(int64_t sidExt, int32_t ensemble, int64_t freq) {
ProgramSelector sel = {};
- // TODO(243686545): Have a helper function to create the sidExt instead of
- // passing the whole identifier here. Something like makeDabSidExt.
sel.primaryId = makeIdentifier(IdentifierType::DAB_SID_EXT, sidExt);
vector<ProgramIdentifier> secondaryIds = {
makeIdentifier(IdentifierType::DAB_ENSEMBLE, ensemble),
- // TODO(243686545): Include frequency here when the helper method to
- // translate between ensemble and frequency is implemented.
- };
+ makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, freq)};
sel.secondaryIds = std::move(secondaryIds);
return sel;
}
@@ -330,10 +350,6 @@
}
}
- if (!filter.includeCategories && sel.primaryId.type == IdentifierType::DAB_ENSEMBLE) {
- return false;
- }
-
return true;
}
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
index 8ea6319..beebd03 100644
--- a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
@@ -138,7 +138,7 @@
ProgramIdentifier makeIdentifier(IdentifierType type, int64_t value);
ProgramSelector makeSelectorAmfm(int32_t frequency);
-ProgramSelector makeSelectorDab(int32_t sidExt, int32_t ensemble);
+ProgramSelector makeSelectorDab(int64_t sidExt, int32_t ensemble, int64_t freq);
bool satisfies(const ProgramFilter& filter, const ProgramSelector& sel);
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
index b836dbe..b83eb2b 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -204,6 +204,7 @@
ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION = 851991,
ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED = 851992,
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES = 851994,
+ ANDROID_SCALER_RAW_CROP_REGION = 851995,
ANDROID_SENSOR_EXPOSURE_TIME = 917504,
ANDROID_SENSOR_FRAME_DURATION = 917505,
ANDROID_SENSOR_SENSITIVITY = 917506,
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
index bfa4f1a..958fa12 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
@@ -44,5 +44,6 @@
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 3,
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 4,
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 5,
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW = 6,
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START = 65536,
}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 83e9230..671d69d 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -1284,6 +1284,13 @@
*/
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES = 851994,
/**
+ * android.scaler.rawCropRegion [dynamic, int32[], public]
+ *
+ * <p>The region of the sensor that corresponds to the RAW read out for this
+ * capture when the stream use case of a RAW stream is set to CROPPED_RAW.</p>
+ */
+ ANDROID_SCALER_RAW_CROP_REGION,
+ /**
* android.sensor.exposureTime [dynamic, int64, public]
*
* <p>Duration each pixel is exposed to
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
index daa0fd3..da27a48 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
@@ -35,5 +35,6 @@
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 0x3L,
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 0x4L,
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 0x5L,
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW = 0x6L,
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START = 0x10000L,
}
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index 747ea33..4d4bb26 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -3035,115 +3035,22 @@
}
}
+TEST_P(CameraAidlTest, configureStreamsUseCasesCroppedRaw) {
+ AvailableStream rawStreamThreshold =
+ {INT_MAX, INT_MAX, static_cast<int32_t>(PixelFormat::RAW16)};
+ configureStreamUseCaseInternal(rawStreamThreshold);
+}
+
// Verify that valid stream use cases can be configured successfully, and invalid use cases
// fail stream configuration.
TEST_P(CameraAidlTest, configureStreamsUseCases) {
- std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
-
- for (const auto& name : cameraDeviceNames) {
- CameraMetadata meta;
- std::shared_ptr<ICameraDevice> cameraDevice;
-
- openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
- &cameraDevice /*out*/);
-
- camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
- // Check if camera support depth only
- if (isDepthOnly(staticMeta)) {
- ndk::ScopedAStatus ret = mSession->close();
- mSession = nullptr;
- ASSERT_TRUE(ret.isOk());
- continue;
- }
-
- std::vector<AvailableStream> outputPreviewStreams;
- AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
- static_cast<int32_t>(PixelFormat::YCBCR_420_888)};
- ASSERT_EQ(Status::OK,
- getAvailableOutputStreams(staticMeta, outputPreviewStreams, &previewThreshold));
- ASSERT_NE(0u, outputPreviewStreams.size());
-
- // Combine valid and invalid stream use cases
- std::vector<int64_t> useCases(kMandatoryUseCases);
- useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL + 1);
-
- std::vector<int64_t> supportedUseCases;
- camera_metadata_ro_entry entry;
- auto retcode = find_camera_metadata_ro_entry(
- staticMeta, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, &entry);
- if ((0 == retcode) && (entry.count > 0)) {
- supportedUseCases.insert(supportedUseCases.end(), entry.data.i64,
- entry.data.i64 + entry.count);
- } else {
- supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
- }
-
- std::vector<Stream> streams(1);
- streams[0] = {0,
- StreamType::OUTPUT,
- outputPreviewStreams[0].width,
- outputPreviewStreams[0].height,
- static_cast<PixelFormat>(outputPreviewStreams[0].format),
- static_cast<::aidl::android::hardware::graphics::common::BufferUsage>(
- GRALLOC1_CONSUMER_USAGE_CPU_READ),
- Dataspace::UNKNOWN,
- StreamRotation::ROTATION_0,
- std::string(),
- 0,
- -1,
- {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
- RequestAvailableDynamicRangeProfilesMap::
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
-
- int32_t streamConfigCounter = 0;
- CameraMetadata req;
- StreamConfiguration config;
- RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE;
- ndk::ScopedAStatus ret = mSession->constructDefaultRequestSettings(reqTemplate, &req);
- ASSERT_TRUE(ret.isOk());
- config.sessionParams = req;
-
- for (int64_t useCase : useCases) {
- bool useCaseSupported = std::find(supportedUseCases.begin(), supportedUseCases.end(),
- useCase) != supportedUseCases.end();
-
- streams[0].useCase = static_cast<
- aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases>(
- useCase);
- config.streams = streams;
- config.operationMode = StreamConfigurationMode::NORMAL_MODE;
- config.streamConfigCounter = streamConfigCounter;
- config.multiResolutionInputImage = false;
-
- bool combSupported;
- ret = cameraDevice->isStreamCombinationSupported(config, &combSupported);
- if (static_cast<int32_t>(Status::OPERATION_NOT_SUPPORTED) ==
- ret.getServiceSpecificError()) {
- continue;
- }
-
- ASSERT_TRUE(ret.isOk());
- ASSERT_EQ(combSupported, useCaseSupported);
-
- std::vector<HalStream> halStreams;
- ret = mSession->configureStreams(config, &halStreams);
- ALOGI("configureStreams returns status: %d", ret.getServiceSpecificError());
- if (useCaseSupported) {
- ASSERT_TRUE(ret.isOk());
- ASSERT_EQ(1u, halStreams.size());
- } else {
- ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT),
- ret.getServiceSpecificError());
- }
- }
- ret = mSession->close();
- mSession = nullptr;
- ASSERT_TRUE(ret.isOk());
- }
+ AvailableStream previewStreamThreshold =
+ {kMaxPreviewWidth, kMaxPreviewHeight, static_cast<int32_t>(PixelFormat::YCBCR_420_888)};
+ configureStreamUseCaseInternal(previewStreamThreshold);
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CameraAidlTest);
INSTANTIATE_TEST_SUITE_P(
PerInstance, CameraAidlTest,
testing::ValuesIn(android::getAidlHalInstanceNames(ICameraProvider::descriptor)),
- android::hardware::PrintInstanceNameToString);
\ No newline at end of file
+ android::hardware::PrintInstanceNameToString);
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index b9e30ab..974223d 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -321,8 +321,8 @@
if (entry.data.i64[i] == ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
supportDefaultUseCase = true;
}
- ASSERT_TRUE(entry.data.i64[i] <= ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL ||
- entry.data.i64[i] >=
+ ASSERT_TRUE(entry.data.i64[i] <= ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW
+ || entry.data.i64[i] >=
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START);
}
ASSERT_TRUE(supportDefaultUseCase);
@@ -2164,6 +2164,121 @@
}
}
+void CameraAidlTest::configureStreamUseCaseInternal(const AvailableStream &threshold) {
+ std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+
+ for (const auto& name : cameraDeviceNames) {
+ CameraMetadata meta;
+ std::shared_ptr<ICameraDevice> cameraDevice;
+
+ openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
+ &cameraDevice /*out*/);
+
+ camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
+ // Check if camera support depth only
+ if (isDepthOnly(staticMeta) ||
+ (threshold.format == static_cast<int32_t>(PixelFormat::RAW16) &&
+ !supportsCroppedRawUseCase(staticMeta))) {
+ ndk::ScopedAStatus ret = mSession->close();
+ mSession = nullptr;
+ ASSERT_TRUE(ret.isOk());
+ continue;
+ }
+
+ std::vector<AvailableStream> outputPreviewStreams;
+
+ ASSERT_EQ(Status::OK,
+ getAvailableOutputStreams(staticMeta, outputPreviewStreams, &threshold));
+ ASSERT_NE(0u, outputPreviewStreams.size());
+
+ // Combine valid and invalid stream use cases
+ std::vector<int64_t> useCases(kMandatoryUseCases);
+ useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW + 1);
+
+ std::vector<int64_t> supportedUseCases;
+ if (threshold.format == static_cast<int32_t>(PixelFormat::RAW16)) {
+ // If the format is RAW16, supported use case is only CROPPED_RAW.
+ // All others are unsupported for this format.
+ useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW);
+ supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW);
+ supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ } else {
+ camera_metadata_ro_entry entry;
+ auto retcode = find_camera_metadata_ro_entry(
+ staticMeta, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, &entry);
+ if ((0 == retcode) && (entry.count > 0)) {
+ supportedUseCases.insert(supportedUseCases.end(), entry.data.i64,
+ entry.data.i64 + entry.count);
+ } else {
+ supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ }
+ }
+
+ std::vector<Stream> streams(1);
+ streams[0] = {0,
+ StreamType::OUTPUT,
+ outputPreviewStreams[0].width,
+ outputPreviewStreams[0].height,
+ static_cast<PixelFormat>(outputPreviewStreams[0].format),
+ static_cast<::aidl::android::hardware::graphics::common::BufferUsage>(
+ GRALLOC1_CONSUMER_USAGE_CPU_READ),
+ Dataspace::UNKNOWN,
+ StreamRotation::ROTATION_0,
+ std::string(),
+ 0,
+ -1,
+ {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
+ RequestAvailableDynamicRangeProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
+
+ int32_t streamConfigCounter = 0;
+ CameraMetadata req;
+ StreamConfiguration config;
+ RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE;
+ ndk::ScopedAStatus ret = mSession->constructDefaultRequestSettings(reqTemplate, &req);
+ ASSERT_TRUE(ret.isOk());
+ config.sessionParams = req;
+
+ for (int64_t useCase : useCases) {
+ bool useCaseSupported = std::find(supportedUseCases.begin(), supportedUseCases.end(),
+ useCase) != supportedUseCases.end();
+
+ streams[0].useCase = static_cast<
+ aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases>(
+ useCase);
+ config.streams = streams;
+ config.operationMode = StreamConfigurationMode::NORMAL_MODE;
+ config.streamConfigCounter = streamConfigCounter;
+ config.multiResolutionInputImage = false;
+
+ bool combSupported;
+ ret = cameraDevice->isStreamCombinationSupported(config, &combSupported);
+ if (static_cast<int32_t>(Status::OPERATION_NOT_SUPPORTED) ==
+ ret.getServiceSpecificError()) {
+ continue;
+ }
+
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(combSupported, useCaseSupported);
+
+ std::vector<HalStream> halStreams;
+ ret = mSession->configureStreams(config, &halStreams);
+ ALOGI("configureStreams returns status: %d", ret.getServiceSpecificError());
+ if (useCaseSupported) {
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(1u, halStreams.size());
+ } else {
+ ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT),
+ ret.getServiceSpecificError());
+ }
+ }
+ ret = mSession->close();
+ mSession = nullptr;
+ ASSERT_TRUE(ret.isOk());
+ }
+
+}
+
void CameraAidlTest::configureSingleStream(
const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
const AvailableStream* previewThreshold, uint64_t bufferUsage, RequestTemplate reqTemplate,
@@ -3039,6 +3154,21 @@
return false;
}
+bool CameraAidlTest::supportsCroppedRawUseCase(const camera_metadata_t *staticMeta) {
+ camera_metadata_ro_entry availableStreamUseCasesEntry;
+ int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES,
+ &availableStreamUseCasesEntry);
+ if (rc == 0) {
+ for (size_t i = 0; i < availableStreamUseCasesEntry.count; i++) {
+ if (availableStreamUseCasesEntry.data.i64[i] ==
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
bool CameraAidlTest::isPerFrameControl(const camera_metadata_t* staticMeta) {
camera_metadata_ro_entry syncLatencyEntry;
int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_SYNC_MAX_LATENCY,
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h
index b6e398b..8b8a4bc 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.h
+++ b/camera/provider/aidl/vts/camera_aidl_test.h
@@ -223,6 +223,8 @@
int32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/,
std::shared_ptr<DeviceCb>* cb /*out*/, uint32_t streamConfigCounter = 0);
+ void configureStreamUseCaseInternal(const AvailableStream &threshold);
+
void configureSingleStream(
const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
const AvailableStream* previewThreshold, uint64_t bufferUsage,
@@ -410,6 +412,7 @@
int32_t frameCount, const bool *overrideSequence, const bool *expectedResults);
bool supportZoomSettingsOverride(const camera_metadata_t* staticMeta);
+ bool supportsCroppedRawUseCase(const camera_metadata_t *staticMeta);
bool isPerFrameControl(const camera_metadata_t* staticMeta);
protected:
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index f50a5e7..c88cb59 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -602,10 +602,11 @@
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode())
<< toString(primitive);
- //TODO(b/187207798): revert back to conservative timeout values once
- //latencies have been fixed
- EXPECT_EQ(completionFuture.wait_for(duration * 4), std::future_status::ready)
- << toString(primitive);
+ // TODO(b/261130361): Investigate why latency from driver and hardware will cause test
+ // to fail when wait duration is ~40ms or less.
+ EXPECT_EQ(completionFuture.wait_for(duration + std::chrono::milliseconds(50)),
+ std::future_status::ready)
+ << toString(primitive);
end = high_resolution_clock::now();
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);