Merge "Added SEAT_AIRBAG_ENABLED to hardware layer."
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index 8c32f14..92d7d54 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -23,9 +23,18 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
+aidl_interface_defaults {
+ name: "android.hardware.audio_defaults",
+ host_supported: true,
+ vendor_available: true,
+ stability: "vintf",
+}
+
aidl_interface {
name: "android.hardware.audio.common",
- vendor_available: true,
+ defaults: [
+ "android.hardware.audio_defaults",
+ ],
srcs: [
"android/hardware/audio/common/PlaybackTrackMetadata.aidl",
"android/hardware/audio/common/RecordTrackMetadata.aidl",
@@ -35,7 +44,6 @@
imports: [
"android.media.audio.common.types-V2",
],
- stability: "vintf",
backend: {
cpp: {
enabled: true,
@@ -87,9 +95,18 @@
],
}
+cc_defaults {
+ name: "latest_android_hardware_audio_common_ndk_shared",
+ shared_libs: [
+ latest_android_hardware_audio_common + "-ndk",
+ ],
+}
+
aidl_interface {
name: "android.hardware.audio.core",
- vendor_available: true,
+ defaults: [
+ "android.hardware.audio_defaults",
+ ],
srcs: [
"android/hardware/audio/core/AudioMode.aidl",
"android/hardware/audio/core/AudioPatch.aidl",
@@ -110,7 +127,6 @@
"android.hardware.audio.common-V1",
"android.media.audio.common.types-V2",
],
- stability: "vintf",
backend: {
// The C++ backend is disabled transitively due to use of FMQ.
cpp: {
@@ -148,7 +164,9 @@
aidl_interface {
name: "android.hardware.audio.effect",
- vendor_available: true,
+ defaults: [
+ "android.hardware.audio_defaults",
+ ],
srcs: [
"android/hardware/audio/effect/BassBoost.aidl",
"android/hardware/audio/effect/Capability.aidl",
@@ -177,7 +195,6 @@
"android.hardware.audio.common-V1",
"android.media.audio.common.types-V2",
],
- stability: "vintf",
backend: {
// The C++ backend is disabled transitively due to use of FMQ.
cpp: {
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 0a92e99..2b9ed5b 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -66,6 +66,7 @@
name: "aidlaudioeffectservice_defaults",
defaults: [
"latest_android_media_audio_common_types_ndk_shared",
+ "latest_android_hardware_audio_effect_ndk_shared",
],
vendor: true,
shared_libs: [
@@ -78,7 +79,6 @@
"libutils",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
- "android.hardware.audio.effect-V1-ndk",
],
header_libs: [
"libaudioaidl_headers",
@@ -111,10 +111,11 @@
"libbassboostsw",
"libbundleaidl",
"libdynamicsprocessingsw",
+ "libenvreverbsw",
"libequalizersw",
"libhapticgeneratorsw",
"libloudnessenhancersw",
- "libreverbsw",
+ "libpresetreverbsw",
"libtinyxml2",
"libvirtualizersw",
"libvisualizersw",
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index b6fea27..f4ac8fe 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -34,7 +34,8 @@
<library name="equalizersw" path="libequalizersw.so"/>
<library name="haptic_generatorsw" path="libhapticgeneratorsw.so"/>
<library name="loudness_enhancersw" path="libloudnessenhancersw.so"/>
- <library name="reverbsw" path="libreverbsw.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="volumesw" path="libvolumesw.so"/>
@@ -64,11 +65,12 @@
<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="loudness_enhancer" library="loudness_enhancersw" uuid="fa819610-588b-11ed-9b6a-0242ac120002"/>
- <effect name="reverb" library="reverbsw" uuid="fa8199c6-588b-11ed-9b6a-0242ac120002"/>
+ <effect name="env_reverb" library="env_reverbsw" uuid="fa819886-588b-11ed-9b6a-0242ac120002"/>
+ <effect name="preset_reverb" library="preset_reverbsw" uuid="fa8199c6-588b-11ed-9b6a-0242ac120002"/>
<effect name="virtualizer" library="virtualizersw" uuid="fa819d86-588b-11ed-9b6a-0242ac120002"/>
<effect name="visualizer" library="visualizersw" uuid="fa81a0f6-588b-11ed-9b6a-0242ac120002"/>
<effect name="volume" library="volumesw" uuid="fa81a718-588b-11ed-9b6a-0242ac120002"/>
- <effectProxy name="equalizer" uuid="14804144-a5ee-4d24-aa88-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"/>
</effectProxy>
diff --git a/audio/aidl/default/bassboost/BassBoostSw.cpp b/audio/aidl/default/bassboost/BassBoostSw.cpp
index 3c39824..c52d16f 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.cpp
+++ b/audio/aidl/default/bassboost/BassBoostSw.cpp
@@ -26,14 +26,14 @@
#include "BassBoostSw.h"
using aidl::android::hardware::audio::effect::BassBoostSw;
-using aidl::android::hardware::audio::effect::BassBoostSwImplUUID;
using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kBassBoostSwImplUUID;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
- if (!in_impl_uuid || *in_impl_uuid != BassBoostSwImplUUID) {
+ if (!in_impl_uuid || *in_impl_uuid != kBassBoostSwImplUUID) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
diff --git a/audio/aidl/default/bassboost/BassBoostSw.h b/audio/aidl/default/bassboost/BassBoostSw.h
index fe9c640..90a8887 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.h
+++ b/audio/aidl/default/bassboost/BassBoostSw.h
@@ -39,8 +39,8 @@
public:
BassBoostSw() { LOG(DEBUG) << __func__; }
~BassBoostSw() {
+ cleanUp();
LOG(DEBUG) << __func__;
- releaseContext();
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
@@ -57,13 +57,14 @@
const BassBoost::Capability kCapability;
/* Effect descriptor */
const Descriptor kDescriptor = {
- .common = {.id = {.type = BassBoostTypeUUID,
- .uuid = BassBoostSwImplUUID,
+ .common = {.id = {.type = kBassBoostTypeUUID,
+ .uuid = kBassBoostSwImplUUID,
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
- .name = "BassBoostSw"},
+ .name = "BassBoostSw",
+ .implementor = "The Android Open Source Project"},
.capability = Capability::make<Capability::bassBoost>(kCapability)};
/* parameters */
diff --git a/audio/aidl/default/config/audio_policy_configuration.xsd b/audio/aidl/default/config/audio_policy_configuration.xsd
index 823b217..2c18a1e 100644
--- a/audio/aidl/default/config/audio_policy_configuration.xsd
+++ b/audio/aidl/default/config/audio_policy_configuration.xsd
@@ -424,6 +424,8 @@
<xs:enumeration value="AUDIO_FORMAT_DRA"/>
<xs:enumeration value="AUDIO_FORMAT_APTX_ADAPTIVE_QLEA"/>
<xs:enumeration value="AUDIO_FORMAT_APTX_ADAPTIVE_R4"/>
+ <xs:enumeration value="AUDIO_FORMAT_DTS_HD_MA"/>
+ <xs:enumeration value="AUDIO_FORMAT_DTS_UHD_P2"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="extendableAudioFormat">
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
index 52403e1..3920a58 100644
--- a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
@@ -26,14 +26,14 @@
#include "DynamicsProcessingSw.h"
using aidl::android::hardware::audio::effect::DynamicsProcessingSw;
-using aidl::android::hardware::audio::effect::DynamicsProcessingSwImplUUID;
using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kDynamicsProcessingSwImplUUID;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
- if (!in_impl_uuid || *in_impl_uuid != DynamicsProcessingSwImplUUID) {
+ if (!in_impl_uuid || *in_impl_uuid != kDynamicsProcessingSwImplUUID) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
index fc26902..2bc2762 100644
--- a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
@@ -39,8 +39,8 @@
public:
DynamicsProcessingSw() { LOG(DEBUG) << __func__; }
~DynamicsProcessingSw() {
+ cleanUp();
LOG(DEBUG) << __func__;
- releaseContext();
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
@@ -57,13 +57,14 @@
const DynamicsProcessing::Capability kCapability;
/* Effect descriptor */
const Descriptor kDescriptor = {
- .common = {.id = {.type = DynamicsProcessingTypeUUID,
- .uuid = DynamicsProcessingSwImplUUID,
+ .common = {.id = {.type = kDynamicsProcessingTypeUUID,
+ .uuid = kDynamicsProcessingSwImplUUID,
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
- .name = "DynamicsProcessingSw"},
+ .name = "DynamicsProcessingSw",
+ .implementor = "The Android Open Source Project"},
.capability = Capability::make<Capability::dynamicsProcessing>(kCapability)};
/* parameters */
diff --git a/audio/aidl/default/reverb/Android.bp b/audio/aidl/default/envReverb/Android.bp
similarity index 95%
copy from audio/aidl/default/reverb/Android.bp
copy to audio/aidl/default/envReverb/Android.bp
index 955038c..c239ee5 100644
--- a/audio/aidl/default/reverb/Android.bp
+++ b/audio/aidl/default/envReverb/Android.bp
@@ -24,14 +24,14 @@
}
cc_library_shared {
- name: "libreverbsw",
+ name: "libenvreverbsw",
defaults: [
"aidlaudioeffectservice_defaults",
"latest_android_media_audio_common_types_ndk_shared",
"latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
- "ReverbSw.cpp",
+ "EnvReverbSw.cpp",
":effectCommonFile",
],
visibility: [
diff --git a/audio/aidl/default/reverb/ReverbSw.cpp b/audio/aidl/default/envReverb/EnvReverbSw.cpp
similarity index 77%
copy from audio/aidl/default/reverb/ReverbSw.cpp
copy to audio/aidl/default/envReverb/EnvReverbSw.cpp
index 639f1a2..ad447ab 100644
--- a/audio/aidl/default/reverb/ReverbSw.cpp
+++ b/audio/aidl/default/envReverb/EnvReverbSw.cpp
@@ -15,7 +15,7 @@
*/
#include <cstddef>
-#define LOG_TAG "AHAL_ReverbSw"
+#define LOG_TAG "AHAL_EnvReverbSw"
#include <Utils.h>
#include <algorithm>
#include <unordered_set>
@@ -23,22 +23,22 @@
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
-#include "ReverbSw.h"
+#include "EnvReverbSw.h"
+using aidl::android::hardware::audio::effect::EnvReverbSw;
using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::ReverbSw;
-using aidl::android::hardware::audio::effect::ReverbSwImplUUID;
+using aidl::android::hardware::audio::effect::kEnvReverbSwImplUUID;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
- if (!in_impl_uuid || *in_impl_uuid != ReverbSwImplUUID) {
+ if (!in_impl_uuid || *in_impl_uuid != kEnvReverbSwImplUUID) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
- *instanceSpp = ndk::SharedRefBase::make<ReverbSw>();
+ *instanceSpp = ndk::SharedRefBase::make<EnvReverbSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
@@ -64,13 +64,13 @@
namespace aidl::android::hardware::audio::effect {
-ndk::ScopedAStatus ReverbSw::getDescriptor(Descriptor* _aidl_return) {
+ndk::ScopedAStatus EnvReverbSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus ReverbSw::setParameterSpecific(const Parameter::Specific& specific) {
+ndk::ScopedAStatus EnvReverbSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::reverb != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
std::lock_guard lg(mMutex);
@@ -81,24 +81,24 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus ReverbSw::getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) {
+ndk::ScopedAStatus EnvReverbSw::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::reverbTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
specific->set<Parameter::Specific::reverb>(mSpecificParam);
return ndk::ScopedAStatus::ok();
}
-std::shared_ptr<EffectContext> ReverbSw::createContext(const Parameter::Common& common) {
+std::shared_ptr<EffectContext> EnvReverbSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
return mContext;
}
- mContext = std::make_shared<ReverbSwContext>(1 /* statusFmqDepth */, common);
+ mContext = std::make_shared<EnvReverbSwContext>(1 /* statusFmqDepth */, common);
return mContext;
}
-RetCode ReverbSw::releaseContext() {
+RetCode EnvReverbSw::releaseContext() {
if (mContext) {
mContext.reset();
}
@@ -106,7 +106,7 @@
}
// Processing method running in EffectWorker thread.
-IEffect::Status ReverbSw::effectProcessImpl(float* in, float* out, int process) {
+IEffect::Status EnvReverbSw::effectProcessImpl(float* in, float* out, int process) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " process " << process;
for (int i = 0; i < process; i++) {
diff --git a/audio/aidl/default/reverb/ReverbSw.h b/audio/aidl/default/envReverb/EnvReverbSw.h
similarity index 79%
rename from audio/aidl/default/reverb/ReverbSw.h
rename to audio/aidl/default/envReverb/EnvReverbSw.h
index e00956f..5a9ab27 100644
--- a/audio/aidl/default/reverb/ReverbSw.h
+++ b/audio/aidl/default/envReverb/EnvReverbSw.h
@@ -26,21 +26,21 @@
namespace aidl::android::hardware::audio::effect {
-class ReverbSwContext final : public EffectContext {
+class EnvReverbSwContext final : public EffectContext {
public:
- ReverbSwContext(int statusDepth, const Parameter::Common& common)
+ EnvReverbSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
// TODO: add specific context here
};
-class ReverbSw final : public EffectImpl {
+class EnvReverbSw final : public EffectImpl {
public:
- ReverbSw() { LOG(DEBUG) << __func__; }
- ~ReverbSw() {
+ EnvReverbSw() { LOG(DEBUG) << __func__; }
+ ~EnvReverbSw() {
+ cleanUp();
LOG(DEBUG) << __func__;
- releaseContext();
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
@@ -52,18 +52,19 @@
RetCode releaseContext() override;
private:
- std::shared_ptr<ReverbSwContext> mContext;
+ std::shared_ptr<EnvReverbSwContext> mContext;
/* capabilities */
const Reverb::Capability kCapability;
/* Effect descriptor */
const Descriptor kDescriptor = {
- .common = {.id = {.type = ReverbTypeUUID,
- .uuid = ReverbSwImplUUID,
+ .common = {.id = {.type = kEnvReverbTypeUUID,
+ .uuid = kEnvReverbSwImplUUID,
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
- .name = "ReverbSw"},
+ .name = "EnvReverbSw",
+ .implementor = "The Android Open Source Project"},
.capability = Capability::make<Capability::reverb>(kCapability)};
/* parameters */
diff --git a/audio/aidl/default/equalizer/EqualizerSw.cpp b/audio/aidl/default/equalizer/EqualizerSw.cpp
index 32c3969..d61ef97 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.cpp
+++ b/audio/aidl/default/equalizer/EqualizerSw.cpp
@@ -26,14 +26,14 @@
#include "EqualizerSw.h"
using aidl::android::hardware::audio::effect::EqualizerSw;
-using aidl::android::hardware::audio::effect::EqualizerSwImplUUID;
using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kEqualizerSwImplUUID;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
- if (!in_impl_uuid || *in_impl_uuid != EqualizerSwImplUUID) {
+ if (!in_impl_uuid || *in_impl_uuid != kEqualizerSwImplUUID) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
diff --git a/audio/aidl/default/equalizer/EqualizerSw.h b/audio/aidl/default/equalizer/EqualizerSw.h
index 8762f5d..aa4587a 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.h
+++ b/audio/aidl/default/equalizer/EqualizerSw.h
@@ -82,8 +82,8 @@
public:
EqualizerSw() { LOG(DEBUG) << __func__; }
~EqualizerSw() {
+ cleanUp();
LOG(DEBUG) << __func__;
- releaseContext();
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
@@ -109,13 +109,14 @@
const Equalizer::Capability kEqCap = {.bandFrequencies = mBandFrequency, .presets = mPresets};
// Effect descriptor.
- const Descriptor kDesc = {.common = {.id = {.type = EqualizerTypeUUID,
- .uuid = EqualizerSwImplUUID,
- .proxy = std::nullopt},
+ const Descriptor kDesc = {.common = {.id = {.type = kEqualizerTypeUUID,
+ .uuid = kEqualizerSwImplUUID,
+ .proxy = kEqualizerProxyUUID},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
- .name = "EqualizerSw"},
+ .name = "EqualizerSw",
+ .implementor = "The Android Open Source Project"},
.capability = Capability::make<Capability::equalizer>(kEqCap)};
ndk::ScopedAStatus getParameterEqualizer(const Equalizer::Tag& tag,
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
index 90675c2..fd5ea34 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
@@ -26,14 +26,14 @@
#include "HapticGeneratorSw.h"
using aidl::android::hardware::audio::effect::HapticGeneratorSw;
-using aidl::android::hardware::audio::effect::HapticGeneratorSwImplUUID;
using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kHapticGeneratorSwImplUUID;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
- if (!in_impl_uuid || *in_impl_uuid != HapticGeneratorSwImplUUID) {
+ if (!in_impl_uuid || *in_impl_uuid != kHapticGeneratorSwImplUUID) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
index b5a5036..518aa87 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
@@ -39,8 +39,8 @@
public:
HapticGeneratorSw() { LOG(DEBUG) << __func__; }
~HapticGeneratorSw() {
+ cleanUp();
LOG(DEBUG) << __func__;
- releaseContext();
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
@@ -57,13 +57,14 @@
const HapticGenerator::Capability kCapability;
/* Effect descriptor */
const Descriptor kDescriptor = {
- .common = {.id = {.type = HapticGeneratorTypeUUID,
- .uuid = HapticGeneratorSwImplUUID,
+ .common = {.id = {.type = kHapticGeneratorTypeUUID,
+ .uuid = kHapticGeneratorSwImplUUID,
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
- .name = "HapticGeneratorSw"},
+ .name = "HapticGeneratorSw",
+ .implementor = "The Android Open Source Project"},
.capability = Capability::make<Capability::hapticGenerator>(kCapability)};
/* parameters */
diff --git a/audio/aidl/default/include/effect-impl/EffectImpl.h b/audio/aidl/default/include/effect-impl/EffectImpl.h
index cb395b7..d9825da 100644
--- a/audio/aidl/default/include/effect-impl/EffectImpl.h
+++ b/audio/aidl/default/include/effect-impl/EffectImpl.h
@@ -30,11 +30,8 @@
class EffectImpl : public BnEffect, public EffectWorker {
public:
- EffectImpl() { LOG(DEBUG) << __func__; }
- ~EffectImpl() {
- cleanUp();
- LOG(DEBUG) << __func__;
- }
+ EffectImpl() = default;
+ virtual ~EffectImpl() = default;
/**
* Each effect implementation CAN override these methods if necessary
@@ -78,9 +75,9 @@
State mState GUARDED_BY(mMutex) = State::INIT;
IEffect::Status status(binder_status_t status, size_t consumed, size_t produced);
+ void cleanUp();
private:
- void cleanUp();
std::shared_ptr<EffectContext> mContext GUARDED_BY(mMutex);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectUUID.h b/audio/aidl/default/include/effect-impl/EffectUUID.h
index 184a587..7709eab 100644
--- a/audio/aidl/default/include/effect-impl/EffectUUID.h
+++ b/audio/aidl/default/include/effect-impl/EffectUUID.h
@@ -23,150 +23,160 @@
using ::aidl::android::media::audio::common::AudioUuid;
-// Null UUID
-static const AudioUuid EffectNullUuid = {static_cast<int32_t>(0xec7178ec),
- 0xe5e1,
- 0x4432,
- 0xa3f4,
- {0x46, 0x57, 0xe6, 0x79, 0x52, 0x10}};
-
+// ec7178ec-e5e1-4432-a3f4-4657e6795210
+static const AudioUuid kEffectNullUuid = {static_cast<int32_t>(0xec7178ec),
+ 0xe5e1,
+ 0x4432,
+ 0xa3f4,
+ {0x46, 0x57, 0xe6, 0x79, 0x52, 0x10}};
// Zero UUID
-static const AudioUuid EffectZeroUuid = {
+static const AudioUuid kEffectZeroUuid = {
static_cast<int32_t>(0x0), 0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
-// Equalizer type UUID.
-static const AudioUuid EqualizerTypeUUID = {static_cast<int32_t>(0x0bed4300),
- 0xddd6,
- 0x11db,
- 0x8f34,
- {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-
-// 0bed4300-847d-11df-bb17-0002a5d5c51b
-static const AudioUuid EqualizerSwImplUUID = {static_cast<int32_t>(0x0bed4300),
- 0x847d,
- 0x11df,
- 0xbb17,
- {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-
-// ce772f20-847d-11df-bb17-0002a5d5c51b
-static const AudioUuid EqualizerBundleImplUUID = {static_cast<int32_t>(0xce772f20),
- 0x847d,
- 0x11df,
- 0xbb17,
- {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-
-// fa8184a4-588b-11ed-9b6a-0242ac120002
-static const AudioUuid BassBoostTypeUUID = {static_cast<int32_t>(0xfa8184a4),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// 0634f220-ddd4-11db-a0fc-0002a5d5c51b
+static const AudioUuid kBassBoostTypeUUID = {static_cast<int32_t>(0x0634f220),
+ 0xddd4,
+ 0x11db,
+ 0xa0fc,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
// fa8181f2-588b-11ed-9b6a-0242ac120002
-static const AudioUuid BassBoostSwImplUUID = {static_cast<int32_t>(0xfa8181f2),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa81862a-588b-11ed-9b6a-0242ac120002
-static const AudioUuid DownmixTypeUUID = {static_cast<int32_t>(0xfa81862a),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa8187ba-588b-11ed-9b6a-0242ac120002
-static const AudioUuid DownmixSwImplUUID = {static_cast<int32_t>(0xfa8187ba),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa818954-588b-11ed-9b6a-0242ac120002
-static const AudioUuid DynamicsProcessingTypeUUID = {static_cast<int32_t>(0xfa818954),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa818d78-588b-11ed-9b6a-0242ac120002
-static const AudioUuid DynamicsProcessingSwImplUUID = {static_cast<int32_t>(0xfa818d78),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa818f62-588b-11ed-9b6a-0242ac120002
-static const AudioUuid HapticGeneratorTypeUUID = {static_cast<int32_t>(0xfa818f62),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa819110-588b-11ed-9b6a-0242ac120002
-static const AudioUuid HapticGeneratorSwImplUUID = {static_cast<int32_t>(0xfa819110),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-
-// fa8194a8-588b-11ed-9b6a-0242ac120002
-static const AudioUuid LoudnessEnhancerTypeUUID = {static_cast<int32_t>(0xfa8194a8),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa819610-588b-11ed-9b6a-0242ac120002
-static const AudioUuid LoudnessEnhancerSwImplUUID = {static_cast<int32_t>(0xfa819610),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa819886-588b-11ed-9b6a-0242ac120002
-static const AudioUuid ReverbTypeUUID = {static_cast<int32_t>(0xfa819886),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa8199c6-588b-11ed-9b6a-0242ac120002
-static const AudioUuid ReverbSwImplUUID = {static_cast<int32_t>(0xfa8199c6),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-
-// fa819af2-588b-11ed-9b6a-0242ac120002
-static const AudioUuid VirtualizerTypeUUID = {static_cast<int32_t>(0xfa819af2),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa819d86-588b-11ed-9b6a-0242ac120002
-static const AudioUuid VirtualizerSwImplUUID = {static_cast<int32_t>(0xfa819d86),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-
-// fa819f3e-588b-11ed-9b6a-0242ac120002
-static const AudioUuid VisualizerTypeUUID = {static_cast<int32_t>(0xfa819f3e),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa81a0f6-588b-11ed-9b6a-0242ac120002
-static const AudioUuid VisualizerSwImplUUID = {static_cast<int32_t>(0xfa81a0f6),
+static const AudioUuid kBassBoostSwImplUUID = {static_cast<int32_t>(0xfa8181f2),
0x588b,
0x11ed,
0x9b6a,
{0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-
-// fa81a2b8-588b-11ed-9b6a-0242ac120002
-static const AudioUuid VolumeTypeUUID = {static_cast<int32_t>(0xfa81a2b8),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
-// fa81a718-588b-11ed-9b6a-0242ac120002
-static const AudioUuid VolumeSwImplUUID = {static_cast<int32_t>(0xfa81a718),
+// fa81862a-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kDownmixTypeUUID = {static_cast<int32_t>(0xfa81862a),
0x588b,
0x11ed,
0x9b6a,
{0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// fa8187ba-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kDownmixSwImplUUID = {static_cast<int32_t>(0xfa8187ba),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// 0bed4300-ddd6-11db-8f34-0002a5d5c51b.
+static const AudioUuid kEqualizerTypeUUID = {static_cast<int32_t>(0x0bed4300),
+ 0xddd6,
+ 0x11db,
+ 0x8f34,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 0bed4300-847d-11df-bb17-0002a5d5c51b
+static const AudioUuid kEqualizerSwImplUUID = {static_cast<int32_t>(0x0bed4300),
+ 0x847d,
+ 0x11df,
+ 0xbb17,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// ce772f20-847d-11df-bb17-0002a5d5c51b
+static const AudioUuid kEqualizerBundleImplUUID = {static_cast<int32_t>(0xce772f20),
+ 0x847d,
+ 0x11df,
+ 0xbb17,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// c8e70ecd-48ca-456e-8a4f-0002a5d5c51b
+static const AudioUuid kEqualizerProxyUUID = {static_cast<int32_t>(0xc8e70ecd),
+ 0x48ca,
+ 0x456e,
+ 0x8a4f,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// 7261676f-6d75-7369-6364-28e2fd3ac39e
+static const AudioUuid kDynamicsProcessingTypeUUID = {static_cast<int32_t>(0x7261676f),
+ 0x6d75,
+ 0x7369,
+ 0x6364,
+ {0x28, 0xe2, 0xfd, 0x3a, 0xc3, 0x9e}};
+// fa818d78-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kDynamicsProcessingSwImplUUID = {static_cast<int32_t>(0xfa818d78),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// 1411e6d6-aecd-4021-a1cf-a6aceb0d71e5
+static const AudioUuid kHapticGeneratorTypeUUID = {static_cast<int32_t>(0x1411e6d6),
+ 0xaecd,
+ 0x4021,
+ 0xa1cf,
+ {0xa6, 0xac, 0xeb, 0x0d, 0x71, 0xe5}};
+// fa819110-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kHapticGeneratorSwImplUUID = {static_cast<int32_t>(0xfa819110),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// fe3199be-aed0-413f-87bb-11260eb63cf1
+static const AudioUuid kLoudnessEnhancerTypeUUID = {static_cast<int32_t>(0xfe3199be),
+ 0xaed0,
+ 0x413f,
+ 0x87bb,
+ {0x11, 0x26, 0x0e, 0xb6, 0x3c, 0xf1}};
+// fa819610-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kLoudnessEnhancerSwImplUUID = {static_cast<int32_t>(0xfa819610),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// c2e5d5f0-94bd-4763-9cac-4e234d06839e
+static const AudioUuid kEnvReverbTypeUUID = {static_cast<int32_t>(0xc2e5d5f0),
+ 0x94bd,
+ 0x4763,
+ 0x9cac,
+ {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}};
+// fa819886-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kEnvReverbSwImplUUID = {static_cast<int32_t>(0xfa819886),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// 47382d60-ddd8-11db-bf3a-0002a5d5c51b
+static const AudioUuid kPresetReverbTypeUUID = {static_cast<int32_t>(0x47382d60),
+ 0xddd8,
+ 0x11db,
+ 0xbf3a,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// fa8199c6-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kPresetReverbSwImplUUID = {static_cast<int32_t>(0xfa8199c6),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// 37cc2c00-dddd-11db-8577-0002a5d5c51b
+static const AudioUuid kVirtualizerTypeUUID = {static_cast<int32_t>(0x37cc2c00),
+ 0xdddd,
+ 0x11db,
+ 0x8577,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// fa819d86-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kVirtualizerSwImplUUID = {static_cast<int32_t>(0xfa819d86),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// fa819f3e-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kVisualizerTypeUUID = {static_cast<int32_t>(0xfa819f3e),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// fa81a0f6-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kVisualizerSwImplUUID = {static_cast<int32_t>(0xfa81a0f6),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// fa81a2b8-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kVolumeTypeUUID = {static_cast<int32_t>(0xfa81a2b8),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// fa81a718-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kVolumeSwImplUUID = {static_cast<int32_t>(0xfa81a718),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
/**
* @brief A map between effect name and effect type UUID.
@@ -174,20 +184,21 @@
* We need this map is because existing audio_effects.xml don't have a type UUID defined.
*/
static const std::map<const std::string /* effect type */, const AudioUuid&> kUuidNameTypeMap = {
- {"bassboost", BassBoostTypeUUID},
- {"downmix", DownmixTypeUUID},
- {"dynamics_processing", DynamicsProcessingTypeUUID},
- {"equalizer", EqualizerTypeUUID},
- {"haptic_generator", HapticGeneratorTypeUUID},
- {"loudness_enhancer", LoudnessEnhancerTypeUUID},
- {"reverb", ReverbTypeUUID},
- {"reverb_env_aux", ReverbTypeUUID},
- {"reverb_env_ins", ReverbTypeUUID},
- {"reverb_pre_aux", ReverbTypeUUID},
- {"reverb_pre_ins", ReverbTypeUUID},
- {"virtualizer", VirtualizerTypeUUID},
- {"visualizer", VisualizerTypeUUID},
- {"volume", VolumeTypeUUID},
+ {"bassboost", kBassBoostTypeUUID},
+ {"downmix", kDownmixTypeUUID},
+ {"dynamics_processing", kDynamicsProcessingTypeUUID},
+ {"equalizer", kEqualizerTypeUUID},
+ {"haptic_generator", kHapticGeneratorTypeUUID},
+ {"loudness_enhancer", kLoudnessEnhancerTypeUUID},
+ {"env_reverb", kEnvReverbTypeUUID},
+ {"preset_reverb", kPresetReverbTypeUUID},
+ {"reverb_env_aux", kEnvReverbTypeUUID},
+ {"reverb_env_ins", kEnvReverbTypeUUID},
+ {"reverb_pre_aux", kPresetReverbTypeUUID},
+ {"reverb_pre_ins", kPresetReverbTypeUUID},
+ {"virtualizer", kVirtualizerTypeUUID},
+ {"visualizer", kVisualizerTypeUUID},
+ {"volume", kVolumeTypeUUID},
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
index 27b9169..9d2b978 100644
--- a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
@@ -26,14 +26,14 @@
#include "LoudnessEnhancerSw.h"
using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kLoudnessEnhancerSwImplUUID;
using aidl::android::hardware::audio::effect::LoudnessEnhancerSw;
-using aidl::android::hardware::audio::effect::LoudnessEnhancerSwImplUUID;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
- if (!in_impl_uuid || *in_impl_uuid != LoudnessEnhancerSwImplUUID) {
+ if (!in_impl_uuid || *in_impl_uuid != kLoudnessEnhancerSwImplUUID) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
index 478aebc..856bf0b 100644
--- a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
@@ -48,8 +48,8 @@
public:
LoudnessEnhancerSw() { LOG(DEBUG) << __func__; }
~LoudnessEnhancerSw() {
+ cleanUp();
LOG(DEBUG) << __func__;
- releaseContext();
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
@@ -66,13 +66,14 @@
const LoudnessEnhancer::Capability kCapability;
/* Effect descriptor */
const Descriptor kDescriptor = {
- .common = {.id = {.type = LoudnessEnhancerTypeUUID,
- .uuid = LoudnessEnhancerSwImplUUID,
+ .common = {.id = {.type = kLoudnessEnhancerTypeUUID,
+ .uuid = kLoudnessEnhancerSwImplUUID,
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
- .name = "LoudnessEnhancerSw"},
+ .name = "LoudnessEnhancerSw",
+ .implementor = "The Android Open Source Project"},
.capability = Capability::make<Capability::loudnessEnhancer>(kCapability)};
ndk::ScopedAStatus getParameterLoudnessEnhancer(const LoudnessEnhancer::Tag& tag,
diff --git a/audio/aidl/default/reverb/Android.bp b/audio/aidl/default/presetReverb/Android.bp
similarity index 95%
rename from audio/aidl/default/reverb/Android.bp
rename to audio/aidl/default/presetReverb/Android.bp
index 955038c..4148511 100644
--- a/audio/aidl/default/reverb/Android.bp
+++ b/audio/aidl/default/presetReverb/Android.bp
@@ -24,14 +24,14 @@
}
cc_library_shared {
- name: "libreverbsw",
+ name: "libpresetreverbsw",
defaults: [
"aidlaudioeffectservice_defaults",
"latest_android_media_audio_common_types_ndk_shared",
"latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
- "ReverbSw.cpp",
+ "PresetReverbSw.cpp",
":effectCommonFile",
],
visibility: [
diff --git a/audio/aidl/default/reverb/ReverbSw.cpp b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
similarity index 77%
rename from audio/aidl/default/reverb/ReverbSw.cpp
rename to audio/aidl/default/presetReverb/PresetReverbSw.cpp
index 639f1a2..069d0ff 100644
--- a/audio/aidl/default/reverb/ReverbSw.cpp
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
@@ -15,7 +15,7 @@
*/
#include <cstddef>
-#define LOG_TAG "AHAL_ReverbSw"
+#define LOG_TAG "AHAL_PresetReverbSw"
#include <Utils.h>
#include <algorithm>
#include <unordered_set>
@@ -23,22 +23,22 @@
#include <android-base/logging.h>
#include <fmq/AidlMessageQueue.h>
-#include "ReverbSw.h"
+#include "PresetReverbSw.h"
using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::ReverbSw;
-using aidl::android::hardware::audio::effect::ReverbSwImplUUID;
+using aidl::android::hardware::audio::effect::kPresetReverbSwImplUUID;
+using aidl::android::hardware::audio::effect::PresetReverbSw;
using aidl::android::hardware::audio::effect::State;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
- if (!in_impl_uuid || *in_impl_uuid != ReverbSwImplUUID) {
+ if (!in_impl_uuid || *in_impl_uuid != kPresetReverbSwImplUUID) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
if (instanceSpp) {
- *instanceSpp = ndk::SharedRefBase::make<ReverbSw>();
+ *instanceSpp = ndk::SharedRefBase::make<PresetReverbSw>();
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
return EX_NONE;
} else {
@@ -64,13 +64,13 @@
namespace aidl::android::hardware::audio::effect {
-ndk::ScopedAStatus ReverbSw::getDescriptor(Descriptor* _aidl_return) {
+ndk::ScopedAStatus PresetReverbSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
*_aidl_return = kDescriptor;
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus ReverbSw::setParameterSpecific(const Parameter::Specific& specific) {
+ndk::ScopedAStatus PresetReverbSw::setParameterSpecific(const Parameter::Specific& specific) {
RETURN_IF(Parameter::Specific::reverb != specific.getTag(), EX_ILLEGAL_ARGUMENT,
"EffectNotSupported");
std::lock_guard lg(mMutex);
@@ -81,24 +81,24 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus ReverbSw::getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) {
+ndk::ScopedAStatus PresetReverbSw::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::reverbTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
specific->set<Parameter::Specific::reverb>(mSpecificParam);
return ndk::ScopedAStatus::ok();
}
-std::shared_ptr<EffectContext> ReverbSw::createContext(const Parameter::Common& common) {
+std::shared_ptr<EffectContext> PresetReverbSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
return mContext;
}
- mContext = std::make_shared<ReverbSwContext>(1 /* statusFmqDepth */, common);
+ mContext = std::make_shared<PresetReverbSwContext>(1 /* statusFmqDepth */, common);
return mContext;
}
-RetCode ReverbSw::releaseContext() {
+RetCode PresetReverbSw::releaseContext() {
if (mContext) {
mContext.reset();
}
@@ -106,7 +106,7 @@
}
// Processing method running in EffectWorker thread.
-IEffect::Status ReverbSw::effectProcessImpl(float* in, float* out, int process) {
+IEffect::Status PresetReverbSw::effectProcessImpl(float* in, float* out, int process) {
// TODO: get data buffer and process.
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " process " << process;
for (int i = 0; i < process; i++) {
diff --git a/audio/aidl/default/reverb/ReverbSw.h b/audio/aidl/default/presetReverb/PresetReverbSw.h
similarity index 78%
copy from audio/aidl/default/reverb/ReverbSw.h
copy to audio/aidl/default/presetReverb/PresetReverbSw.h
index e00956f..75a5a94 100644
--- a/audio/aidl/default/reverb/ReverbSw.h
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.h
@@ -26,21 +26,21 @@
namespace aidl::android::hardware::audio::effect {
-class ReverbSwContext final : public EffectContext {
+class PresetReverbSwContext final : public EffectContext {
public:
- ReverbSwContext(int statusDepth, const Parameter::Common& common)
+ PresetReverbSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
// TODO: add specific context here
};
-class ReverbSw final : public EffectImpl {
+class PresetReverbSw final : public EffectImpl {
public:
- ReverbSw() { LOG(DEBUG) << __func__; }
- ~ReverbSw() {
+ PresetReverbSw() { LOG(DEBUG) << __func__; }
+ ~PresetReverbSw() {
+ cleanUp();
LOG(DEBUG) << __func__;
- releaseContext();
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
@@ -52,18 +52,19 @@
RetCode releaseContext() override;
private:
- std::shared_ptr<ReverbSwContext> mContext;
+ std::shared_ptr<PresetReverbSwContext> mContext;
/* capabilities */
const Reverb::Capability kCapability;
/* Effect descriptor */
const Descriptor kDescriptor = {
- .common = {.id = {.type = ReverbTypeUUID,
- .uuid = ReverbSwImplUUID,
+ .common = {.id = {.type = kPresetReverbTypeUUID,
+ .uuid = kPresetReverbSwImplUUID,
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
- .name = "ReverbSw"},
+ .name = "PresetReverbSw",
+ .implementor = "The Android Open Source Project"},
.capability = Capability::make<Capability::reverb>(kCapability)};
/* parameters */
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.cpp b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
index ccb7b4b..9688fc8 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.cpp
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
@@ -26,14 +26,14 @@
#include "VirtualizerSw.h"
using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kVirtualizerSwImplUUID;
using aidl::android::hardware::audio::effect::State;
using aidl::android::hardware::audio::effect::VirtualizerSw;
-using aidl::android::hardware::audio::effect::VirtualizerSwImplUUID;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
- if (!in_impl_uuid || *in_impl_uuid != VirtualizerSwImplUUID) {
+ if (!in_impl_uuid || *in_impl_uuid != kVirtualizerSwImplUUID) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.h b/audio/aidl/default/virtualizer/VirtualizerSw.h
index da1998b..e4de8b3 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.h
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.h
@@ -39,8 +39,8 @@
public:
VirtualizerSw() { LOG(DEBUG) << __func__; }
~VirtualizerSw() {
+ cleanUp();
LOG(DEBUG) << __func__;
- releaseContext();
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
@@ -57,13 +57,14 @@
const Virtualizer::Capability kCapability;
/* Effect descriptor */
const Descriptor kDescriptor = {
- .common = {.id = {.type = VirtualizerTypeUUID,
- .uuid = VirtualizerSwImplUUID,
+ .common = {.id = {.type = kVirtualizerTypeUUID,
+ .uuid = kVirtualizerSwImplUUID,
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
- .name = "VirtualizerSw"},
+ .name = "VirtualizerSw",
+ .implementor = "The Android Open Source Project"},
.capability = Capability::make<Capability::virtualizer>(kCapability)};
/* parameters */
diff --git a/audio/aidl/default/visualizer/VisualizerSw.cpp b/audio/aidl/default/visualizer/VisualizerSw.cpp
index 5a24f18..24a7bef 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.cpp
+++ b/audio/aidl/default/visualizer/VisualizerSw.cpp
@@ -26,14 +26,14 @@
#include "VisualizerSw.h"
using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kVisualizerSwImplUUID;
using aidl::android::hardware::audio::effect::State;
using aidl::android::hardware::audio::effect::VisualizerSw;
-using aidl::android::hardware::audio::effect::VisualizerSwImplUUID;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
- if (!in_impl_uuid || *in_impl_uuid != VisualizerSwImplUUID) {
+ if (!in_impl_uuid || *in_impl_uuid != kVisualizerSwImplUUID) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
diff --git a/audio/aidl/default/visualizer/VisualizerSw.h b/audio/aidl/default/visualizer/VisualizerSw.h
index 21101dd..bccd6e9 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.h
+++ b/audio/aidl/default/visualizer/VisualizerSw.h
@@ -39,8 +39,8 @@
public:
VisualizerSw() { LOG(DEBUG) << __func__; }
~VisualizerSw() {
+ cleanUp();
LOG(DEBUG) << __func__;
- releaseContext();
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
@@ -57,13 +57,14 @@
const Visualizer::Capability kCapability;
/* Effect descriptor */
const Descriptor kDescriptor = {
- .common = {.id = {.type = VisualizerTypeUUID,
- .uuid = VisualizerSwImplUUID,
+ .common = {.id = {.type = kVisualizerTypeUUID,
+ .uuid = kVisualizerSwImplUUID,
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
- .name = "VisualizerSw"},
+ .name = "VisualizerSw",
+ .implementor = "The Android Open Source Project"},
.capability = Capability::make<Capability::visualizer>(kCapability)};
/* parameters */
diff --git a/audio/aidl/default/volume/VolumeSw.cpp b/audio/aidl/default/volume/VolumeSw.cpp
index e2f42d7..b8af921 100644
--- a/audio/aidl/default/volume/VolumeSw.cpp
+++ b/audio/aidl/default/volume/VolumeSw.cpp
@@ -26,14 +26,14 @@
#include "VolumeSw.h"
using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kVolumeSwImplUUID;
using aidl::android::hardware::audio::effect::State;
using aidl::android::hardware::audio::effect::VolumeSw;
-using aidl::android::hardware::audio::effect::VolumeSwImplUUID;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
std::shared_ptr<IEffect>* instanceSpp) {
- if (!in_impl_uuid || *in_impl_uuid != VolumeSwImplUUID) {
+ if (!in_impl_uuid || *in_impl_uuid != kVolumeSwImplUUID) {
LOG(ERROR) << __func__ << "uuid not supported";
return EX_ILLEGAL_ARGUMENT;
}
diff --git a/audio/aidl/default/volume/VolumeSw.h b/audio/aidl/default/volume/VolumeSw.h
index e46c864..86e01c1 100644
--- a/audio/aidl/default/volume/VolumeSw.h
+++ b/audio/aidl/default/volume/VolumeSw.h
@@ -39,8 +39,8 @@
public:
VolumeSw() { LOG(DEBUG) << __func__; }
~VolumeSw() {
+ cleanUp();
LOG(DEBUG) << __func__;
- releaseContext();
}
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
@@ -57,13 +57,14 @@
const Volume::Capability kCapability;
/* Effect descriptor */
const Descriptor kDescriptor = {
- .common = {.id = {.type = VolumeTypeUUID,
- .uuid = VolumeSwImplUUID,
+ .common = {.id = {.type = kVolumeTypeUUID,
+ .uuid = kVolumeSwImplUUID,
.proxy = std::nullopt},
.flags = {.type = Flags::Type::INSERT,
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
- .name = "VolumeSw"},
+ .name = "VolumeSw",
+ .implementor = "The Android Open Source Project"},
.capability = Capability::make<Capability::volume>(kCapability)};
/* parameters */
diff --git a/audio/aidl/vts/EffectFactoryHelper.h b/audio/aidl/vts/EffectFactoryHelper.h
index d58fcf2..dc766dd 100644
--- a/audio/aidl/vts/EffectFactoryHelper.h
+++ b/audio/aidl/vts/EffectFactoryHelper.h
@@ -29,10 +29,7 @@
using namespace android;
using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::EffectNullUuid;
-using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::Processing;
using aidl::android::media::audio::common::AudioUuid;
class EffectFactoryHelper {
@@ -48,122 +45,36 @@
ASSERT_NE(mEffectFactory, nullptr);
mEffectFactory = IFactory::fromBinder(binderUtil.restartService());
ASSERT_NE(mEffectFactory, nullptr);
- ClearEffectMap();
}
- void QueryEffects(const std::optional<AudioUuid>& in_type,
- const std::optional<AudioUuid>& in_instance,
- const std::optional<AudioUuid>& in_proxy,
- std::vector<Descriptor::Identity>* _aidl_return) {
- ASSERT_NE(mEffectFactory, nullptr);
- EXPECT_IS_OK(mEffectFactory->queryEffects(in_type, in_instance, in_proxy, _aidl_return));
- mIds = *_aidl_return;
- }
+ std::shared_ptr<IFactory> GetFactory() const { return mEffectFactory; }
- void QueryProcessing(const std::optional<Processing::Type>& in_type,
- std::vector<Processing>* _aidl_return) {
- ASSERT_NE(mEffectFactory, nullptr);
- EXPECT_IS_OK(mEffectFactory->queryProcessing(in_type, _aidl_return));
- // only update the whole list if no filter applied
- if (!in_type.has_value()) {
- mProcesses = *_aidl_return;
- }
- }
+ static std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>>
+ getAllEffectDescriptors(std::string serviceName, std::optional<AudioUuid> type = std::nullopt) {
+ AudioHalBinderServiceUtil util;
+ auto names = android::getAidlHalInstanceNames(serviceName);
+ std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>> result;
- void CreateEffects() {
- for (const auto& id : mIds) {
- std::shared_ptr<IEffect> effect;
- EXPECT_IS_OK(mEffectFactory->createEffect(id.uuid, &effect));
- EXPECT_NE(effect, nullptr) << id.toString();
- if (effect) {
- mEffectIdMap[effect] = id;
+ for (const auto& name : names) {
+ auto factory = IFactory::fromBinder(util.connectToService(name));
+ if (factory) {
+ if (std::vector<Descriptor::Identity> ids;
+ factory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids).isOk()) {
+ for (const auto& id : ids) {
+ if (type.has_value() && id.type != type.value()) {
+ continue;
+ }
+ result.emplace_back(factory, id);
+ }
+ }
}
}
- }
- void QueryAndCreateEffects(const AudioUuid& type = EffectNullUuid) {
- std::vector<Descriptor::Identity> ids;
- ASSERT_NE(mEffectFactory, nullptr);
-
- if (type == EffectNullUuid) {
- EXPECT_IS_OK(
- mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
- } else {
- EXPECT_IS_OK(mEffectFactory->queryEffects(type, std::nullopt, std::nullopt, &ids));
- }
- for (const auto& id : ids) {
- ASSERT_EQ(id.type, type);
- std::shared_ptr<IEffect> effect;
- EXPECT_IS_OK(mEffectFactory->createEffect(id.uuid, &effect));
- EXPECT_NE(effect, nullptr) << id.toString();
- if (effect) {
- mEffectIdMap[effect] = id;
- }
- }
+ return result;
}
- void CreateEffectsAndExpect(
- const std::vector<std::pair<Descriptor::Identity, binder_exception_t>>& uuid_status) {
- ASSERT_NE(mEffectFactory, nullptr);
- for (const auto& it : uuid_status) {
- std::shared_ptr<IEffect> effect;
- auto status = mEffectFactory->createEffect(it.first.uuid, &effect);
- EXPECT_STATUS(it.second, status);
- if (effect) {
- mEffectIdMap[effect] = it.first;
- }
- }
- }
-
- void DestroyEffectAndExpect(std::shared_ptr<IEffect>& instance, binder_exception_t exception) {
- ASSERT_NE(mEffectFactory, nullptr);
- auto status = mEffectFactory->destroyEffect(instance);
- EXPECT_STATUS(exception, status);
- }
-
- void QueryAndCreateAllEffects() {
- ASSERT_NE(mEffectFactory, nullptr);
- EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt,
- &mCompleteIds));
- for (const auto& id : mCompleteIds) {
- std::shared_ptr<IEffect> effect;
- EXPECT_IS_OK(mEffectFactory->createEffect(id.uuid, &effect));
- EXPECT_NE(effect, nullptr) << id.toString();
- mEffectIdMap[effect] = id;
- }
- }
-
- void DestroyEffects(const binder_exception_t expected = EX_NONE, const int remaining = 0) {
- ASSERT_NE(mEffectFactory, nullptr);
-
- for (auto it = mEffectIdMap.begin(); it != mEffectIdMap.end();) {
- auto erased = it++;
- auto status = mEffectFactory->destroyEffect(erased->first);
- EXPECT_STATUS(expected, status);
- if (status.isOk()) {
- mEffectIdMap.erase(erased);
- }
- }
- EXPECT_EQ((unsigned int)remaining, mEffectIdMap.size());
- }
-
- std::shared_ptr<IFactory> GetFactory() { return mEffectFactory; }
- const std::vector<Descriptor::Identity>& GetEffectIds() { return mIds; }
- const std::vector<Descriptor::Identity>& GetCompleteEffectIdList() const {
- return mCompleteIds;
- }
- const std::map<std::shared_ptr<IEffect>, Descriptor::Identity>& GetEffectMap() const {
- return mEffectIdMap;
- }
- void ClearEffectMap() { mEffectIdMap.clear(); }
-
private:
std::shared_ptr<IFactory> mEffectFactory;
std::string mServiceName;
AudioHalBinderServiceUtil binderUtil;
- std::vector<Descriptor::Identity> mIds;
- std::vector<Descriptor::Identity> mCompleteIds;
- std::vector<Processing> mProcesses;
-
- std::map<std::shared_ptr<IEffect>, Descriptor::Identity> mEffectIdMap;
};
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 623ac37..73a1f49 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -16,6 +16,7 @@
#pragma once
+#include <algorithm>
#include <memory>
#include <string>
#include <unordered_map>
@@ -24,7 +25,6 @@
#include <aidl/android/hardware/audio/effect/IEffect.h>
#include <aidl/android/hardware/audio/effect/IFactory.h>
#include <aidl/android/media/audio/common/AudioChannelLayout.h>
-#include <aidl/android/media/audio/common/AudioDeviceType.h>
#include <android/binder_auto_utils.h>
#include <fmq/AidlMessageQueue.h>
@@ -35,275 +35,139 @@
using namespace android;
using aidl::android::hardware::audio::effect::CommandId;
using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::EffectNullUuid;
-using aidl::android::hardware::audio::effect::EffectZeroUuid;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::Parameter;
using aidl::android::hardware::audio::effect::State;
using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
using aidl::android::media::audio::common::AudioChannelLayout;
-using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioFormatDescription;
using aidl::android::media::audio::common::AudioFormatType;
using aidl::android::media::audio::common::AudioUuid;
using aidl::android::media::audio::common::PcmType;
-const AudioFormatDescription DefaultFormat = {
+const AudioFormatDescription kDefaultFormatDescription = {
.type = AudioFormatType::PCM, .pcm = PcmType::FLOAT_32_BIT, .encoding = ""};
+typedef ::android::AidlMessageQueue<IEffect::Status,
+ ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+ StatusMQ;
+typedef ::android::AidlMessageQueue<float,
+ ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+ DataMQ;
+
class EffectHelper {
public:
- explicit EffectHelper(const std::string& name) : mFactoryHelper(EffectFactoryHelper(name)) {
- mFactoryHelper.ConnectToFactoryService();
+ static void create(std::shared_ptr<IFactory> factory, std::shared_ptr<IEffect>& effect,
+ Descriptor::Identity id, binder_status_t status = EX_NONE) {
+ ASSERT_NE(factory, nullptr);
+ EXPECT_STATUS(status, factory->createEffect(id.uuid, &effect));
+ if (status == EX_NONE) {
+ ASSERT_NE(effect, nullptr) << id.uuid.toString();
+ }
}
- void OpenEffects(const AudioUuid& type = EffectNullUuid) {
- auto open = [&](const std::shared_ptr<IEffect>& effect) {
- ASSERT_NE(effect, nullptr);
- IEffect::OpenEffectReturn ret;
- EXPECT_IS_OK(effect->open(mCommon, mSpecific, &ret));
- EffectParam params;
- params.statusMQ = std::make_unique<StatusMQ>(ret.statusMQ);
- params.inputMQ = std::make_unique<DataMQ>(ret.inputDataMQ);
- params.outputMQ = std::make_unique<DataMQ>(ret.outputDataMQ);
- mEffectParams.push_back(std::move(params));
- };
- EXPECT_NO_FATAL_FAILURE(ForEachEffect(open, type));
+ static void destroy(std::shared_ptr<IFactory> factory, std::shared_ptr<IEffect> effect,
+ binder_status_t status = EX_NONE) {
+ ASSERT_NE(factory, nullptr);
+ ASSERT_NE(effect, nullptr);
+ EXPECT_STATUS(status, factory->destroyEffect(effect));
}
- void CloseEffects(const binder_status_t status = EX_NONE) {
- auto close = [&](const std::shared_ptr<IEffect>& effect) {
- ASSERT_NE(effect, nullptr);
+ static void open(std::shared_ptr<IEffect> effect, const Parameter::Common& common,
+ const std::optional<Parameter::Specific>& specific,
+ IEffect::OpenEffectReturn* ret, binder_status_t status = EX_NONE) {
+ ASSERT_NE(effect, nullptr);
+ EXPECT_STATUS(status, effect->open(common, specific, ret));
+ }
+
+ static void open(std::shared_ptr<IEffect> effect, int session = 0,
+ binder_status_t status = EX_NONE) {
+ ASSERT_NE(effect, nullptr);
+ Parameter::Common common = EffectHelper::createParamCommon(session);
+ IEffect::OpenEffectReturn ret;
+ open(effect, common, std::nullopt /* specific */, &ret, status);
+ }
+
+ static void close(std::shared_ptr<IEffect> effect, binder_status_t status = EX_NONE) {
+ if (effect) {
EXPECT_STATUS(status, effect->close());
- };
-
- EXPECT_NO_FATAL_FAILURE(ForEachEffect(close));
- }
-
- void CreateEffects(const int n = 1) {
- for (int i = 0; i < n; i++) {
- ASSERT_NO_FATAL_FAILURE(mFactoryHelper.QueryAndCreateAllEffects());
}
}
-
- void CreateEffectsWithUUID(const AudioUuid& type = EffectNullUuid) {
- ASSERT_NO_FATAL_FAILURE(mFactoryHelper.QueryAndCreateEffects(type));
+ static void getDescriptor(std::shared_ptr<IEffect> effect, Descriptor& desc,
+ binder_status_t status = EX_NONE) {
+ ASSERT_NE(effect, nullptr);
+ EXPECT_STATUS(status, effect->getDescriptor(&desc));
}
-
- void QueryEffects() { ASSERT_NO_FATAL_FAILURE(mFactoryHelper.QueryAndCreateAllEffects()); }
-
- void DestroyEffects(const binder_status_t status = EX_NONE, const int remaining = 0) {
- ASSERT_NO_FATAL_FAILURE(mFactoryHelper.DestroyEffects(status, remaining));
- mEffectDescriptors.clear();
+ static void expectState(std::shared_ptr<IEffect> effect, State expectState,
+ binder_status_t status = EX_NONE) {
+ ASSERT_NE(effect, nullptr);
+ State state;
+ EXPECT_STATUS(status, effect->getState(&state));
+ EXPECT_EQ(expectState, state);
}
-
- void GetEffectDescriptors() {
- auto get = [&](const std::shared_ptr<IEffect>& effect) {
- ASSERT_NE(effect, nullptr);
- Descriptor desc;
- EXPECT_IS_OK(effect->getDescriptor(&desc));
- mEffectDescriptors.push_back(std::move(desc));
- };
- EXPECT_NO_FATAL_FAILURE(ForEachEffect(get));
+ static void command(std::shared_ptr<IEffect> effect, CommandId command,
+ binder_status_t status = EX_NONE) {
+ ASSERT_NE(effect, nullptr);
+ EXPECT_STATUS(status, effect->command(command));
}
-
- void CommandEffects(CommandId command) {
- auto close = [&](const std::shared_ptr<IEffect>& effect) {
- ASSERT_NE(effect, nullptr);
- EXPECT_IS_OK(effect->command(command));
- };
- EXPECT_NO_FATAL_FAILURE(ForEachEffect(close));
+ static void allocateInputData(const Parameter::Common common, std::unique_ptr<DataMQ>& mq,
+ std::vector<float>& buffer) {
+ ASSERT_NE(mq, nullptr);
+ auto frameSize = android::hardware::audio::common::getFrameSizeInBytes(
+ common.input.base.format, common.input.base.channelMask);
+ const size_t floatsToWrite = mq->availableToWrite();
+ EXPECT_NE(0UL, floatsToWrite);
+ EXPECT_EQ(frameSize * common.input.frameCount, floatsToWrite * sizeof(float));
+ buffer.resize(floatsToWrite);
+ std::fill(buffer.begin(), buffer.end(), 0x5a);
}
-
- void CommandEffectsExpectStatus(CommandId command, const binder_status_t status) {
- auto func = [&](const std::shared_ptr<IEffect>& effect) {
- ASSERT_NE(effect, nullptr);
- EXPECT_STATUS(status, effect->command(command));
- };
- EXPECT_NO_FATAL_FAILURE(ForEachEffect(func));
+ static void writeToFmq(std::unique_ptr<DataMQ>& mq, const std::vector<float>& buffer) {
+ const size_t available = mq->availableToWrite();
+ EXPECT_NE(0Ul, available);
+ auto bufferFloats = buffer.size();
+ auto floatsToWrite = std::min(available, bufferFloats);
+ EXPECT_TRUE(mq->write(buffer.data(), floatsToWrite));
}
-
- void ExpectState(State expected) {
- auto get = [&](const std::shared_ptr<IEffect>& effect) {
- ASSERT_NE(effect, nullptr);
- State state = State::INIT;
- EXPECT_IS_OK(effect->getState(&state));
- EXPECT_EQ(expected, state);
- };
- EXPECT_NO_FATAL_FAILURE(ForEachEffect(get));
- }
-
- void SetParameter() {
- auto func = [&](const std::shared_ptr<IEffect>& effect) {
- ASSERT_NE(effect, nullptr);
- Parameter param;
- param.set<Parameter::common>(mCommon);
- EXPECT_IS_OK(effect->setParameter(param));
- };
- EXPECT_NO_FATAL_FAILURE(ForEachEffect(func));
- }
-
- void VerifyParameters() {
- auto func = [&](const std::shared_ptr<IEffect>& effect) {
- ASSERT_NE(effect, nullptr);
- Parameter paramCommonGet = Parameter(), paramCommonExpect = Parameter();
- Parameter::Id id;
- id.set<Parameter::Id::commonTag>(Parameter::common);
- paramCommonExpect.set<Parameter::common>(mCommon);
- EXPECT_IS_OK(effect->getParameter(id, ¶mCommonGet));
- EXPECT_EQ(paramCommonExpect, paramCommonGet)
- << paramCommonExpect.toString() << " vs " << paramCommonGet.toString();
- };
- EXPECT_NO_FATAL_FAILURE(ForEachEffect(func));
- }
-
- void QueryEffects(const std::optional<AudioUuid>& in_type,
- const std::optional<AudioUuid>& in_instance,
- const std::optional<AudioUuid>& in_proxy,
- std::vector<Descriptor::Identity>* _aidl_return) {
- mFactoryHelper.QueryEffects(in_type, in_instance, in_proxy, _aidl_return);
- }
-
- template <typename Functor>
- void ForEachEffect(Functor functor, const std::optional<AudioUuid>& type = EffectNullUuid) {
- auto effectMap = mFactoryHelper.GetEffectMap();
- for (const auto& it : effectMap) {
- SCOPED_TRACE(it.second.toString());
- if (type != EffectNullUuid && it.second.type != type) continue;
- functor(it.first);
+ static void readFromFmq(std::unique_ptr<StatusMQ>& statusMq, size_t statusNum,
+ std::unique_ptr<DataMQ>& dataMq, size_t expectFloats,
+ std::vector<float>& buffer) {
+ IEffect::Status status{};
+ EXPECT_TRUE(statusMq->readBlocking(&status, statusNum));
+ EXPECT_EQ(STATUS_OK, status.status);
+ if (statusNum != 0) {
+ EXPECT_EQ(expectFloats, (unsigned)status.fmqProduced);
+ EXPECT_EQ(expectFloats, dataMq->availableToRead());
+ if (expectFloats != 0) {
+ EXPECT_TRUE(dataMq->read(buffer.data(), expectFloats));
+ }
}
}
+ static Parameter::Common createParamCommon(
+ int session = 0, int ioHandle = -1, int iSampleRate = 48000, int oSampleRate = 48000,
+ long iFrameCount = 0x100, long oFrameCount = 0x100,
+ AudioChannelLayout inputChannelLayout =
+ AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+ AudioChannelLayout::LAYOUT_STEREO),
+ AudioChannelLayout outputChannelLayout =
+ AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+ AudioChannelLayout::LAYOUT_STEREO)) {
+ Parameter::Common common;
+ common.session = session;
+ common.ioHandle = ioHandle;
- template <typename Functor>
- void ForEachDescriptor(Functor functor) {
- for (size_t i = 0; i < mEffectDescriptors.size(); i++) {
- SCOPED_TRACE(mEffectDescriptors[i].toString());
- functor(i, mEffectDescriptors[i]);
- }
- }
-
- static const size_t mWriteMQBytes = 0x400;
-
- enum class IO : char { INPUT = 0, OUTPUT = 1, INOUT = 2 };
-
- void initParamCommonFormat(IO io = IO::INOUT,
- const AudioFormatDescription& format = DefaultFormat) {
- if (io == IO::INPUT || io == IO::INOUT) {
- mCommon.input.base.format = format;
- }
- if (io == IO::OUTPUT || io == IO::INOUT) {
- mCommon.output.base.format = format;
- }
- }
-
- void initParamCommonSampleRate(IO io = IO::INOUT, const int& sampleRate = 48000) {
- if (io == IO::INPUT || io == IO::INOUT) {
- mCommon.input.base.sampleRate = sampleRate;
- }
- if (io == IO::OUTPUT || io == IO::INOUT) {
- mCommon.output.base.sampleRate = sampleRate;
- }
- }
-
- void initParamCommonFrameCount(IO io = IO::INOUT, const long& frameCount = 48000) {
- if (io == IO::INPUT || io == IO::INOUT) {
- mCommon.input.frameCount = frameCount;
- }
- if (io == IO::OUTPUT || io == IO::INOUT) {
- mCommon.output.frameCount = frameCount;
- }
- }
- void initParamCommon(int session = 0, int ioHandle = -1, int iSampleRate = 48000,
- int oSampleRate = 48000, long iFrameCount = 0x100,
- long oFrameCount = 0x100) {
- mCommon.session = session;
- mCommon.ioHandle = ioHandle;
-
- auto& input = mCommon.input;
- auto& output = mCommon.output;
+ auto& input = common.input;
+ auto& output = common.output;
input.base.sampleRate = iSampleRate;
- input.base.channelMask = mInputChannelLayout;
+ input.base.channelMask = inputChannelLayout;
+ input.base.format = kDefaultFormatDescription;
input.frameCount = iFrameCount;
- input.base.format = DefaultFormat;
output.base.sampleRate = oSampleRate;
- output.base.channelMask = mOutputChannelLayout;
- output.base.format = DefaultFormat;
+ output.base.channelMask = outputChannelLayout;
+ output.base.format = kDefaultFormatDescription;
output.frameCount = oFrameCount;
- output.base.format = DefaultFormat;
- inputFrameSize = android::hardware::audio::common::getFrameSizeInBytes(
- input.base.format, input.base.channelMask);
- outputFrameSize = android::hardware::audio::common::getFrameSizeInBytes(
- output.base.format, output.base.channelMask);
+ return common;
}
- void setSpecific(Parameter::Specific& specific) { mSpecific = specific; }
-
- // usually this function only call once.
- void PrepareInputData(size_t bytes = mWriteMQBytes) {
- size_t maxInputBytes = mWriteMQBytes;
- for (auto& it : mEffectParams) {
- auto& mq = it.inputMQ;
- EXPECT_NE(nullptr, mq);
- EXPECT_TRUE(mq->isValid());
- const size_t bytesToWrite = mq->availableToWrite() * sizeof(float);
- EXPECT_EQ(inputFrameSize * mCommon.input.frameCount, bytesToWrite);
- EXPECT_NE(0UL, bytesToWrite);
- EXPECT_TRUE(bytes <= bytesToWrite);
- maxInputBytes = std::max(maxInputBytes, bytesToWrite);
- }
- mInputBuffer.resize(maxInputBytes / sizeof(float));
- std::fill(mInputBuffer.begin(), mInputBuffer.end(), 0x5a);
- }
-
- void writeToFmq(size_t bytes = mWriteMQBytes) {
- for (auto& it : mEffectParams) {
- auto& mq = it.inputMQ;
- EXPECT_NE(nullptr, mq);
- const size_t bytesToWrite = mq->availableToWrite() * sizeof(float);
- EXPECT_NE(0Ul, bytesToWrite);
- EXPECT_TRUE(bytes <= bytesToWrite);
- EXPECT_TRUE(mq->write(mInputBuffer.data(), bytes / sizeof(float)));
- }
- }
-
- void readFromFmq(size_t expectBytes = mWriteMQBytes) {
- for (auto& it : mEffectParams) {
- IEffect::Status status{};
- auto& statusMq = it.statusMQ;
- EXPECT_NE(nullptr, statusMq);
- EXPECT_TRUE(statusMq->readBlocking(&status, 1));
- EXPECT_EQ(STATUS_OK, status.status);
- EXPECT_EQ(expectBytes, (unsigned)status.fmqProduced * sizeof(float));
-
- auto& outputMq = it.outputMQ;
- EXPECT_NE(nullptr, outputMq);
- EXPECT_EQ(expectBytes, outputMq->availableToRead() * sizeof(float));
- }
- }
-
- void setInputChannelLayout(AudioChannelLayout input) { mInputChannelLayout = input; }
- void setOutputChannelLayout(AudioChannelLayout output) { mOutputChannelLayout = output; }
- const std::vector<Descriptor::Identity>& GetCompleteEffectIdList() const {
- return mFactoryHelper.GetCompleteEffectIdList();
- }
- const std::vector<Descriptor>& getDescriptorVec() const { return mEffectDescriptors; }
-
- private:
- EffectFactoryHelper mFactoryHelper;
-
- AudioChannelLayout mInputChannelLayout =
- AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
- AudioChannelLayout::LAYOUT_STEREO);
- AudioChannelLayout mOutputChannelLayout =
- AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
- AudioChannelLayout::LAYOUT_STEREO);
-
- Parameter::Common mCommon;
- std::optional<Parameter::Specific> mSpecific = std::nullopt;
-
- size_t inputFrameSize, outputFrameSize;
- std::vector<float> mInputBuffer; // reuse same buffer for all effects testing
-
typedef ::android::AidlMessageQueue<
IEffect::Status, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
StatusMQ;
@@ -317,6 +181,4 @@
std::unique_ptr<DataMQ> inputMQ;
std::unique_ptr<DataMQ> outputMQ;
};
- std::vector<EffectParam> mEffectParams;
- std::vector<Descriptor> mEffectDescriptors;
};
diff --git a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
index d30dff4..8ae963e 100644
--- a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
@@ -15,6 +15,7 @@
*/
#include <memory>
+#include <set>
#include <string>
#include <vector>
@@ -37,23 +38,81 @@
using namespace android;
using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::EffectNullUuid;
-using aidl::android::hardware::audio::effect::EffectZeroUuid;
+using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::kEffectNullUuid;
+using aidl::android::hardware::audio::effect::kEffectZeroUuid;
using aidl::android::hardware::audio::effect::Processing;
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::AudioStreamType;
using aidl::android::media::audio::common::AudioUuid;
/// Effect factory testing.
class EffectFactoryTest : public testing::TestWithParam<std::string> {
public:
- void SetUp() override { ASSERT_NO_FATAL_FAILURE(mFactory.ConnectToFactoryService()); }
+ void SetUp() override {
+ mFactoryHelper = std::make_unique<EffectFactoryHelper>(GetParam());
+ connectAndGetFactory();
+ }
- void TearDown() override { mFactory.DestroyEffects(); }
+ void TearDown() override {
+ for (auto& effect : mEffects) {
+ const auto status = mEffectFactory->destroyEffect(effect);
+ EXPECT_STATUS(EX_NONE, status);
+ }
+ }
- EffectFactoryHelper mFactory = EffectFactoryHelper(GetParam());
+ std::unique_ptr<EffectFactoryHelper> mFactoryHelper;
+ std::shared_ptr<IFactory> mEffectFactory;
+ std::vector<std::shared_ptr<IEffect>> mEffects;
+ const Descriptor::Identity kNullDesc = {.uuid = kEffectNullUuid};
+ const Descriptor::Identity kZeroDesc = {.uuid = kEffectZeroUuid};
- const Descriptor::Identity nullDesc = {.uuid = EffectNullUuid};
- const Descriptor::Identity zeroDesc = {.uuid = EffectZeroUuid};
+ template <typename Functor>
+ void ForEachId(const std::vector<Descriptor::Identity> ids, Functor functor) {
+ for (const auto& id : ids) {
+ SCOPED_TRACE(id.toString());
+ functor(id);
+ }
+ }
+ template <typename Functor>
+ void ForEachEffect(std::vector<std::shared_ptr<IEffect>> effects, Functor functor) {
+ for (auto& effect : effects) {
+ functor(effect);
+ }
+ }
+
+ std::vector<std::shared_ptr<IEffect>> createWithIds(
+ const std::vector<Descriptor::Identity> ids,
+ const binder_status_t expectStatus = EX_NONE) {
+ std::vector<std::shared_ptr<IEffect>> effects;
+ for (const auto& id : ids) {
+ std::shared_ptr<IEffect> effect;
+ EXPECT_STATUS(expectStatus, mEffectFactory->createEffect(id.uuid, &effect));
+ if (expectStatus == EX_NONE) {
+ EXPECT_NE(effect, nullptr) << " null effect with uuid: " << id.uuid.toString();
+ effects.push_back(std::move(effect));
+ }
+ }
+ return effects;
+ }
+ void destroyEffects(std::vector<std::shared_ptr<IEffect>> effects,
+ const binder_status_t expectStatus = EX_NONE) {
+ for (const auto& effect : effects) {
+ EXPECT_STATUS(expectStatus, mEffectFactory->destroyEffect(effect));
+ }
+ }
+ void creatAndDestroyIds(const std::vector<Descriptor::Identity> ids) {
+ for (const auto& id : ids) {
+ auto effects = createWithIds({id});
+ ASSERT_NO_FATAL_FAILURE(destroyEffects(effects));
+ }
+ }
+ void connectAndGetFactory() {
+ ASSERT_NO_FATAL_FAILURE(mFactoryHelper->ConnectToFactoryService());
+ mEffectFactory = mFactoryHelper->GetFactory();
+ ASSERT_NE(mEffectFactory, nullptr);
+ }
};
TEST_P(EffectFactoryTest, SetupAndTearDown) {
@@ -61,165 +120,160 @@
}
TEST_P(EffectFactoryTest, CanBeRestarted) {
- ASSERT_NO_FATAL_FAILURE(mFactory.RestartFactoryService());
+ ASSERT_NO_FATAL_FAILURE(mFactoryHelper->RestartFactoryService());
}
-TEST_P(EffectFactoryTest, QueriedDescriptorList) {
- std::vector<Descriptor::Identity> descriptors;
- mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
- EXPECT_NE(descriptors.size(), 0UL);
-}
+/**
+ * @brief Check at least support list of effect must be supported by aosp:
+ * https://developer.android.com/reference/android/media/audiofx/AudioEffect
+ */
+TEST_P(EffectFactoryTest, ExpectAllAospEffectTypes) {
+ std::vector<Descriptor::Identity> ids;
+ std::set<AudioUuid> typeUuidSet(
+ {aidl::android::hardware::audio::effect::kBassBoostTypeUUID,
+ aidl::android::hardware::audio::effect::kEqualizerTypeUUID,
+ aidl::android::hardware::audio::effect::kEnvReverbTypeUUID,
+ aidl::android::hardware::audio::effect::kPresetReverbTypeUUID,
+ aidl::android::hardware::audio::effect::kDynamicsProcessingTypeUUID,
+ aidl::android::hardware::audio::effect::kHapticGeneratorTypeUUID,
+ aidl::android::hardware::audio::effect::kVirtualizerTypeUUID});
-TEST_P(EffectFactoryTest, DescriptorUUIDNotNull) {
- std::vector<Descriptor::Identity> descriptors;
- mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
- // TODO: Factory eventually need to return the full list of MUST supported AOSP effects.
- for (auto& desc : descriptors) {
- EXPECT_NE(desc.type, EffectNullUuid);
- EXPECT_NE(desc.uuid, EffectNullUuid);
+ EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+ EXPECT_TRUE(ids.size() >= typeUuidSet.size());
+ for (const auto& id : ids) {
+ typeUuidSet.erase(id.type);
}
+ std::string msg = " missing type UUID:\n";
+ for (const auto& uuid : typeUuidSet) {
+ msg += (uuid.toString() + "\n");
+ }
+ SCOPED_TRACE(msg);
+ EXPECT_EQ(0UL, typeUuidSet.size());
}
-TEST_P(EffectFactoryTest, QueriedDescriptorNotExistType) {
- std::vector<Descriptor::Identity> descriptors;
- mFactory.QueryEffects(EffectNullUuid, std::nullopt, std::nullopt, &descriptors);
- EXPECT_EQ(descriptors.size(), 0UL);
+TEST_P(EffectFactoryTest, QueryNullTypeUuid) {
+ std::vector<Descriptor::Identity> ids;
+ EXPECT_IS_OK(mEffectFactory->queryEffects(kEffectNullUuid, std::nullopt, std::nullopt, &ids));
+ EXPECT_EQ(ids.size(), 0UL);
}
-TEST_P(EffectFactoryTest, QueriedDescriptorNotExistInstance) {
- std::vector<Descriptor::Identity> descriptors;
- mFactory.QueryEffects(std::nullopt, EffectNullUuid, std::nullopt, &descriptors);
- EXPECT_EQ(descriptors.size(), 0UL);
+TEST_P(EffectFactoryTest, QueriedNullImplUuid) {
+ std::vector<Descriptor::Identity> ids;
+ EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, kEffectNullUuid, std::nullopt, &ids));
+ EXPECT_EQ(ids.size(), 0UL);
}
-TEST_P(EffectFactoryTest, CreateAndDestroyOnce) {
- std::vector<Descriptor::Identity> descriptors;
- mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
- auto numIds = mFactory.GetEffectIds().size();
- EXPECT_NE(numIds, 0UL);
-
- auto& effectMap = mFactory.GetEffectMap();
- EXPECT_EQ(effectMap.size(), 0UL);
- mFactory.CreateEffects();
- EXPECT_EQ(effectMap.size(), numIds);
- mFactory.DestroyEffects();
- EXPECT_EQ(effectMap.size(), 0UL);
+TEST_P(EffectFactoryTest, QueriedNullProxyUuid) {
+ std::vector<Descriptor::Identity> ids;
+ EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, kEffectNullUuid, &ids));
+ EXPECT_EQ(ids.size(), 0UL);
}
-TEST_P(EffectFactoryTest, CreateAndDestroyRepeat) {
- std::vector<Descriptor::Identity> descriptors;
- mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
- auto numIds = mFactory.GetEffectIds().size();
- EXPECT_NE(numIds, 0UL);
+// create all effects, and then destroy them all together
+TEST_P(EffectFactoryTest, CreateAndDestroyEffects) {
+ std::vector<Descriptor::Identity> ids;
+ EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+ EXPECT_NE(ids.size(), 0UL);
- auto& effectMap = mFactory.GetEffectMap();
- EXPECT_EQ(effectMap.size(), 0UL);
- mFactory.CreateEffects();
- EXPECT_EQ(effectMap.size(), numIds);
- mFactory.DestroyEffects();
- EXPECT_EQ(effectMap.size(), 0UL);
-
- // Create and destroy again
- mFactory.CreateEffects();
- EXPECT_EQ(effectMap.size(), numIds);
- mFactory.DestroyEffects();
- EXPECT_EQ(effectMap.size(), 0UL);
+ std::vector<std::shared_ptr<IEffect>> effects;
+ effects = createWithIds(ids);
+ EXPECT_EQ(ids.size(), effects.size());
+ destroyEffects(effects);
}
TEST_P(EffectFactoryTest, CreateMultipleInstanceOfSameEffect) {
- std::vector<Descriptor::Identity> descriptors;
- mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
- auto numIds = mFactory.GetEffectIds().size();
- EXPECT_NE(numIds, 0UL);
+ std::vector<Descriptor::Identity> ids;
+ EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+ EXPECT_NE(ids.size(), 0UL);
- auto& effectMap = mFactory.GetEffectMap();
- EXPECT_EQ(effectMap.size(), 0UL);
- mFactory.CreateEffects();
- EXPECT_EQ(effectMap.size(), numIds);
- // Create effect instances of same implementation
- mFactory.CreateEffects();
- EXPECT_EQ(effectMap.size(), 2 * numIds);
+ std::vector<std::shared_ptr<IEffect>> effects = createWithIds(ids);
+ EXPECT_EQ(ids.size(), effects.size());
+ std::vector<std::shared_ptr<IEffect>> effects2 = createWithIds(ids);
+ EXPECT_EQ(ids.size(), effects2.size());
+ std::vector<std::shared_ptr<IEffect>> effects3 = createWithIds(ids);
+ EXPECT_EQ(ids.size(), effects3.size());
- mFactory.CreateEffects();
- EXPECT_EQ(effectMap.size(), 3 * numIds);
+ destroyEffects(effects);
+ destroyEffects(effects2);
+ destroyEffects(effects3);
+}
- mFactory.DestroyEffects();
- EXPECT_EQ(effectMap.size(), 0UL);
+// create and destroy each effect one by one
+TEST_P(EffectFactoryTest, CreateAndDestroyEffectsOneByOne) {
+ std::vector<Descriptor::Identity> ids;
+ EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+ EXPECT_NE(ids.size(), 0UL);
+
+ creatAndDestroyIds(ids);
+}
+
+// for each effect: repeat 3 times create and destroy
+TEST_P(EffectFactoryTest, CreateAndDestroyRepeat) {
+ std::vector<Descriptor::Identity> ids;
+ EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+ EXPECT_NE(ids.size(), 0UL);
+
+ creatAndDestroyIds(ids);
+ creatAndDestroyIds(ids);
+ creatAndDestroyIds(ids);
}
// Expect EX_ILLEGAL_ARGUMENT when create with invalid UUID.
TEST_P(EffectFactoryTest, CreateWithInvalidUuid) {
- std::vector<std::pair<Descriptor::Identity, binder_status_t>> descriptors;
- descriptors.push_back(std::make_pair(nullDesc, EX_ILLEGAL_ARGUMENT));
- descriptors.push_back(std::make_pair(zeroDesc, EX_ILLEGAL_ARGUMENT));
-
- auto& effectMap = mFactory.GetEffectMap();
- mFactory.CreateEffectsAndExpect(descriptors);
- EXPECT_EQ(effectMap.size(), 0UL);
+ std::vector<Descriptor::Identity> ids = {kNullDesc, kZeroDesc};
+ auto effects = createWithIds(ids, EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(effects.size(), 0UL);
}
// Expect EX_ILLEGAL_ARGUMENT when destroy null interface.
TEST_P(EffectFactoryTest, DestroyWithInvalidInterface) {
std::shared_ptr<IEffect> spDummyEffect(nullptr);
-
- mFactory.DestroyEffectAndExpect(spDummyEffect, EX_ILLEGAL_ARGUMENT);
+ destroyEffects({spDummyEffect}, EX_ILLEGAL_ARGUMENT);
}
-TEST_P(EffectFactoryTest, CreateAndRemoveReference) {
- std::vector<Descriptor::Identity> descriptors;
- mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
- auto numIds = mFactory.GetEffectIds().size();
- EXPECT_NE(numIds, 0UL);
+// Same descriptor ID should work after service restart.
+TEST_P(EffectFactoryTest, CreateDestroyWithRestart) {
+ std::vector<Descriptor::Identity> ids;
+ EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+ EXPECT_NE(ids.size(), 0UL);
+ creatAndDestroyIds(ids);
- auto& effectMap = mFactory.GetEffectMap();
- EXPECT_EQ(effectMap.size(), 0UL);
- mFactory.CreateEffects();
- EXPECT_EQ(effectMap.size(), numIds);
- // remove all reference
- mFactory.ClearEffectMap();
- EXPECT_EQ(effectMap.size(), 0UL);
+ mFactoryHelper->RestartFactoryService();
+
+ connectAndGetFactory();
+ creatAndDestroyIds(ids);
}
-TEST_P(EffectFactoryTest, CreateRemoveReferenceAndCreateDestroy) {
- std::vector<Descriptor::Identity> descriptors;
- mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
- auto numIds = mFactory.GetEffectIds().size();
- EXPECT_NE(numIds, 0UL);
+// Effect handle invalid after restart.
+TEST_P(EffectFactoryTest, EffectInvalidAfterRestart) {
+ std::vector<Descriptor::Identity> ids;
+ EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &ids));
+ EXPECT_NE(ids.size(), 0UL);
+ std::vector<std::shared_ptr<IEffect>> effects = createWithIds(ids);
- auto& effectMap = mFactory.GetEffectMap();
- EXPECT_EQ(effectMap.size(), 0UL);
- mFactory.CreateEffects();
- EXPECT_EQ(effectMap.size(), numIds);
- // remove all reference
- mFactory.ClearEffectMap();
- EXPECT_EQ(effectMap.size(), 0UL);
+ ASSERT_NO_FATAL_FAILURE(mFactoryHelper->RestartFactoryService());
- // Create and destroy again
- mFactory.CreateEffects();
- EXPECT_EQ(effectMap.size(), numIds);
- mFactory.DestroyEffects();
- EXPECT_EQ(effectMap.size(), 0UL);
+ connectAndGetFactory();
+ destroyEffects(effects, EX_ILLEGAL_ARGUMENT);
}
-TEST_P(EffectFactoryTest, CreateRestartAndCreateDestroy) {
- std::vector<Descriptor::Identity> descriptors;
- mFactory.QueryEffects(std::nullopt, std::nullopt, std::nullopt, &descriptors);
- auto numIds = mFactory.GetEffectIds().size();
- auto& effectMap = mFactory.GetEffectMap();
- mFactory.CreateEffects();
- EXPECT_EQ(effectMap.size(), numIds);
- ASSERT_NO_FATAL_FAILURE(mFactory.RestartFactoryService());
-
- mFactory.CreateEffects();
- EXPECT_EQ(effectMap.size(), numIds);
- mFactory.DestroyEffects();
- EXPECT_EQ(effectMap.size(), 0UL);
-}
-
+// expect no error with the queryProcessing interface, but don't check number of processing
TEST_P(EffectFactoryTest, QueryProcess) {
std::vector<Processing> processing;
- mFactory.QueryProcessing(std::nullopt, &processing);
- // TODO: verify the number of process in example implementation after audio_effects.xml migrated
+ EXPECT_IS_OK(mEffectFactory->queryProcessing(std::nullopt, &processing));
+
+ Processing::Type streamType =
+ Processing::Type::make<Processing::Type::streamType>(AudioStreamType::SYSTEM);
+ std::vector<Processing> processingFilteredByStream;
+ EXPECT_IS_OK(mEffectFactory->queryProcessing(streamType, &processingFilteredByStream));
+
+ Processing::Type source =
+ Processing::Type::make<Processing::Type::source>(AudioSource::DEFAULT);
+ std::vector<Processing> processingFilteredBySource;
+ EXPECT_IS_OK(mEffectFactory->queryProcessing(source, &processingFilteredBySource));
+
+ EXPECT_TRUE(processing.size() >= processingFilteredByStream.size());
+ EXPECT_TRUE(processing.size() >= processingFilteredBySource.size());
}
INSTANTIATE_TEST_SUITE_P(EffectFactoryTest, EffectFactoryTest,
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index 3ea67bc..8212149 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -16,26 +16,24 @@
#define LOG_TAG "VtsHalAudioEffectTargetTest"
+#include <chrono>
#include <memory>
#include <string>
-#include <unordered_map>
-#include <unordered_set>
#include <vector>
+#include <Utils.h>
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+#include <aidl/android/hardware/audio/effect/IFactory.h>
#include <android-base/logging.h>
-#include <android-base/properties.h>
#include <android/binder_interface_utils.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
-
-#include <Utils.h>
-#include <aidl/android/hardware/audio/effect/IEffect.h>
-#include <aidl/android/hardware/audio/effect/IFactory.h>
-#include <aidl/android/media/audio/common/AudioDeviceType.h>
+#include <fmq/AidlMessageQueue.h>
#include "AudioHalBinderServiceUtil.h"
+#include "EffectFactoryHelper.h"
#include "EffectHelper.h"
#include "TestUtils.h"
@@ -49,309 +47,725 @@
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::AudioDeviceType;
-class AudioEffectTest : public testing::TestWithParam<std::string>, public EffectHelper {
+enum ParamName { PARAM_INSTANCE_NAME };
+using EffectTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>>;
+
+class AudioEffectTest : public testing::TestWithParam<EffectTestParam>, public EffectHelper {
public:
- AudioEffectTest() : EffectHelper(GetParam()) {}
+ AudioEffectTest() { std::tie(mFactory, mIdentity) = std::get<PARAM_INSTANCE_NAME>(GetParam()); }
- void SetUp() override {
- CreateEffects();
- initParamCommonFormat();
- initParamCommon();
- }
+ void SetUp() override {}
+ void TearDown() override {}
- void TearDown() override {
- CloseEffects();
- DestroyEffects();
- }
+ static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+ std::shared_ptr<IFactory> mFactory;
+ Descriptor::Identity mIdentity;
};
-TEST_P(AudioEffectTest, OpenEffectTest) {
- OpenEffects();
+TEST_P(AudioEffectTest, SetupAndTearDown) {
+ // Intentionally empty test body.
}
-TEST_P(AudioEffectTest, OpenAndCloseEffect) {
- OpenEffects();
- CloseEffects();
+TEST_P(AudioEffectTest, CreateAndDestroy) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
-TEST_P(AudioEffectTest, CloseUnopenedEffectTest) {
- CloseEffects();
+TEST_P(AudioEffectTest, OpenAndClose) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
-TEST_P(AudioEffectTest, DoubleOpenCloseEffects) {
- OpenEffects();
- CloseEffects();
- OpenEffects();
- CloseEffects();
-
- OpenEffects();
- OpenEffects();
- CloseEffects();
-
- OpenEffects();
- CloseEffects();
- CloseEffects();
+TEST_P(AudioEffectTest, CloseUnopenedEffect) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
-TEST_P(AudioEffectTest, GetDescriptors) {
- GetEffectDescriptors();
+TEST_P(AudioEffectTest, DoubleOpenAndClose) {
+ std::shared_ptr<IEffect> effect1, effect2;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect1, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect2, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect1));
+ ASSERT_NO_FATAL_FAILURE(open(effect2, 1 /* session */));
+ ASSERT_NO_FATAL_FAILURE(close(effect1));
+ ASSERT_NO_FATAL_FAILURE(close(effect2));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect1));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect2));
}
-TEST_P(AudioEffectTest, DescriptorIdExistAndUnique) {
- auto checker = [&](const std::shared_ptr<IEffect>& effect) {
- Descriptor desc;
- std::vector<Descriptor::Identity> idList;
- EXPECT_IS_OK(effect->getDescriptor(&desc));
- QueryEffects(desc.common.id.type, desc.common.id.uuid, desc.common.id.proxy, &idList);
- // Must have at least one instance.
- EXPECT_NE(idList.size(), 0UL);
- };
- ForEachEffect(checker);
+TEST_P(AudioEffectTest, TripleOpenAndClose) {
+ std::shared_ptr<IEffect> effect1, effect2, effect3;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect1, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect2, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect3, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect1));
+ ASSERT_NO_FATAL_FAILURE(open(effect2, 1 /* session */));
+ ASSERT_NO_FATAL_FAILURE(open(effect3, 2 /* session */));
+ ASSERT_NO_FATAL_FAILURE(close(effect1));
+ ASSERT_NO_FATAL_FAILURE(close(effect2));
+ ASSERT_NO_FATAL_FAILURE(close(effect3));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect1));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect2));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect3));
+}
- // Check unique with a set
- auto stringHash = [](const Descriptor::Identity& id) {
- return std::hash<std::string>()(id.toString());
- };
- auto vec = GetCompleteEffectIdList();
- std::unordered_set<Descriptor::Identity, decltype(stringHash)> idSet(0, stringHash);
- for (auto it : vec) {
- EXPECT_EQ(idSet.count(it), 0UL) << it.toString();
- idSet.insert(it);
+TEST_P(AudioEffectTest, GetDescritorBeforeOpen) {
+ std::shared_ptr<IEffect> effect;
+ Descriptor desc;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(getDescriptor(effect, desc));
+ EXPECT_EQ(mIdentity.toString(), desc.common.id.toString());
+ EXPECT_NE("", desc.common.name);
+ EXPECT_NE("", desc.common.implementor);
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+TEST_P(AudioEffectTest, GetDescritorAfterOpen) {
+ std::shared_ptr<IEffect> effect;
+ Descriptor beforeOpen, afterOpen, afterClose;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(getDescriptor(effect, beforeOpen));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(getDescriptor(effect, afterOpen));
+ EXPECT_EQ(beforeOpen.toString(), afterOpen.toString()) << "\n"
+ << beforeOpen.toString() << "\n"
+ << afterOpen.toString();
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(getDescriptor(effect, afterClose));
+ EXPECT_EQ(beforeOpen.toString(), afterClose.toString()) << "\n"
+ << beforeOpen.toString() << "\n"
+ << afterClose.toString();
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+TEST_P(AudioEffectTest, DescriptorExistAndUnique) {
+ std::shared_ptr<IEffect> effect;
+ Descriptor desc;
+
+ auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor);
+ std::set<Descriptor::Identity> idSet;
+ for (const auto& it : descList) {
+ auto& id = it.second;
+ EXPECT_EQ(0ul, idSet.count(id));
+ idSet.insert(id);
}
+
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(getDescriptor(effect, desc));
+ EXPECT_EQ(1ul, idSet.count(desc.common.id));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
/// State testing.
// An effect instance is in INIT state by default after it was created.
TEST_P(AudioEffectTest, InitStateAfterCreation) {
- ExpectState(State::INIT);
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::INIT));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
-// An effect instance transfer to INIT state after it was open successfully with IEffect.open().
+// An effect instance transfer to IDLE state after IEffect.ASSERT_NO_FATAL_FAILURE(open().
TEST_P(AudioEffectTest, IdleStateAfterOpen) {
- OpenEffects();
- ExpectState(State::IDLE);
- CloseEffects();
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
// An effect instance is in PROCESSING state after it receive an START command.
TEST_P(AudioEffectTest, ProcessingStateAfterStart) {
- OpenEffects();
- CommandEffects(CommandId::START);
- ExpectState(State::PROCESSING);
- CommandEffects(CommandId::STOP);
- CloseEffects();
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::INIT));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
// An effect instance transfer to IDLE state after Command.Id.STOP in PROCESSING state.
TEST_P(AudioEffectTest, IdleStateAfterStop) {
- OpenEffects();
- CommandEffects(CommandId::START);
- ExpectState(State::PROCESSING);
- CommandEffects(CommandId::STOP);
- ExpectState(State::IDLE);
- CloseEffects();
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
// An effect instance transfer to IDLE state after Command.Id.RESET in PROCESSING state.
TEST_P(AudioEffectTest, IdleStateAfterReset) {
- OpenEffects();
- CommandEffects(CommandId::START);
- ExpectState(State::PROCESSING);
- CommandEffects(CommandId::RESET);
- ExpectState(State::IDLE);
- CloseEffects();
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
-// An effect instance transfer to INIT if instance receive a close() call.
+// An effect instance transfer to INIT after IEffect.ASSERT_NO_FATAL_FAILURE(close().
TEST_P(AudioEffectTest, InitStateAfterClose) {
- OpenEffects();
- CommandEffects(CommandId::START);
- ExpectState(State::PROCESSING);
- CommandEffects(CommandId::STOP);
- ExpectState(State::IDLE);
- CloseEffects();
- ExpectState(State::INIT);
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::INIT));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
// An effect instance shouldn't accept any command before open.
TEST_P(AudioEffectTest, NoCommandAcceptedBeforeOpen) {
- ExpectState(State::INIT);
- CommandEffectsExpectStatus(CommandId::START, EX_ILLEGAL_STATE);
- CommandEffectsExpectStatus(CommandId::STOP, EX_ILLEGAL_STATE);
- CommandEffectsExpectStatus(CommandId::RESET, EX_ILLEGAL_STATE);
- ExpectState(State::INIT);
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START, EX_ILLEGAL_STATE));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP, EX_ILLEGAL_STATE));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET, EX_ILLEGAL_STATE));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
// No-op when receive STOP command in IDLE state.
TEST_P(AudioEffectTest, StopCommandInIdleStateNoOp) {
- ExpectState(State::INIT);
- OpenEffects();
- ExpectState(State::IDLE);
- CommandEffects(CommandId::STOP);
- ExpectState(State::IDLE);
- CloseEffects();
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
-// No-op when receive STOP command in IDLE state.
+// No-op when receive RESET command in IDLE state.
TEST_P(AudioEffectTest, ResetCommandInIdleStateNoOp) {
- ExpectState(State::INIT);
- OpenEffects();
- ExpectState(State::IDLE);
- CommandEffects(CommandId::RESET);
- ExpectState(State::IDLE);
- CloseEffects();
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
// Repeat START and STOP command.
TEST_P(AudioEffectTest, RepeatStartAndStop) {
- OpenEffects();
- CommandEffects(CommandId::START);
- ExpectState(State::PROCESSING);
- CommandEffects(CommandId::STOP);
- ExpectState(State::IDLE);
- CommandEffects(CommandId::START);
- ExpectState(State::PROCESSING);
- CommandEffects(CommandId::STOP);
- ExpectState(State::IDLE);
- CloseEffects();
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
// Repeat START and RESET command.
TEST_P(AudioEffectTest, RepeatStartAndReset) {
- OpenEffects();
- CommandEffects(CommandId::START);
- ExpectState(State::PROCESSING);
- CommandEffects(CommandId::RESET);
- ExpectState(State::IDLE);
- CommandEffects(CommandId::START);
- ExpectState(State::PROCESSING);
- CommandEffects(CommandId::RESET);
- ExpectState(State::IDLE);
- CloseEffects();
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
-// Repeat START and STOP command, try to close at PROCESSING state.
+// Try to close an effect instance at PROCESSING state.
TEST_P(AudioEffectTest, CloseProcessingStateEffects) {
- OpenEffects();
- CommandEffects(CommandId::START);
- ExpectState(State::PROCESSING);
- CommandEffects(CommandId::STOP);
- ExpectState(State::IDLE);
- CommandEffects(CommandId::START);
- ExpectState(State::PROCESSING);
- CloseEffects(EX_ILLEGAL_STATE);
- // cleanup
- CommandEffects(CommandId::STOP);
- ExpectState(State::IDLE);
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+ ASSERT_NO_FATAL_FAILURE(close(effect, EX_ILLEGAL_STATE));
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
// Expect EX_ILLEGAL_STATE if the effect instance is not in a proper state to be destroyed.
TEST_P(AudioEffectTest, DestroyOpenEffects) {
- // cleanup all effects.
- CloseEffects();
- DestroyEffects();
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
- // open effects, destroy without close, expect to get EX_ILLEGAL_STATE status.
- CreateEffects();
- OpenEffects();
- auto vec = GetCompleteEffectIdList();
- DestroyEffects(EX_ILLEGAL_STATE, vec.size());
- CloseEffects();
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect, EX_ILLEGAL_STATE));
+}
+
+// Expect EX_ILLEGAL_STATE if the effect instance is not in a proper state to be destroyed.
+TEST_P(AudioEffectTest, DestroyProcessingEffects) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect, EX_ILLEGAL_STATE));
+}
+
+TEST_P(AudioEffectTest, NormalSequenceStates) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::INIT));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
/// Parameter testing.
// Verify parameters pass in open can be successfully get.
-TEST_P(AudioEffectTest, VerifyParametersAfterOpen) {
- OpenEffects();
- VerifyParameters();
- CloseEffects();
+TEST_P(AudioEffectTest, VerifyCommonParametersAfterOpen) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+ Parameter::Common common = EffectHelper::createParamCommon();
+ IEffect::OpenEffectReturn ret;
+ ASSERT_NO_FATAL_FAILURE(open(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+
+ Parameter get = Parameter(), expect = Parameter();
+ expect.set<Parameter::common>(common);
+ Parameter::Id id;
+ id.set<Parameter::Id::commonTag>(Parameter::common);
+ EXPECT_IS_OK(effect->getParameter(id, &get));
+ EXPECT_EQ(expect, get) << expect.toString() << " vs " << get.toString();
+
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
// Verify parameters pass in set can be successfully get.
-TEST_P(AudioEffectTest, SetAndGetParameter) {
- OpenEffects();
- VerifyParameters();
- initParamCommon(1 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */,
- 44100 /* oSampleRate */);
- SetParameter();
- VerifyParameters();
- CloseEffects();
+TEST_P(AudioEffectTest, SetAndGetCommonParameter) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+
+ 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(effect->setParameter(set));
+
+ Parameter::Id id;
+ id.set<Parameter::Id::commonTag>(Parameter::common);
+ EXPECT_IS_OK(effect->getParameter(id, &get));
+ EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
-// Verify parameters pass in set can be successfully get.
+// Verify parameters set and get in PROCESSING state.
TEST_P(AudioEffectTest, SetAndGetParameterInProcessing) {
- OpenEffects();
- VerifyParameters();
- CommandEffects(CommandId::START);
- ExpectState(State::PROCESSING);
- initParamCommon(1 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */,
- 44100 /* oSampleRate */);
- SetParameter();
- VerifyParameters();
- CommandEffects(CommandId::STOP);
- ExpectState(State::IDLE);
- CloseEffects();
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+ 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(effect->setParameter(set));
+
+ Parameter::Id id;
+ id.set<Parameter::Id::commonTag>(Parameter::common);
+ EXPECT_IS_OK(effect->getParameter(id, &get));
+ EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
-// Parameters kept after reset.
-TEST_P(AudioEffectTest, ResetAndVerifyParameter) {
- OpenEffects();
- VerifyParameters();
- CommandEffects(CommandId::START);
- ExpectState(State::PROCESSING);
- initParamCommon(1 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */,
- 44100 /* oSampleRate */);
- SetParameter();
- VerifyParameters();
- CommandEffects(CommandId::RESET);
- ExpectState(State::IDLE);
- VerifyParameters();
- CloseEffects();
+// Verify parameters set and get in IDLE state.
+TEST_P(AudioEffectTest, SetAndGetParameterInIdle) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+ 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(effect->setParameter(set));
+
+ Parameter::Id id;
+ id.set<Parameter::Id::commonTag>(Parameter::common);
+ EXPECT_IS_OK(effect->getParameter(id, &get));
+ EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
-// TODO: need a way to support setting different sessionId to different effect instances
-#if 0
-// Multiple instances of same implementation running.
-TEST_P(AudioEffectTest, MultipleInstancesRunningWithDiffSessionId) {
- CreateEffects();
- ExpectState(State::INIT);
- OpenEffects();
- ExpectState(State::IDLE);
- CommandEffects(CommandId::START);
- ExpectState(State::PROCESSING);
- initParamCommon(1 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */,
- 44100 /* oSampleRate */);
- SetParameter();
- VerifyParameters();
- CommandEffects(CommandId::STOP);
- ExpectState(State::IDLE);
- VerifyParameters();
- CloseEffects();
-}
-#endif
+// Verify Parameters kept after stop.
+TEST_P(AudioEffectTest, SetAndGetParameterAfterStop) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
-// Send data to effects and expect it to consume by check statusMQ.
-TEST_P(AudioEffectTest, ExpectEffectsToConsumeDataInMQ) {
- OpenEffects();
- PrepareInputData(mWriteMQBytes);
+ 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(effect->setParameter(set));
- CommandEffects(CommandId::START);
- writeToFmq(mWriteMQBytes);
- readFromFmq(mWriteMQBytes);
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
- ExpectState(State::PROCESSING);
- CommandEffects(CommandId::STOP);
- // cleanup
- CommandEffects(CommandId::STOP);
- ExpectState(State::IDLE);
- CloseEffects();
+ Parameter::Id id;
+ id.set<Parameter::Id::commonTag>(Parameter::common);
+ EXPECT_IS_OK(effect->getParameter(id, &get));
+ EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
}
-INSTANTIATE_TEST_SUITE_P(AudioEffectTestTest, AudioEffectTest,
- testing::ValuesIn(android::getAidlHalInstanceNames(IFactory::descriptor)),
- android::PrintInstanceNameToString);
+// Verify Parameters kept after reset.
+TEST_P(AudioEffectTest, SetAndGetParameterAfterReset) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(open(effect));
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+ 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(effect->setParameter(set));
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+ Parameter::Id id;
+ id.set<Parameter::Id::commonTag>(Parameter::common);
+ EXPECT_IS_OK(effect->getParameter(id, &get));
+ EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+/// Data processing test
+// Send data to effects and expect it to be consumed by checking statusMQ.
+TEST_P(AudioEffectTest, ConsumeDataInProcessingState) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+ 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(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+ auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+ auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+ auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+ std::vector<float> buffer;
+ EffectHelper::allocateInputData(common, inputMQ, buffer);
+ EffectHelper::writeToFmq(inputMQ, buffer);
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+// Send data to effects and expect it to be consumed after effect restart.
+TEST_P(AudioEffectTest, ConsumeDataAfterRestart) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+ 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(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+ auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+ auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+ auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+ std::vector<float> buffer;
+ EffectHelper::allocateInputData(common, inputMQ, buffer);
+ EffectHelper::writeToFmq(inputMQ, buffer);
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+// Send data to IDLE effects and expect it to be consumed after effect start.
+TEST_P(AudioEffectTest, SendDataAtIdleAndConsumeDataInProcessing) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+ 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(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+ auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+ auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+ auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+
+ std::vector<float> buffer;
+ EffectHelper::allocateInputData(common, inputMQ, buffer);
+ EffectHelper::writeToFmq(inputMQ, buffer);
+ EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+// Send data multiple times.
+TEST_P(AudioEffectTest, ProcessDataMultipleTimes) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+ 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(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+ auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+ auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+ auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+
+ std::vector<float> buffer;
+ EffectHelper::allocateInputData(common, inputMQ, buffer);
+ EffectHelper::writeToFmq(inputMQ, buffer);
+ EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+ // expect no status and data after consume
+ EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+
+ EffectHelper::writeToFmq(inputMQ, buffer);
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+ // expect no status and data after consume
+ EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+// Send data to IDLE state effects and expect it not be consumed.
+TEST_P(AudioEffectTest, NotConsumeDataInIdleState) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+ 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(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+ auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+ auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+ auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+ std::vector<float> buffer;
+ EffectHelper::allocateInputData(common, inputMQ, buffer);
+ EffectHelper::writeToFmq(inputMQ, buffer);
+ EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+
+ ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+// Send data to closed effects and expect it not be consumed.
+TEST_P(AudioEffectTest, NotConsumeDataByClosedEffect) {
+ std::shared_ptr<IEffect> effect;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect, mIdentity));
+
+ 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(effect, common, std::nullopt /* specific */, &ret, EX_NONE));
+ ASSERT_NO_FATAL_FAILURE(close(effect));
+
+ auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+ auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+ auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+
+ std::vector<float> buffer;
+ EffectHelper::allocateInputData(common, inputMQ, buffer);
+ EffectHelper::writeToFmq(inputMQ, buffer);
+ EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect));
+}
+
+// Send data to multiple effects.
+TEST_P(AudioEffectTest, ConsumeDataMultipleEffects) {
+ std::shared_ptr<IEffect> effect1, effect2;
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect1, mIdentity));
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, effect2, mIdentity));
+
+ Parameter::Common common1 = EffectHelper::createParamCommon(
+ 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+ kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+ Parameter::Common common2 = EffectHelper::createParamCommon(
+ 1 /* session */, 1 /* ioHandle */, 48000 /* iSampleRate */, 48000 /* oSampleRate */,
+ 2 * kInputFrameCount /* iFrameCount */, 2 * kOutputFrameCount /* oFrameCount */);
+ IEffect::OpenEffectReturn ret1, ret2;
+ ASSERT_NO_FATAL_FAILURE(open(effect1, common1, std::nullopt /* specific */, &ret1, EX_NONE));
+ ASSERT_NO_FATAL_FAILURE(open(effect2, common2, std::nullopt /* specific */, &ret2, EX_NONE));
+ ASSERT_NO_FATAL_FAILURE(command(effect1, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect1, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(effect2, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect2, State::PROCESSING));
+
+ auto statusMQ1 = std::make_unique<EffectHelper::StatusMQ>(ret1.statusMQ);
+ auto inputMQ1 = std::make_unique<EffectHelper::DataMQ>(ret1.inputDataMQ);
+ auto outputMQ1 = std::make_unique<EffectHelper::DataMQ>(ret1.outputDataMQ);
+
+ std::vector<float> buffer1, buffer2;
+ EffectHelper::allocateInputData(common1, inputMQ1, buffer1);
+ EffectHelper::writeToFmq(inputMQ1, buffer1);
+ EffectHelper::readFromFmq(statusMQ1, 1, outputMQ1, buffer1.size(), buffer1);
+
+ auto statusMQ2 = std::make_unique<EffectHelper::StatusMQ>(ret2.statusMQ);
+ auto inputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.inputDataMQ);
+ auto outputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.outputDataMQ);
+ EffectHelper::allocateInputData(common2, inputMQ2, buffer2);
+ EffectHelper::writeToFmq(inputMQ2, buffer2);
+ EffectHelper::readFromFmq(statusMQ2, 1, outputMQ2, buffer2.size(), buffer2);
+
+ ASSERT_NO_FATAL_FAILURE(command(effect1, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect1, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(effect1));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect1));
+
+ ASSERT_NO_FATAL_FAILURE(command(effect2, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(effect2, State::IDLE));
+ ASSERT_NO_FATAL_FAILURE(close(effect2));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect2));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ SingleEffectInstanceTest, AudioEffectTest,
+ ::testing::Combine(testing::ValuesIn(
+ EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor))),
+ [](const testing::TestParamInfo<AudioEffectTest::ParamType>& info) {
+ auto msSinceEpoch = std::chrono::duration_cast<std::chrono::nanoseconds>(
+ std::chrono::system_clock::now().time_since_epoch())
+ .count();
+ auto instance = std::get<PARAM_INSTANCE_NAME>(info.param);
+ std::ostringstream address;
+ address << msSinceEpoch << "_factory_" << instance.first.get();
+ std::string name = address.str() + "_UUID_timeLow_" +
+ ::android::internal::ToString(instance.second.uuid.timeLow) +
+ "_timeMid_" +
+ ::android::internal::ToString(instance.second.uuid.timeMid);
+ std::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioEffectTest);
int main(int argc, char** argv) {
diff --git a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
index 4162551..f19dff6 100644
--- a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
@@ -35,8 +35,6 @@
#include <Utils.h>
#include <aidl/android/hardware/audio/effect/IEffect.h>
#include <aidl/android/hardware/audio/effect/IFactory.h>
-#include <aidl/android/media/audio/common/AudioChannelLayout.h>
-#include <aidl/android/media/audio/common/AudioDeviceType.h>
#include "AudioHalBinderServiceUtil.h"
#include "EffectHelper.h"
@@ -47,103 +45,126 @@
using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::EffectNullUuid;
using aidl::android::hardware::audio::effect::Equalizer;
-using aidl::android::hardware::audio::effect::EqualizerTypeUUID;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::kEqualizerTypeUUID;
using aidl::android::hardware::audio::effect::Parameter;
/**
- * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
- * VtsAudioEfectTargetTest.
+ * Here we focus on specific effect (equalizer) parameter checking, general IEffect interfaces
+ * testing performed in VtsAudioEfectTargetTest.
*/
-enum ParamName { PARAM_INSTANCE_NAME, PARAM_PRESET_INDEX, PARAM_BAND_INDEX, PARAM_BAND_LEVEL };
-using EqualizerParamTestParam = std::tuple<std::string, int, int, int>;
+
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_BAND_LEVEL };
+using EqualizerParamTestParam =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>, int>;
/*
Testing parameter range, assuming the parameter supported by effect is in this range.
This range is verified with IEffect.getDescriptor(), for any index supported vts expect EX_NONE
from IEffect.setParameter(), otherwise expect EX_ILLEGAL_ARGUMENT.
*/
-constexpr std::pair<int, int> kPresetIndexRange = {-1, 10}; // valid range [0, 9]
-constexpr std::pair<int, int> kBandIndexRange = {-1, 5}; // valid range [0, 4]
-constexpr std::pair<int, int> kBandLevelRange = {-5, 5}; // needs update with implementation
+const std::vector<int> kBandLevels = {0, -10, 10}; // needs update with implementation
-class EqualizerParamTest : public ::testing::TestWithParam<EqualizerParamTestParam>,
- public EffectHelper {
+class EqualizerTest : public ::testing::TestWithParam<EqualizerParamTestParam>,
+ public EffectHelper {
public:
- EqualizerParamTest()
- : EffectHelper(std::get<PARAM_INSTANCE_NAME>(GetParam())),
- mParamPresetIndex(std::get<PARAM_PRESET_INDEX>(GetParam())),
- mParamBandIndex(std::get<PARAM_BAND_INDEX>(GetParam())),
- mParamBandLevel(std::get<PARAM_BAND_LEVEL>(GetParam())) {}
+ EqualizerTest() : mBandLevel(std::get<PARAM_BAND_LEVEL>(GetParam())) {
+ std::tie(mFactory, mIdentity) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+ }
void SetUp() override {
- CreateEffectsWithUUID(EqualizerTypeUUID);
- initParamCommonFormat();
- initParamCommon();
- initParamSpecific();
- OpenEffects(EqualizerTypeUUID);
- SCOPED_TRACE(testing::Message() << "preset: " << mParamPresetIndex << " bandIdx "
- << mParamBandIndex << " level " << mParamBandLevel);
- }
+ ASSERT_NE(nullptr, mFactory);
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mIdentity));
+ 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);
+ ASSERT_NO_FATAL_FAILURE(setTagRange());
+ }
void TearDown() override {
- CloseEffects();
- DestroyEffects();
- CleanUp();
+ ASSERT_NO_FATAL_FAILURE(close(mEffect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
}
- int mParamPresetIndex = 0;
- int mParamBandIndex = 0;
- int mParamBandLevel = 0;
+ std::pair<int, int> setPresetIndexRange(const Equalizer::Capability& cap) const {
+ const auto [min, max] =
+ std::minmax_element(cap.presets.begin(), cap.presets.end(),
+ [](const auto& a, const auto& b) { return a.index < b.index; });
+ return {min->index, max->index};
+ }
+ std::pair<int, int> setBandIndexRange(const Equalizer::Capability& cap) const {
+ const auto [min, max] =
+ std::minmax_element(cap.bandFrequencies.begin(), cap.bandFrequencies.end(),
+ [](const auto& a, const auto& b) { return a.index < b.index; });
+ return {min->index, max->index};
+ }
+ void setTagRange() {
+ Descriptor desc;
+ ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+ Equalizer::Capability& eqCap = desc.capability.get<Capability::equalizer>();
+ mPresetIndex = setPresetIndexRange(eqCap);
+ mBandIndex = setBandIndexRange(eqCap);
+ }
+
+ static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+ std::shared_ptr<IFactory> mFactory;
+ std::shared_ptr<IEffect> mEffect;
+ Descriptor::Identity mIdentity;
+ std::pair<int, int> mPresetIndex;
+ std::pair<int, int> mBandIndex;
+ const int mBandLevel;
+ Descriptor mDesc;
void SetAndGetEqualizerParameters() {
- auto functor = [&](const std::shared_ptr<IEffect>& effect) {
- for (auto& it : mTags) {
- auto& tag = it.first;
- auto& eq = it.second;
+ ASSERT_NE(nullptr, mEffect);
+ for (auto& it : mTags) {
+ auto& tag = it.first;
+ auto& eq = it.second;
- // validate parameter
- Descriptor desc;
- ASSERT_STATUS(EX_NONE, effect->getDescriptor(&desc));
- const bool valid = isTagInRange(it.first, it.second, desc);
- const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+ // validate parameter
+ const bool valid = isTagInRange(it.first, it.second);
+ const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
- // set
- Parameter expectParam;
- Parameter::Specific specific;
- specific.set<Parameter::Specific::equalizer>(*eq.get());
- expectParam.set<Parameter::specific>(specific);
- EXPECT_STATUS(expected, effect->setParameter(expectParam))
- << expectParam.toString();
+ // set
+ Parameter expectParam;
+ Parameter::Specific specific;
+ specific.set<Parameter::Specific::equalizer>(eq);
+ expectParam.set<Parameter::specific>(specific);
+ EXPECT_STATUS(expected, mEffect->setParameter(expectParam))
+ << expectParam.toString() << "\n"
+ << mDesc.toString();
- // only get if parameter in range and set success
- if (expected == EX_NONE) {
- Parameter getParam;
- Parameter::Id id;
- Equalizer::Id eqId;
- eqId.set<Equalizer::Id::commonTag>(tag);
- id.set<Parameter::Id::equalizerTag>(eqId);
- // if set success, then get should match
- EXPECT_STATUS(expected, effect->getParameter(id, &getParam));
- EXPECT_TRUE(isEqParameterExpected(expectParam, getParam));
- }
+ // only get if parameter in range and set success
+ if (expected == EX_NONE) {
+ Parameter getParam;
+ Parameter::Id id;
+ Equalizer::Id eqId;
+ eqId.set<Equalizer::Id::commonTag>(tag);
+ id.set<Parameter::Id::equalizerTag>(eqId);
+ // if set success, then get should match
+ EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+ EXPECT_TRUE(isEqParameterExpected(expectParam, getParam))
+ << "\nexpect:" << expectParam.toString()
+ << "\ngetParam:" << getParam.toString();
}
- };
- EXPECT_NO_FATAL_FAILURE(ForEachEffect(functor));
+ }
}
bool isEqParameterExpected(const Parameter& expect, const Parameter& target) {
- // if parameter same, then for sure matched
+ // if parameter same, then for sure they are matched
if (expect == target) return true;
// if not, see if target include the expect parameter, and others all default (0).
/*
- This is verify the case of client setParameter to a single bandLevel ({3, -1} for
- example), and return of getParameter must be [{0, 0}, {1, 0}, {2, 0}, {3, -1}, {4, 0}]
- */
+ * This is to verify the case of client setParameter to a single bandLevel ({3, -1} for
+ * example), and return of getParameter must be [{0, 0}, {1, 0}, {2, 0}, {3, -1}, {4, 0}]
+ */
EXPECT_EQ(expect.getTag(), Parameter::specific);
EXPECT_EQ(target.getTag(), Parameter::specific);
@@ -160,10 +181,16 @@
switch (eqTag) {
case Equalizer::bandLevels: {
auto expectBl = expectEq.get<Equalizer::bandLevels>();
+ std::sort(expectBl.begin(), expectBl.end(),
+ [](const auto& a, const auto& b) { return a.index < b.index; });
+ expectBl.erase(std::unique(expectBl.begin(), expectBl.end()), expectBl.end());
auto targetBl = targetEq.get<Equalizer::bandLevels>();
return std::includes(targetBl.begin(), targetBl.end(), expectBl.begin(),
expectBl.end());
}
+ case Equalizer::preset: {
+ return expectEq.get<Equalizer::preset>() == targetEq.get<Equalizer::preset>();
+ }
default:
return false;
}
@@ -173,27 +200,24 @@
void addPresetParam(int preset) {
Equalizer eq;
eq.set<Equalizer::preset>(preset);
- mTags.push_back({Equalizer::preset, std::make_unique<Equalizer>(std::move(eq))});
+ mTags.push_back({Equalizer::preset, eq});
}
void addBandLevelsParam(std::vector<Equalizer::BandLevel>& bandLevels) {
Equalizer eq;
eq.set<Equalizer::bandLevels>(bandLevels);
- mTags.push_back({Equalizer::bandLevels, std::make_unique<Equalizer>(std::move(eq))});
+ mTags.push_back({Equalizer::bandLevels, eq});
}
- bool isTagInRange(const Equalizer::Tag& tag, const std::unique_ptr<Equalizer>& eq,
- const Descriptor& desc) const {
- std::cout << "xxx" << toString(tag) << " " << desc.toString();
- const Equalizer::Capability& eqCap = desc.capability.get<Capability::equalizer>();
+ bool isTagInRange(const Equalizer::Tag& tag, const Equalizer& eq) const {
switch (tag) {
case Equalizer::preset: {
- int index = eq->get<Equalizer::preset>();
- return isPresetIndexInRange(eqCap, index);
+ int index = eq.get<Equalizer::preset>();
+ return index >= mPresetIndex.first && index <= mPresetIndex.second;
}
case Equalizer::bandLevels: {
- auto& bandLevel = eq->get<Equalizer::bandLevels>();
- return isBandIndexInRange(eqCap, bandLevel);
+ auto& bandLevel = eq.get<Equalizer::bandLevels>();
+ return isBandInRange(bandLevel);
}
default:
return false;
@@ -201,78 +225,125 @@
return false;
}
- bool isPresetIndexInRange(const Equalizer::Capability& cap, int idx) const {
- const auto [min, max] =
- std::minmax_element(cap.presets.begin(), cap.presets.end(),
- [](const auto& a, const auto& b) { return a.index < b.index; });
- return idx >= min->index && idx <= max->index;
- }
-
- bool isBandIndexInRange(const Equalizer::Capability& cap,
- const std::vector<Equalizer::BandLevel>& bandLevel) const {
+ bool isBandInRange(const std::vector<Equalizer::BandLevel>& bandLevel) const {
for (auto& it : bandLevel) {
- if (!isBandIndexInRange(cap, it.index)) return false;
+ if (it.index < mBandIndex.first || it.index > mBandIndex.second) return false;
}
return true;
}
- bool isBandIndexInRange(const Equalizer::Capability& cap, int idx) const {
- const auto [min, max] =
- std::minmax_element(cap.bandFrequencies.begin(), cap.bandFrequencies.end(),
- [](const auto& a, const auto& b) { return a.index < b.index; });
- return idx >= min->index && idx <= max->index;
+ Parameter::Specific getDefaultParamSpecific() {
+ Equalizer eq = Equalizer::make<Equalizer::preset>(0);
+ Parameter::Specific specific =
+ Parameter::Specific::make<Parameter::Specific::equalizer>(eq);
+ return specific;
}
private:
- std::vector<std::pair<Equalizer::Tag, std::unique_ptr<Equalizer>>> mTags;
+ std::vector<std::pair<Equalizer::Tag, Equalizer>> mTags;
bool validCapabilityTag(Capability& cap) { return cap.getTag() == Capability::equalizer; }
- void initParamSpecific() {
- Equalizer eq;
- eq.set<Equalizer::preset>(0);
- Parameter::Specific specific;
- specific.set<Parameter::Specific::equalizer>(eq);
- setSpecific(specific);
- }
-
void CleanUp() { mTags.clear(); }
};
-TEST_P(EqualizerParamTest, SetAndGetPreset) {
- EXPECT_NO_FATAL_FAILURE(addPresetParam(mParamPresetIndex));
- SetAndGetEqualizerParameters();
+TEST_P(EqualizerTest, SetAndGetPresetOutOfLowerBound) {
+ addPresetParam(mPresetIndex.second - 1);
+ ASSERT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
}
-TEST_P(EqualizerParamTest, SetAndGetSingleBand) {
- std::vector<Equalizer::BandLevel> bandLevels;
- Equalizer::BandLevel bandLevel = {mParamBandIndex, mParamBandLevel};
- bandLevels.push_back(bandLevel);
- EXPECT_NO_FATAL_FAILURE(addBandLevelsParam(bandLevels));
- SetAndGetEqualizerParameters();
+TEST_P(EqualizerTest, SetAndGetPresetOutOfUpperBound) {
+ addPresetParam(mPresetIndex.second + 1);
+ EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetPresetAtLowerBound) {
+ addPresetParam(mPresetIndex.first);
+ EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetPresetAtHigherBound) {
+ addPresetParam(mPresetIndex.second);
+ EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetPresetInBound) {
+ addPresetParam((mPresetIndex.first + mPresetIndex.second) >> 1);
+ EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetBandOutOfLowerBound) {
+ std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.first - 1, mBandLevel}};
+ addBandLevelsParam(bandLevels);
+ EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetBandOutOfUpperBound) {
+ std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.second + 1, mBandLevel}};
+ addBandLevelsParam(bandLevels);
+ EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetBandAtLowerBound) {
+ std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.first, mBandLevel}};
+ addBandLevelsParam(bandLevels);
+ EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetBandAtHigherBound) {
+ std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.second, mBandLevel}};
+ addBandLevelsParam(bandLevels);
+ EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetBandInBound) {
+ std::vector<Equalizer::BandLevel> bandLevels{
+ {(mBandIndex.first + mBandIndex.second) >> 1, mBandLevel}};
+ addBandLevelsParam(bandLevels);
+ EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetMultiBands) {
+ addPresetParam(mPresetIndex.first);
+ std::vector<Equalizer::BandLevel> bandLevels{
+ {mBandIndex.first, mBandLevel},
+ {mBandIndex.second, mBandLevel},
+ {(mBandIndex.first + mBandIndex.second) >> 1, mBandLevel}};
+ addBandLevelsParam(bandLevels);
+ EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+TEST_P(EqualizerTest, SetAndGetMultipleParams) {
+ std::vector<Equalizer::BandLevel> bandLevels{
+ {(mBandIndex.first + mBandIndex.second) >> 1, mBandLevel}};
+ addBandLevelsParam(bandLevels);
+ addPresetParam((mPresetIndex.first + mPresetIndex.second) >> 1);
+ EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
}
INSTANTIATE_TEST_SUITE_P(
- EqualizerTest, EqualizerParamTest,
- ::testing::Combine(
- testing::ValuesIn(android::getAidlHalInstanceNames(IFactory::descriptor)),
- testing::Range(kPresetIndexRange.first, kPresetIndexRange.second),
- testing::Range(kBandIndexRange.first, kBandIndexRange.second),
- testing::Range(kBandLevelRange.first, kBandLevelRange.second)),
- [](const testing::TestParamInfo<EqualizerParamTest::ParamType>& info) {
- std::string instance = std::get<PARAM_INSTANCE_NAME>(info.param);
- std::string presetIdx = std::to_string(std::get<PARAM_PRESET_INDEX>(info.param));
- std::string bandIdx = std::to_string(std::get<PARAM_BAND_INDEX>(info.param));
+ EqualizerTest, EqualizerTest,
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kEqualizerTypeUUID)),
+ testing::ValuesIn(kBandLevels)),
+ [](const testing::TestParamInfo<EqualizerTest::ParamType>& info) {
+ auto msSinceEpoch = std::chrono::duration_cast<std::chrono::nanoseconds>(
+ std::chrono::system_clock::now().time_since_epoch())
+ .count();
+ auto instance = std::get<PARAM_INSTANCE_NAME>(info.param);
std::string bandLevel = std::to_string(std::get<PARAM_BAND_LEVEL>(info.param));
-
- std::string name = instance + "_presetIndex" + presetIdx + "_bandIndex" + bandIdx +
- "_bandLevel" + bandLevel;
+ std::ostringstream address;
+ address << msSinceEpoch << "_factory_" << instance.first.get();
+ std::string name = address.str() + "_UUID_timeLow_" +
+ ::android::internal::ToString(instance.second.uuid.timeLow) +
+ "_timeMid_" +
+ ::android::internal::ToString(instance.second.uuid.timeMid) +
+ "_bandLevel_" + bandLevel;
std::replace_if(
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
return name;
});
-
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EqualizerParamTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EqualizerTest);
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index 2ad016d..1485657 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -27,8 +27,8 @@
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::kLoudnessEnhancerTypeUUID;
using aidl::android::hardware::audio::effect::LoudnessEnhancer;
-using aidl::android::hardware::audio::effect::LoudnessEnhancerTypeUUID;
using aidl::android::hardware::audio::effect::Parameter;
/**
@@ -36,7 +36,8 @@
* VtsAudioEffectTargetTest.
*/
enum ParamName { PARAM_INSTANCE_NAME, PARAM_GAIN_MB };
-using LoudnessEnhancerParamTestParam = std::tuple<std::string, int>;
+using LoudnessEnhancerParamTestParam =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor::Identity>, int>;
// Every int 32 bit value is a valid gain, so testing the corner cases and one regular value.
// TODO : Update the test values once range/capability is updated by implementation.
@@ -46,53 +47,64 @@
class LoudnessEnhancerParamTest : public ::testing::TestWithParam<LoudnessEnhancerParamTestParam>,
public EffectHelper {
public:
- LoudnessEnhancerParamTest()
- : EffectHelper(std::get<PARAM_INSTANCE_NAME>(GetParam())),
- mParamGainMb(std::get<PARAM_GAIN_MB>(GetParam())) {}
+ LoudnessEnhancerParamTest() : mParamGainMb(std::get<PARAM_GAIN_MB>(GetParam())) {
+ std::tie(mFactory, mIdentity) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+ }
void SetUp() override {
- CreateEffectsWithUUID(LoudnessEnhancerTypeUUID);
- initParamCommonFormat();
- initParamCommon();
- initParamSpecific();
- OpenEffects(LoudnessEnhancerTypeUUID);
- SCOPED_TRACE(testing::Message() << "gainMb: " << mParamGainMb);
- }
+ ASSERT_NE(nullptr, mFactory);
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mIdentity));
+ 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 {
- CloseEffects();
- DestroyEffects();
- CleanUp();
+ ASSERT_NO_FATAL_FAILURE(close(mEffect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
}
+ Parameter::Specific getDefaultParamSpecific() {
+ LoudnessEnhancer le = LoudnessEnhancer::make<LoudnessEnhancer::gainMb>(0);
+ Parameter::Specific specific =
+ Parameter::Specific::make<Parameter::Specific::loudnessEnhancer>(le);
+ return specific;
+ }
+
+ static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+ std::shared_ptr<IFactory> mFactory;
+ std::shared_ptr<IEffect> mEffect;
+ Descriptor::Identity mIdentity;
int mParamGainMb = 0;
- void SetAndGetLoudnessEnhancerParameters() {
- auto functor = [&](const std::shared_ptr<IEffect>& effect) {
- for (auto& it : mTags) {
- auto& tag = it.first;
- auto& le = it.second;
+ void SetAndGetParameters() {
+ for (auto& it : mTags) {
+ auto& tag = it.first;
+ auto& le = it.second;
- // set parameter
- Parameter expectParam;
- Parameter::Specific specific;
- specific.set<Parameter::Specific::loudnessEnhancer>(le);
- expectParam.set<Parameter::specific>(specific);
- // All values are valid, set parameter should succeed
- EXPECT_STATUS(EX_NONE, effect->setParameter(expectParam)) << expectParam.toString();
+ // set parameter
+ Parameter expectParam;
+ Parameter::Specific specific;
+ specific.set<Parameter::Specific::loudnessEnhancer>(le);
+ expectParam.set<Parameter::specific>(specific);
+ // All values are valid, set parameter should succeed
+ EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectParam)) << expectParam.toString();
- // get parameter
- Parameter getParam;
- Parameter::Id id;
- LoudnessEnhancer::Id leId;
- leId.set<LoudnessEnhancer::Id::commonTag>(tag);
- id.set<Parameter::Id::loudnessEnhancerTag>(leId);
- EXPECT_STATUS(EX_NONE, effect->getParameter(id, &getParam));
+ // get parameter
+ Parameter getParam;
+ Parameter::Id id;
+ LoudnessEnhancer::Id leId;
+ leId.set<LoudnessEnhancer::Id::commonTag>(tag);
+ id.set<Parameter::Id::loudnessEnhancerTag>(leId);
+ EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
- EXPECT_EQ(expectParam, getParam);
- }
- };
- EXPECT_NO_FATAL_FAILURE(ForEachEffect(functor));
+ EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+ << "\ngetParam:" << getParam.toString();
+ }
}
void addGainMbParam(int gainMb) {
@@ -103,33 +115,33 @@
private:
std::vector<std::pair<LoudnessEnhancer::Tag, LoudnessEnhancer>> mTags;
-
- void initParamSpecific() {
- LoudnessEnhancer le;
- le.set<LoudnessEnhancer::gainMb>(0);
- Parameter::Specific specific;
- specific.set<Parameter::Specific::loudnessEnhancer>(le);
- setSpecific(specific);
- }
-
void CleanUp() { mTags.clear(); }
};
TEST_P(LoudnessEnhancerParamTest, SetAndGetGainMb) {
EXPECT_NO_FATAL_FAILURE(addGainMbParam(mParamGainMb));
- SetAndGetLoudnessEnhancerParameters();
+ SetAndGetParameters();
}
INSTANTIATE_TEST_SUITE_P(
LoudnessEnhancerTest, LoudnessEnhancerParamTest,
- ::testing::Combine(
- testing::ValuesIn(android::getAidlHalInstanceNames(IFactory::descriptor)),
- testing::ValuesIn(kGainMbValues)),
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kLoudnessEnhancerTypeUUID)),
+ testing::ValuesIn(kGainMbValues)),
[](const testing::TestParamInfo<LoudnessEnhancerParamTest::ParamType>& info) {
- std::string instance = std::get<PARAM_INSTANCE_NAME>(info.param);
+ auto msSinceEpoch = std::chrono::duration_cast<std::chrono::nanoseconds>(
+ std::chrono::system_clock::now().time_since_epoch())
+ .count();
+ auto instance = std::get<PARAM_INSTANCE_NAME>(info.param);
std::string gainMb = std::to_string(std::get<PARAM_GAIN_MB>(info.param));
- std::string name = instance + "_gainMb" + gainMb;
+ std::ostringstream address;
+ address << msSinceEpoch << "_factory_" << instance.first.get();
+ std::string name = address.str() + "_UUID_timeLow_" +
+ ::android::internal::ToString(instance.second.uuid.timeLow) +
+ "_timeMid_" +
+ ::android::internal::ToString(instance.second.uuid.timeMid) +
+ "_gainMb" + gainMb;
std::replace_if(
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
return name;
diff --git a/automotive/remoteaccess/test_grpc_server/README.md b/automotive/remoteaccess/test_grpc_server/README.md
index 28035de..6bc1829 100644
--- a/automotive/remoteaccess/test_grpc_server/README.md
+++ b/automotive/remoteaccess/test_grpc_server/README.md
@@ -79,6 +79,8 @@
* `make -j TestWakeupClientServer`
+* `make -j ApPowerControlLib`
+
## How to push the test wakeup client to a TCU which runs Android.
* Make the target device writable:
@@ -97,6 +99,8 @@
* `adb push vendor/bin/TestWakeupClientServer /vendor/bin`
+* `adb push vendor/lib/ApPowerControlLib.so /vendor/lib`
+
* `adb shell`
* `su`
diff --git a/automotive/remoteaccess/test_grpc_server/impl/Android.bp b/automotive/remoteaccess/test_grpc_server/impl/Android.bp
index e978c8c..152b528 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/Android.bp
+++ b/automotive/remoteaccess/test_grpc_server/impl/Android.bp
@@ -31,6 +31,7 @@
"libutils",
"libgrpc++",
"libprotobuf-cpp-full",
+ "//hardware/interfaces/automotive/remoteaccess/test_grpc_server/lib:ApPowerControlLib",
],
whole_static_libs: [
"wakeup_client_protos",
diff --git a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
index 795265f..7dcd31e 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
@@ -16,6 +16,8 @@
#include "TestWakeupClientServiceImpl.h"
+#include "ApPowerControl.h"
+
#include <android-base/stringprintf.h>
#include <inttypes.h>
#include <utils/Looper.h>
@@ -245,8 +247,7 @@
}
void TestWakeupClientServiceImpl::wakeupApplicationProcessor() {
- printf("Waking up application processor...\n");
- // TODO(b/254547153): Send can bus message using socket CAN once we know what the message is.
+ wakeupAp();
}
} // namespace remoteaccess
diff --git a/automotive/remoteaccess/test_grpc_server/lib/Android.bp b/automotive/remoteaccess/test_grpc_server/lib/Android.bp
new file mode 100644
index 0000000..7e95f53
--- /dev/null
+++ b/automotive/remoteaccess/test_grpc_server/lib/Android.bp
@@ -0,0 +1,32 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+soong_namespace {}
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library_shared {
+ name: "ApPowerControlLib",
+ vendor: true,
+ srcs: ["*.cpp"],
+ local_include_dirs: ["."],
+ export_include_dirs: ["."],
+}
diff --git a/automotive/remoteaccess/test_grpc_server/lib/ApPowerControl.cpp b/automotive/remoteaccess/test_grpc_server/lib/ApPowerControl.cpp
new file mode 100644
index 0000000..862fed1
--- /dev/null
+++ b/automotive/remoteaccess/test_grpc_server/lib/ApPowerControl.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ApPowerControl.h"
+
+#include <cstdio>
+
+void wakeupAp() {
+ printf("Waking up application processor...\n");
+}
diff --git a/automotive/remoteaccess/test_grpc_server/lib/ApPowerControl.h b/automotive/remoteaccess/test_grpc_server/lib/ApPowerControl.h
new file mode 100644
index 0000000..9560576
--- /dev/null
+++ b/automotive/remoteaccess/test_grpc_server/lib/ApPowerControl.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Wakeup application processor if not already waken up.
+void wakeupAp();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 7c8e1f5..9e4f252 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -1632,10 +1632,8 @@
*
* The Android properties are:
*
- * int32Values[0] : Input code identifying the function representing this event. Valid event
- * types are defined by CustomInputType.CUSTOM_EVENT_F1 up to
- * CustomInputType.CUSTOM_EVENT_F10. They represent the custom event to be
- * defined by OEM partners.
+ * int32Values[0] : Input code identifying the function representing this event. OEMs are free
+ * to use any signed 32 bits number to represent the input code value.
* int32Values[1] : target display type defined in VehicleDisplay. Events not tied to specific
* display must be sent to VehicleDisplay#MAIN.
* int32Values[2] : repeat counter, if 0 then event is not repeated. Values 1 or above means
@@ -5326,10 +5324,11 @@
*/
enum CustomInputType : int32_t {
/**
- * Ten functions representing the custom input code to be defined and implemented by OEM
- * partners.
+ * Ten optional function codes to be used in case OEM don't need more than 10 input code values.
*
- * OEMs need to formally contact Android team if more than 10 functions are required.
+ * OEMs are free to use any signed 32 bits number to represent the input code value.
+ * The following function keys are only for convenience and any other integer values are
+ * also allowed.
*/
CUSTOM_EVENT_F1 = 1001,
CUSTOM_EVENT_F2 = 1002,
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
index 6913ff1..24fd518 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -158,6 +158,9 @@
SEAT_EASY_ACCESS_ENABLED = 354421661,
SEAT_AIRBAG_ENABLED = 354421662,
SEAT_CUSHION_SIDE_SUPPORT_POS = 356518815,
+ SEAT_CUSHION_SIDE_SUPPORT_MOVE = 356518816,
+ SEAT_LUMBAR_VERTICAL_POS = 356518817,
+ SEAT_LUMBAR_VERTICAL_MOVE = 356518818,
SEAT_OCCUPANCY = 356518832,
WINDOW_POS = 322964416,
WINDOW_MOVE = 322964417,
@@ -168,6 +171,7 @@
STEERING_WHEEL_HEIGHT_MOVE = 289410019,
STEERING_WHEEL_THEFT_LOCK_ENABLED = 287312868,
STEERING_WHEEL_LOCKED = 287312869,
+ STEERING_WHEEL_EASY_ACCESS_ENABLED = 287312870,
VEHICLE_MAP_SERVICE = 299895808,
OBD2_LIVE_FRAME = 299896064,
OBD2_FREEZE_FRAME = 299896065,
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
index f9ee52d..b6886c0 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -1762,6 +1762,62 @@
SEAT_CUSHION_SIDE_SUPPORT_POS =
0x0B9F + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
/**
+ * Represents property for movement direction and speed of seat cushion side support.
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers
+ * between minInt32Value and maxInt32Value must be supported.
+ *
+ * maxInt32Value in default area's VehicleAreaConfig represents the maximum movement speed of
+ * the seat cushion side support in the growing wider direction (i.e. less support).
+ * minInt32Value in default area's VehicleAreaConfig represents the maximum movement speed of
+ * the seat cushion side support in the growing thinner direction (i.e. more support).
+ *
+ * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+ * the seat cushion side support reaches the positional limit, the value resets to 0.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ SEAT_CUSHION_SIDE_SUPPORT_MOVE =
+ 0x0BA0 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+ /**
+ * Represents property for seat’s lumbar support vertical position.
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers
+ * between minInt32Value and maxInt32Value are supported.
+ *
+ * maxInt32Value indicates the highest position.
+ * minInt32Value indicates the lowest position.
+ *
+ * This value is not in any particular unit but in a specified range of steps.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ SEAT_LUMBAR_VERTICAL_POS =
+ 0x0BA1 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+ /**
+ * Represents property for vertical movement direction and speed of seat lumbar support.
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers
+ * between minInt32Value and maxInt32Value must be supported.
+ *
+ * maxInt32Value in default area's VehicleAreaConfig indicates the lumbar support is moving at
+ * the fastest upward speed.
+ * minInt32Value in default area's VehicleAreaConfig indicates the lumbar support is moving at
+ * the fastest downward speed.
+ *
+ * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+ * the seat cushion side support reaches the positional limit, the value resets to 0.
+ *
+ * This value is not in any particular unit but in a specified range of steps.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ SEAT_LUMBAR_VERTICAL_MOVE =
+ 0x0BA2 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+ /**
* Seat Occupancy
*
* Indicates whether a particular seat is occupied or not, to the best of the car's ability
@@ -1925,6 +1981,17 @@
STEERING_WHEEL_LOCKED =
0x0BE5 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
/**
+ * Steering wheel easy access feature enabled
+ *
+ * If true, the driver’s steering wheel will automatically adjust to make it easier for the
+ * driver to enter and exit the vehicle.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ STEERING_WHEEL_EASY_ACCESS_ENABLED =
+ 0x0BE6 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+ /**
* Vehicle Maps Service (VMS) message
*
* This property uses MIXED data to communicate vms messages.
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
index 9435a41..d5182dd 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
@@ -158,6 +158,9 @@
{VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_OCCUPANCY, VehiclePropertyAccess::READ},
{VehicleProperty::WINDOW_POS, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::WINDOW_MOVE, VehiclePropertyAccess::READ_WRITE},
@@ -168,6 +171,7 @@
{VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::STEERING_WHEEL_LOCKED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::VEHICLE_MAP_SERVICE, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyAccess::READ},
{VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyAccess::READ},
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
index 730d03e..47bad2c 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
@@ -158,6 +158,9 @@
{VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_OCCUPANCY, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::WINDOW_POS, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::WINDOW_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
@@ -168,6 +171,7 @@
{VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::STEERING_WHEEL_LOCKED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::VEHICLE_MAP_SERVICE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
index f73d94a..85a62d3 100644
--- a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
@@ -150,6 +150,9 @@
Map.entry(VehicleProperty.SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_AIRBAG_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_OCCUPANCY, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.WINDOW_POS, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.WINDOW_MOVE, VehiclePropertyAccess.READ_WRITE),
@@ -160,6 +163,7 @@
Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.STEERING_WHEEL_LOCKED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.VEHICLE_MAP_SERVICE, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyAccess.READ),
diff --git a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
index ee650b7..46b9663 100644
--- a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
@@ -150,6 +150,9 @@
Map.entry(VehicleProperty.SEAT_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_AIRBAG_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_OCCUPANCY, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.WINDOW_POS, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.WINDOW_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
@@ -160,6 +163,7 @@
Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.STEERING_WHEEL_LOCKED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.VEHICLE_MAP_SERVICE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
index 7cbf8f9..bd80ad5 100644
--- a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -1103,6 +1103,111 @@
]
},
{
+ "property": "VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_LUMBAR_VERTICAL_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
"property": "VehicleProperty::SEAT_OCCUPANCY",
"areas": [
{
@@ -2378,6 +2483,14 @@
}
},
{
+ "property": "VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
"property": "VehicleProperty::WHEEL_TICK",
"defaultValue": {
"int64Values": [
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index 2b2ef80..7eefe2a 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -523,6 +523,12 @@
VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
}
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelEasyAccessEnabledConfig) {
+ verifyProperty(VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyMirrorAutoFoldEnabledConfig) {
verifyProperty(VehicleProperty::MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyAccess::READ_WRITE,
VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
@@ -553,6 +559,24 @@
VehiclePropertyGroup::SYSTEM, VehicleArea::SEAT, VehiclePropertyType::INT32);
}
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatCushionSideSupportMoveConfig) {
+ verifyProperty(VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatLumbarVerticalPosConfig) {
+ verifyProperty(VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatLumbarVerticalMoveConfig) {
+ verifyProperty(VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
std::vector<ServiceDescriptor> getDescriptors() {
std::vector<ServiceDescriptor> descriptors;
for (std::string name : getAidlHalInstanceNames(IVehicle::descriptor)) {
diff --git a/biometrics/fingerprint/aidl/OWNERS b/biometrics/OWNERS
similarity index 100%
rename from biometrics/fingerprint/aidl/OWNERS
rename to biometrics/OWNERS
diff --git a/biometrics/common/aidl/Android.bp b/biometrics/common/aidl/Android.bp
index 167e0c7..3cd76fd 100644
--- a/biometrics/common/aidl/Android.bp
+++ b/biometrics/common/aidl/Android.bp
@@ -31,7 +31,5 @@
version: "2",
imports: [],
},
-
],
-
}
diff --git a/biometrics/common/aidl/OWNERS b/biometrics/common/aidl/OWNERS
deleted file mode 100644
index 36d7261..0000000
--- a/biometrics/common/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-ilyamaty@google.com
-kchyn@google.com
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl
index d4433c5..1eb8541 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.common;
+/* @hide */
@VintfStability
parcelable CommonProps {
int sensorId;
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl
index ad11dda..471ed2b 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.common;
+/* @hide */
@VintfStability
parcelable ComponentInfo {
String componentId;
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl
index 2bc6a6d..670114f 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.common;
+/* @hide */
@VintfStability
interface ICancellationSignal {
oneway void cancel();
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
index 9d1cb8f..5e184bc 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.common;
+/* @hide */
@VintfStability
parcelable OperationContext {
int id = 0;
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl
index 3da3a6a..a5b2990 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.common;
+/* @hide */
@Backing(type="byte") @VintfStability
enum OperationReason {
UNKNOWN = 0,
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl
index 6675d09..aa77322 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.common;
+/* @hide */
@Backing(type="byte") @VintfStability
enum SensorStrength {
CONVENIENCE = 0,
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl
index 2f5af5d..cdedf4f 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl
@@ -18,7 +18,9 @@
import android.hardware.biometrics.common.ComponentInfo;
import android.hardware.biometrics.common.SensorStrength;
-
+/**
+ * @hide
+ */
@VintfStability
parcelable CommonProps {
/**
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl
index b268eef..1da9cf6 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.common;
-
+/**
+ * @hide
+ */
@VintfStability
parcelable ComponentInfo {
/**
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl
index 1010256..b9b1f39 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl
@@ -15,9 +15,10 @@
*/
package android.hardware.biometrics.common;
-
+/**
+ * @hide
+ */
@VintfStability
oneway interface ICancellationSignal {
void cancel();
}
-
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
index 72fe660..a1c7a1f 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
@@ -20,6 +20,7 @@
/**
* Additional context associated with an operation.
+ * @hide
*/
@VintfStability
parcelable OperationContext {
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl
index abc25ed..a93cebc 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.common;
-
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum OperationReason {
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl
index 790691c..b5c0999 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.common;
-
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum SensorStrength {
@@ -40,4 +42,4 @@
* HardwareAuthToken(s).
*/
STRONG,
-}
\ No newline at end of file
+}
diff --git a/biometrics/common/util/Android.bp b/biometrics/common/util/Android.bp
index 918ef72..b990812 100644
--- a/biometrics/common/util/Android.bp
+++ b/biometrics/common/util/Android.bp
@@ -13,6 +13,6 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.biometrics.common-V2-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
],
}
diff --git a/biometrics/face/1.0/vts/functional/OWNERS b/biometrics/face/1.0/vts/functional/OWNERS
deleted file mode 100644
index 7651b69..0000000
--- a/biometrics/face/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 432605
-ilyamaty@google.com
diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp
index 0bec0c5..7b11335 100644
--- a/biometrics/face/aidl/Android.bp
+++ b/biometrics/face/aidl/Android.bp
@@ -14,9 +14,9 @@
"android/hardware/biometrics/face/**/*.aidl",
],
imports: [
- "android.hardware.biometrics.common",
+ "android.hardware.biometrics.common-V3",
"android.hardware.common-V2",
- "android.hardware.keymaster-V3",
+ "android.hardware.keymaster-V4",
],
stability: "vintf",
backend: {
diff --git a/biometrics/face/aidl/OWNERS b/biometrics/face/aidl/OWNERS
deleted file mode 100644
index 36d7261..0000000
--- a/biometrics/face/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-ilyamaty@google.com
-kchyn@google.com
diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp
index 63a3645..876a91f 100644
--- a/biometrics/face/aidl/default/Android.bp
+++ b/biometrics/face/aidl/default/Android.bp
@@ -16,8 +16,8 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.biometrics.face-V2-ndk",
- "android.hardware.biometrics.common-V2-ndk",
+ "android.hardware.biometrics.face-V3-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
"android.hardware.biometrics.common.thread",
"android.hardware.biometrics.common.util",
],
@@ -49,9 +49,9 @@
],
static_libs: [
"libandroid.hardware.biometrics.face.VirtualProps",
- "android.hardware.biometrics.face-V2-ndk",
- "android.hardware.biometrics.common-V2-ndk",
- "android.hardware.keymaster-V3-ndk",
+ "android.hardware.biometrics.face-V3-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
vendor: true,
diff --git a/biometrics/face/aidl/default/face-default.xml b/biometrics/face/aidl/default/face-default.xml
index e6ef842..8f2fbb8 100644
--- a/biometrics/face/aidl/default/face-default.xml
+++ b/biometrics/face/aidl/default/face-default.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.biometrics.face</name>
- <version>2</version>
+ <version>3</version>
<fqname>IFace/default</fqname>
</hal>
</manifest>
diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp
index 4171ac3..f62c4e4 100644
--- a/biometrics/face/aidl/vts/Android.bp
+++ b/biometrics/face/aidl/vts/Android.bp
@@ -15,10 +15,10 @@
],
srcs: ["VtsHalBiometricsFaceTargetTest.cpp"],
static_libs: [
- "android.hardware.biometrics.common-V2-ndk",
- "android.hardware.biometrics.face-V2-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.face-V3-ndk",
"android.hardware.common-V2-ndk",
- "android.hardware.keymaster-V3-ndk",
+ "android.hardware.keymaster-V4-ndk",
],
shared_libs: [
"libbinder_ndk",
diff --git a/biometrics/fingerprint/2.1/vts/functional/OWNERS b/biometrics/fingerprint/2.1/vts/functional/OWNERS
deleted file mode 100644
index 0014ce9..0000000
--- a/biometrics/fingerprint/2.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 114777
-ilyamaty@google.com
diff --git a/biometrics/fingerprint/2.2/vts/functional/OWNERS b/biometrics/fingerprint/2.2/vts/functional/OWNERS
deleted file mode 100644
index 0014ce9..0000000
--- a/biometrics/fingerprint/2.2/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 114777
-ilyamaty@google.com
diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp
index 0bd6422..f749822 100644
--- a/biometrics/fingerprint/aidl/Android.bp
+++ b/biometrics/fingerprint/aidl/Android.bp
@@ -14,8 +14,8 @@
"android/hardware/biometrics/fingerprint/**/*.aidl",
],
imports: [
- "android.hardware.biometrics.common",
- "android.hardware.keymaster-V3",
+ "android.hardware.biometrics.common-V3",
+ "android.hardware.keymaster-V4",
],
stability: "vintf",
backend: {
@@ -41,7 +41,5 @@
"android.hardware.keymaster-V3",
],
},
-
],
-
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index c51aa03..0cc619f 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@Backing(type="byte") @VintfStability
enum AcquiredInfo {
UNKNOWN = 0,
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
index af7bc3c..45ce2eb 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@Backing(type="byte") @VintfStability
enum Error {
UNKNOWN = 0,
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
index 9c208c4..67af20d 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@Backing(type="byte") @VintfStability
enum FingerprintSensorType {
UNKNOWN = 0,
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 5d3df6f..0b6f300 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@VintfStability
interface IFingerprint {
android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps();
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
index 30f299d..f305855 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@VintfStability
interface ISession {
void generateChallenge();
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index 3c40ad6..be18ffe 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@VintfStability
interface ISessionCallback {
void onChallengeGenerated(in long challenge);
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl
index 43db6cf..999b324 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl
@@ -32,7 +32,8 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
-@VintfStability
+/* @hide */
+@JavaDerive(equals=true) @VintfStability
parcelable PointerContext {
int pointerId = -1;
float x = 0.000000f;
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl
index 295fde9..dc6a62d 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@VintfStability
parcelable SensorLocation {
int displayId;
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
index 782d289..a77d5f2 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@VintfStability
parcelable SensorProps {
android.hardware.biometrics.common.CommonProps commonProps;
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index 8ec8574..d3aa98a 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.fingerprint;
-
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum AcquiredInfo {
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
index e69859a..d8d47fa 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.fingerprint;
-
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum Error {
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
index dbe7137..7caa154 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.fingerprint;
-
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum FingerprintSensorType {
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 75f90a1..f4febad 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -19,7 +19,9 @@
import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.biometrics.fingerprint.ISessionCallback;
import android.hardware.biometrics.fingerprint.SensorProps;
-
+/**
+ * @hide
+ */
@VintfStability
interface IFingerprint {
/**
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index db01145..f4f7804 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -45,6 +45,7 @@
* ISession only supports execution of one non-interrupting operation at a time, regardless of
* whether it's cancellable. The framework must wait for a callback indicating the end of the
* current non-interrupting operation before a new non-interrupting operation can be started.
+ * @hide
*/
@VintfStability
interface ISession {
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index f699966..24b169e 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -19,7 +19,9 @@
import android.hardware.biometrics.fingerprint.AcquiredInfo;
import android.hardware.biometrics.fingerprint.Error;
import android.hardware.keymaster.HardwareAuthToken;
-
+/**
+ * @hide
+ */
@VintfStability
interface ISessionCallback {
/**
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl
index e025d34..582e6cf 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl
@@ -18,7 +18,9 @@
/**
* Additional context associated with a pointer event.
+ * @hide
*/
+@JavaDerive(equals=true)
@VintfStability
parcelable PointerContext {
/**
@@ -64,7 +66,7 @@
boolean isAod = false;
/**
- * The time of the user interaction that produced this event, in milliseconds.
+ * The time when this event was created, in milliseconds.
*
* This is obtained from MotionEvent#getEventTime, which uses SystemClock.uptimeMillis() as
* the clock.
@@ -74,10 +76,10 @@
long time = 0;
/**
- * The time of the first user interaction in this gesture, in milliseconds.
+ * This event is part of some gesture. This is the time when MotionEvent#ACTION_DOWN was
+ * created for that gesture, in milliseconds.
*
- * If this event is MotionEvent#ACTION_DOWN, it means it's the first event in this gesture,
- * and `gestureStart` will be equal to `time`.
+ * If this event is MotionEvent#ACTION_DOWN, then this value is equal to `time`.
*
* This is obtained from MotionEvent#getDownTime, which uses SystemClock.uptimeMillis() as
* the clock.
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl
index d12605c..a065a7c 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.fingerprint;
-
+/**
+ * @hide
+ */
@VintfStability
parcelable SensorLocation {
/**
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl
index fb516da..d4e9ec6 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl
@@ -19,7 +19,9 @@
import android.hardware.biometrics.common.CommonProps;
import android.hardware.biometrics.fingerprint.FingerprintSensorType;
import android.hardware.biometrics.fingerprint.SensorLocation;
-
+/**
+ * @hide
+ */
@VintfStability
parcelable SensorProps {
/**
diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp
index 77c74e1..fe224c9 100644
--- a/biometrics/fingerprint/aidl/default/Android.bp
+++ b/biometrics/fingerprint/aidl/default/Android.bp
@@ -27,8 +27,8 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.biometrics.fingerprint-V2-ndk",
- "android.hardware.biometrics.common-V2-ndk",
+ "android.hardware.biometrics.fingerprint-V3-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
"android.hardware.biometrics.common.thread",
"android.hardware.biometrics.common.util",
],
@@ -50,9 +50,9 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V2-ndk",
- "android.hardware.biometrics.common-V2-ndk",
- "android.hardware.keymaster-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V3-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
vendor: true,
@@ -76,9 +76,9 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V2-ndk",
- "android.hardware.biometrics.common-V2-ndk",
- "android.hardware.keymaster-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V3-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
vendor: true,
@@ -100,9 +100,9 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V2-ndk",
- "android.hardware.biometrics.common-V2-ndk",
- "android.hardware.keymaster-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V3-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
vendor: true,
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-example.xml b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
index 05d1279..e977b98 100644
--- a/biometrics/fingerprint/aidl/default/fingerprint-example.xml
+++ b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.biometrics.fingerprint</name>
- <version>2</version>
+ <version>3</version>
<fqname>IFingerprint/virtual</fqname>
</hal>
</manifest>
diff --git a/biometrics/fingerprint/aidl/vts/Android.bp b/biometrics/fingerprint/aidl/vts/Android.bp
index a474f66..1652905 100644
--- a/biometrics/fingerprint/aidl/vts/Android.bp
+++ b/biometrics/fingerprint/aidl/vts/Android.bp
@@ -15,9 +15,9 @@
],
srcs: ["VtsHalBiometricsFingerprintTargetTest.cpp"],
static_libs: [
- "android.hardware.biometrics.common-V2-ndk",
- "android.hardware.biometrics.fingerprint-V2-ndk",
- "android.hardware.keymaster-V3-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V3-ndk",
+ "android.hardware.keymaster-V4-ndk",
],
shared_libs: [
"libbinder_ndk",
diff --git a/camera/provider/aidl/Android.bp b/camera/provider/aidl/Android.bp
index bb30e43..d7e613e 100644
--- a/camera/provider/aidl/Android.bp
+++ b/camera/provider/aidl/Android.bp
@@ -17,6 +17,7 @@
"android.hardware.camera.device-V2",
"android.hardware.camera.common-V1",
],
+ frozen: false,
stability: "vintf",
backend: {
java: {
diff --git a/camera/provider/aidl/aidl_api/android.hardware.camera.provider/current/android/hardware/camera/provider/ICameraProvider.aidl b/camera/provider/aidl/aidl_api/android.hardware.camera.provider/current/android/hardware/camera/provider/ICameraProvider.aidl
index c6a3b9a..c15bdee 100644
--- a/camera/provider/aidl/aidl_api/android.hardware.camera.provider/current/android/hardware/camera/provider/ICameraProvider.aidl
+++ b/camera/provider/aidl/aidl_api/android.hardware.camera.provider/current/android/hardware/camera/provider/ICameraProvider.aidl
@@ -41,7 +41,6 @@
void notifyDeviceStateChange(long deviceState);
android.hardware.camera.provider.ConcurrentCameraIdCombination[] getConcurrentCameraIds();
boolean isConcurrentStreamCombinationSupported(in android.hardware.camera.provider.CameraIdAndStreamCombination[] configs);
- void placeholder();
const long DEVICE_STATE_NORMAL = 0;
const long DEVICE_STATE_BACK_COVERED = 1;
const long DEVICE_STATE_FRONT_COVERED = 2;
diff --git a/camera/provider/aidl/android/hardware/camera/provider/ICameraProvider.aidl b/camera/provider/aidl/android/hardware/camera/provider/ICameraProvider.aidl
index 5442058..c4eba8d 100644
--- a/camera/provider/aidl/android/hardware/camera/provider/ICameraProvider.aidl
+++ b/camera/provider/aidl/android/hardware/camera/provider/ICameraProvider.aidl
@@ -304,12 +304,4 @@
*
*/
boolean isConcurrentStreamCombinationSupported(in CameraIdAndStreamCombination[] configs);
-
- /*
- * Due to a bug in vintf regarding aidl changes that are contained to fields,
- * we need a placeholder method that will be removed after this patch.
- *
- * TODO(b/237048744): Remove this once fixed.
- */
- void placeholder();
}
diff --git a/common/aidl/Android.bp b/common/aidl/Android.bp
index 43f8c4d..7f6890c 100644
--- a/common/aidl/Android.bp
+++ b/common/aidl/Android.bp
@@ -37,6 +37,7 @@
min_sdk_version: "29",
},
},
+ frozen: true,
versions: [
"1",
"2",
diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp
index a85597c..95fcc41 100644
--- a/common/fmq/aidl/Android.bp
+++ b/common/fmq/aidl/Android.bp
@@ -37,5 +37,6 @@
min_sdk_version: "29",
},
},
+ frozen: true,
versions: ["1"],
}
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 998b2b0..0be117a 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -109,19 +109,19 @@
<name>android.hardware.automotive.vehicle</name>
<interface>
<name>IVehicle</name>
- <regex-instance>.*</regex-instance>
+ <instance>default</instance>
</interface>
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.automotive.remoteaccess</name>
<interface>
<name>IRemoteAccess</name>
- <regex-instance>.*</regex-instance>
+ <instance>default</instance>
</interface>
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.biometrics.face</name>
- <version>2</version>
+ <version>3</version>
<interface>
<name>IFace</name>
<instance>default</instance>
@@ -129,7 +129,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.biometrics.fingerprint</name>
- <version>2</version>
+ <version>3</version>
<interface>
<name>IFingerprint</name>
<instance>default</instance>
@@ -268,7 +268,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.graphics.allocator</name>
- <version>1</version>
+ <version>1-2</version>
<interface>
<name>IAllocator</name>
<instance>default</instance>
@@ -282,7 +282,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="false">
+ <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 -->
<version>2.1</version>
@@ -392,6 +392,15 @@
</interface>
</hal>
<hal format="aidl" optional="true">
+ <name>android.hardware.media.c2</name>
+ <version>1</version>
+ <interface>
+ <name>IComponentStore</name>
+ <regex-instance>default[0-9]*</regex-instance>
+ <regex-instance>vendor[0-9]*_software</regex-instance>
+ </interface>
+ </hal>
+ <hal format="aidl" optional="true">
<name>android.hardware.memtrack</name>
<version>1</version>
<interface>
@@ -557,6 +566,15 @@
</interface>
</hal>
<hal format="aidl" optional="true">
+ <name>android.hardware.secure_element</name>
+ <version>1</version>
+ <interface>
+ <name>ISecureElement</name>
+ <regex-instance>eSE[1-9][0-9]*</regex-instance>
+ <regex-instance>SIM[1-9][0-9]*</regex-instance>
+ </interface>
+ </hal>
+ <hal format="aidl" optional="true">
<name>android.hardware.security.secureclock</name>
<version>1</version>
<interface>
@@ -644,6 +662,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.usb</name>
+ <version>1-2</version>
<interface>
<name>IUsb</name>
<instance>default</instance>
diff --git a/current.txt b/current.txt
index afde7b1..146ded6 100644
--- a/current.txt
+++ b/current.txt
@@ -929,4 +929,7 @@
1bac6a7c8136dfb0414fe5639eec115aa2d12927e64a0642a43fb53225f099b2 android.hardware.wifi@1.6::IWifiStaIface
0a800e010e8eb6eecdfdc96f04fd2ae2f417a79a74a7c0eec3a9f539199bccd4 android.hardware.wifi@1.6::types
+# ABI preserving changes to HALs during Android U
+2aa559cda86c358c6429114ef6bc72c1b43281e98f9eb6b4df5e7073c8d05767 android.hardware.automotive.vehicle@2.0::types
+
# There will be no more HIDL HALs. Use AIDL instead.
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
index fd07a6e..0247182 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
@@ -61,6 +61,7 @@
const int CAPABILITY_CORRELATION_VECTOR = 4096;
const int CAPABILITY_SATELLITE_PVT = 8192;
const int CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 16384;
+ const int CAPABILITY_ACCUMULATED_DELTA_RANGE = 32768;
@Backing(type="int") @VintfStability
enum GnssStatusValue {
NONE = 0,
diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
index 2b2592b..ff9feea 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
@@ -82,6 +82,9 @@
/** Capability bit mask indicating that GNSS supports measurement corrections for driving */
const int CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 1 << 14;
+ /** Capability bit mask indicating that GNSS supports accumulated delta range */
+ const int CAPABILITY_ACCUMULATED_DELTA_RANGE = 1 << 15;
+
/**
* Callback to inform framework of the GNSS HAL implementation's capabilities.
*
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 23d7999..ec86d2e 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -60,7 +60,8 @@
IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST |
IGnssCallback::CAPABILITY_SATELLITE_PVT |
IGnssCallback::CAPABILITY_CORRELATION_VECTOR |
- IGnssCallback::CAPABILITY_ANTENNA_INFO);
+ IGnssCallback::CAPABILITY_ANTENNA_INFO |
+ IGnssCallback::CAPABILITY_ACCUMULATED_DELTA_RANGE);
auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities);
if (!status.isOk()) {
ALOGE("%s: Unable to invoke callback.gnssSetCapabilitiesCb", __func__);
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index b4f2b77..7578585 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -489,7 +489,9 @@
// Validity check GnssData fields
checkGnssMeasurementClockFields(lastGnssData);
if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
- EXPECT_EQ(lastGnssData.isFullTracking, isFullTracking);
+ if (isFullTracking) {
+ EXPECT_EQ(lastGnssData.isFullTracking, isFullTracking);
+ }
}
for (const auto& measurement : lastGnssData.measurements) {
checkGnssMeasurementFields(measurement, lastGnssData);
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 31cef15..48027b6 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -1505,10 +1505,11 @@
}
/*
- * TestGnssMeasurementSetCallback
- * 1. Start measurement with 20s interval. Expect the first measurement received in 10s.
+ * TestGnssMeasurementSetCallback:
+ * This test ensures setCallback() can be called consecutively without close().
+ * 1. Start measurement with 20s interval and wait for 1 measurement.
* 2. Start measurement with 1s interval and wait for 5 measurements.
- * 3. Verify the received measurement intervals have expected mean and stddev.
+ * Verify the measurements were received at 1Hz.
*/
TEST_P(GnssHalTest, TestGnssMeasurementSetCallback) {
if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
@@ -1581,3 +1582,57 @@
status = iGnssMeasurement->close();
ASSERT_TRUE(status.isOk());
}
+
+/*
+ * TestAccumulatedDeltaRange:
+ * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
+ * 2. Start measurement with 1s interval and wait for up to 15 measurements.
+ * 3. Verify at least one measurement has a valid AccumulatedDeltaRange state.
+ */
+TEST_P(GnssHalTest, TestAccumulatedDeltaRange) {
+ if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
+ return;
+ }
+ if ((aidl_gnss_cb_->last_capabilities_ & IGnssCallback::CAPABILITY_ACCUMULATED_DELTA_RANGE) ==
+ 0) {
+ return;
+ }
+
+ ALOGD("TestAccumulatedDeltaRange");
+
+ auto callback = sp<GnssMeasurementCallbackAidl>::make();
+ sp<IGnssMeasurementInterface> iGnssMeasurement;
+ auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(iGnssMeasurement != nullptr);
+
+ IGnssMeasurementInterface::Options options;
+ options.intervalMs = 1000;
+ options.enableFullTracking = true;
+ status = iGnssMeasurement->setCallbackWithOptions(callback, options);
+ ASSERT_TRUE(status.isOk());
+
+ bool accumulatedDeltaRangeFound = false;
+ const int kNumMeasurementEvents = 15;
+
+ // setCallback at 1s interval and wait for 15 measurements
+ for (int i = 0; i < kNumMeasurementEvents; i++) {
+ GnssData lastGnssData;
+ ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastGnssData, 10));
+ EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
+ ASSERT_TRUE(lastGnssData.measurements.size() > 0);
+
+ // Validity check GnssData fields
+ checkGnssMeasurementClockFields(lastGnssData);
+ for (const auto& measurement : lastGnssData.measurements) {
+ if ((measurement.accumulatedDeltaRangeState & measurement.ADR_STATE_VALID) > 0) {
+ accumulatedDeltaRangeFound = true;
+ break;
+ }
+ }
+ if (accumulatedDeltaRangeFound) break;
+ }
+ ASSERT_TRUE(accumulatedDeltaRangeFound);
+ status = iGnssMeasurement->close();
+ ASSERT_TRUE(status.isOk());
+}
\ No newline at end of file
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index ad351f8..2aed29b 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -170,7 +170,7 @@
.agcLevelDb = 2.3,
.pseudorangeRateMps = -484.13739013671875,
.pseudorangeRateUncertaintyMps = 1.0379999876022339,
- .accumulatedDeltaRangeState = GnssMeasurement::ADR_STATE_UNKNOWN,
+ .accumulatedDeltaRangeState = GnssMeasurement::ADR_STATE_VALID,
.accumulatedDeltaRangeM = 1.52,
.accumulatedDeltaRangeUncertaintyM = 2.43,
.multipathIndicator = aidl::android::hardware::gnss::GnssMultipathIndicator::UNKNOWN,
diff --git a/graphics/Android.bp b/graphics/Android.bp
index 1e9089f..4898dbe 100644
--- a/graphics/Android.bp
+++ b/graphics/Android.bp
@@ -19,14 +19,14 @@
cc_defaults {
name: "android.hardware.graphics.allocator-ndk_static",
static_libs: [
- "android.hardware.graphics.allocator-V1-ndk",
+ "android.hardware.graphics.allocator-V2-ndk",
],
}
cc_defaults {
name: "android.hardware.graphics.allocator-ndk_shared",
shared_libs: [
- "android.hardware.graphics.allocator-V1-ndk",
+ "android.hardware.graphics.allocator-V2-ndk",
],
}
diff --git a/graphics/allocator/aidl/Android.bp b/graphics/allocator/aidl/Android.bp
index 9bdc7a6..67c7fb5 100644
--- a/graphics/allocator/aidl/Android.bp
+++ b/graphics/allocator/aidl/Android.bp
@@ -14,7 +14,7 @@
enabled: true,
support_system_process: true,
},
- vndk_use_version: "1",
+ vndk_use_version: "2",
srcs: ["android/hardware/graphics/allocator/*.aidl"],
imports: [
"android.hardware.common-V2",
@@ -39,6 +39,7 @@
min_sdk_version: "29",
},
},
+ frozen: false,
versions_with_info: [
{
version: "1",
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
new file mode 100644
index 0000000..980e246
--- /dev/null
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.graphics.allocator;
+@VintfStability
+parcelable BufferDescriptorInfo {
+ byte[128] name;
+ int width;
+ int height;
+ int layerCount;
+ 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;
+}
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 fe0b0a2..48bef16 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
@@ -34,5 +34,11 @@
package android.hardware.graphics.allocator;
@VintfStability
interface IAllocator {
+ /**
+ * @deprecated As of android.hardware.graphics.allocator-V2, this is deprecated & replaced with allocate2
+ */
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);
+ boolean isSupported(in android.hardware.graphics.allocator.BufferDescriptorInfo descriptor);
+ String getIMapperLibrarySuffix();
}
diff --git a/graphics/allocator/aidl/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl b/graphics/allocator/aidl/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
new file mode 100644
index 0000000..ffc50b8
--- /dev/null
+++ b/graphics/allocator/aidl/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.allocator;
+
+import android.hardware.graphics.common.BufferUsage;
+import android.hardware.graphics.common.PixelFormat;
+
+@VintfStability
+parcelable BufferDescriptorInfo {
+ /**
+ * The name of the buffer in ASCII. Useful for debugging/tracing.
+ */
+ byte[128] name;
+
+ /**
+ * The width specifies how many columns of pixels must be in the
+ * allocated buffer, but does not necessarily represent the offset in
+ * columns between the same column in adjacent rows. The rows may be
+ * padded.
+ */
+ int width;
+
+ /**
+ * The height specifies how many rows of pixels must be in the
+ * allocated buffer.
+ */
+ int height;
+
+ /**
+ * The number of image layers that must be in the allocated buffer.
+ */
+ int layerCount;
+
+ /**
+ * Buffer pixel format. See PixelFormat.aidl in graphics/common for
+ * valid values
+ */
+ PixelFormat format = PixelFormat.UNSPECIFIED;
+
+ /**
+ * Buffer usage mask; valid flags can be found in the definition of
+ * BufferUsage.aidl in graphics/common
+ */
+ BufferUsage usage = BufferUsage.CPU_READ_NEVER;
+
+ /**
+ * The size in bytes of the reserved region associated with the buffer.
+ * See getReservedRegion for more information.
+ */
+ long reservedSize;
+}
diff --git a/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl b/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl
index 92dfd4f..71cebd6 100644
--- a/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl
+++ b/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl
@@ -17,6 +17,7 @@
package android.hardware.graphics.allocator;
import android.hardware.graphics.allocator.AllocationResult;
+import android.hardware.graphics.allocator.BufferDescriptorInfo;
@VintfStability
interface IAllocator {
@@ -31,6 +32,43 @@
* @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
*/
AllocationResult allocate(in byte[] descriptor, in int count);
+
+ /**
+ * Allocates buffers with the properties specified by the descriptor.
+ *
+ * Allocations should be optimized for usage bits provided in the
+ * descriptor.
+ *
+ * @param descriptor Properties of the buffers to allocate. This must be
+ * obtained from IMapper::createDescriptor().
+ * @param count The number of buffers to allocate.
+ * @return An AllocationResult containing the result of the allocation
+ * @throws AllocationError on failure
+ */
+ AllocationResult allocate2(in BufferDescriptorInfo descriptor, in int count);
+
+ /**
+ * Test whether the given BufferDescriptorInfo is allocatable.
+ *
+ * If this function returns true, it means that a buffer with the given
+ * description can be allocated on this implementation, unless resource
+ * exhaustion occurs. If this function returns false, it means that the
+ * allocation of the given description will never succeed.
+ *
+ * @param description the description of the buffer
+ * @return supported whether the description is supported
+ */
+ boolean isSupported(in BufferDescriptorInfo descriptor);
+
+ /**
+ * Retrieve the library suffix to load for the IMapper SP-HAL. This library must implement the
+ * IMapper stable-C interface (android/hardware/graphics/mapper/IMapper.h).
+ *
+ * The library that will attempt to be loaded is "/vendor/lib[64]/hw/mapper.<imapper_suffix>.so"
+ */
+ String getIMapperLibrarySuffix();
}
diff --git a/graphics/allocator/aidl/vts/Android.bp b/graphics/allocator/aidl/vts/Android.bp
index a38af14..630ab2a 100644
--- a/graphics/allocator/aidl/vts/Android.bp
+++ b/graphics/allocator/aidl/vts/Android.bp
@@ -55,6 +55,7 @@
],
header_libs: [
"libhwui_internal_headers",
+ "libimapper_stablec",
],
cflags: [
"-Wall",
diff --git a/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp b/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp
index 59af5cf..09f1c15 100644
--- a/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp
+++ b/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp
@@ -25,7 +25,10 @@
#include <aidl/android/hardware/graphics/common/PixelFormat.h>
#include <aidlcommonsupport/NativeHandle.h>
#include <android/binder_manager.h>
+#include <android/dlext.h>
#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+#include <android/hardware/graphics/mapper/IMapper.h>
+#include <dlfcn.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
@@ -33,6 +36,7 @@
#include <renderthread/EglManager.h>
#include <utils/GLUtils.h>
#include <vndk/hardware_buffer.h>
+#include <vndksupport/linker.h>
#include <initializer_list>
#include <optional>
#include <string>
@@ -42,60 +46,70 @@
using namespace aidl::android::hardware::graphics::common;
using namespace android;
using namespace android::hardware;
-using namespace android::hardware::graphics::mapper::V4_0;
+using IMapper4 = android::hardware::graphics::mapper::V4_0::IMapper;
+using Error = android::hardware::graphics::mapper::V4_0::Error;
+using android::hardware::graphics::mapper::V4_0::BufferDescriptor;
using android::uirenderer::AutoEglImage;
using android::uirenderer::AutoGLFramebuffer;
using android::uirenderer::AutoSkiaGlTexture;
using android::uirenderer::renderthread::EglManager;
-static constexpr uint64_t pack(const std::initializer_list<BufferUsage>& usages) {
- uint64_t ret = 0;
- for (const auto u : usages) {
- ret |= static_cast<uint64_t>(u);
- }
- return ret;
+typedef AIMapper_Error (*AIMapper_loadIMapperFn)(AIMapper* _Nullable* _Nonnull outImplementation);
+
+inline BufferUsage operator|(BufferUsage lhs, BufferUsage rhs) {
+ using T = std::underlying_type_t<BufferUsage>;
+ return static_cast<BufferUsage>(static_cast<T>(lhs) | static_cast<T>(rhs));
}
-static constexpr hardware::graphics::common::V1_2::PixelFormat cast(PixelFormat format) {
- return static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
+inline BufferUsage& operator|=(BufferUsage& lhs, BufferUsage rhs) {
+ lhs = lhs | rhs;
+ return lhs;
}
+static IMapper4::BufferDescriptorInfo convert(const BufferDescriptorInfo& info) {
+ return IMapper4::BufferDescriptorInfo{
+ .name{reinterpret_cast<const char*>(info.name.data())},
+ .width = static_cast<uint32_t>(info.width),
+ .height = static_cast<uint32_t>(info.height),
+ .layerCount = static_cast<uint32_t>(info.layerCount),
+ .format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(info.format),
+ .usage = static_cast<uint64_t>(info.usage),
+ .reservedSize = 0,
+ };
+}
+
+class GraphicsTestsBase;
+
class BufferHandle {
- sp<IMapper> mMapper;
+ GraphicsTestsBase& mTestBase;
native_handle_t* mRawHandle;
bool mImported = false;
uint32_t mStride;
- const IMapper::BufferDescriptorInfo mInfo;
+ const BufferDescriptorInfo mInfo;
BufferHandle(const BufferHandle&) = delete;
void operator=(const BufferHandle&) = delete;
public:
- BufferHandle(const sp<IMapper> mapper, native_handle_t* handle, bool imported, uint32_t stride,
- const IMapper::BufferDescriptorInfo& info)
- : mMapper(mapper), mRawHandle(handle), mImported(imported), mStride(stride), mInfo(info) {}
+ BufferHandle(GraphicsTestsBase& testBase, native_handle_t* handle, bool imported,
+ uint32_t stride, const BufferDescriptorInfo& info)
+ : mTestBase(testBase),
+ mRawHandle(handle),
+ mImported(imported),
+ mStride(stride),
+ mInfo(info) {}
- ~BufferHandle() {
- if (mRawHandle == nullptr) return;
-
- if (mImported) {
- Error error = mMapper->freeBuffer(mRawHandle);
- EXPECT_EQ(Error::NONE, error) << "failed to free buffer " << mRawHandle;
- } else {
- native_handle_close(mRawHandle);
- native_handle_delete(mRawHandle);
- }
- }
+ ~BufferHandle();
uint32_t stride() const { return mStride; }
AHardwareBuffer_Desc describe() const {
return {
- .width = mInfo.width,
- .height = mInfo.height,
- .layers = mInfo.layerCount,
+ .width = static_cast<uint32_t>(mInfo.width),
+ .height = static_cast<uint32_t>(mInfo.height),
+ .layers = static_cast<uint32_t>(mInfo.layerCount),
.format = static_cast<uint32_t>(mInfo.format),
- .usage = mInfo.usage,
+ .usage = static_cast<uint64_t>(mInfo.usage),
.stride = stride(),
.rfu0 = 0,
.rfu1 = 0,
@@ -114,25 +128,43 @@
class GraphicsTestsBase {
private:
+ friend class BufferHandle;
+ int32_t mIAllocatorVersion = 1;
std::shared_ptr<IAllocator> mAllocator;
- sp<IMapper> mMapper;
+ sp<IMapper4> mMapper4;
+ AIMapper* mAIMapper = nullptr;
protected:
- void Initialize(std::string allocatorService, std::string mapperService) {
+ void Initialize(std::string allocatorService) {
mAllocator = IAllocator::fromBinder(
ndk::SpAIBinder(AServiceManager_checkService(allocatorService.c_str())));
- mMapper = IMapper::getService(mapperService);
+ ASSERT_TRUE(mAllocator->getInterfaceVersion(&mIAllocatorVersion).isOk());
+ if (mIAllocatorVersion >= 2) {
+ std::string mapperSuffix;
+ auto status = mAllocator->getIMapperLibrarySuffix(&mapperSuffix);
+ ASSERT_TRUE(status.isOk());
+ std::string lib_name = "mapper." + mapperSuffix + ".so";
+ void* so = android_load_sphal_library(lib_name.c_str(), RTLD_LOCAL | RTLD_NOW);
+ ASSERT_NE(nullptr, so) << "Failed to load " << lib_name;
+ auto loadIMapper = (AIMapper_loadIMapperFn)dlsym(so, "AIMapper_loadIMapper");
+ ASSERT_NE(nullptr, loadIMapper) << "AIMapper_locaIMapper missing from " << lib_name;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, loadIMapper(&mAIMapper));
+ ASSERT_NE(mAIMapper, nullptr);
+ } else {
+ // Don't have IMapper 5, fall back to IMapper 4
+ mMapper4 = IMapper4::getService();
+ ASSERT_NE(nullptr, mMapper4.get()) << "failed to get mapper service";
+ ASSERT_FALSE(mMapper4->isRemote()) << "mapper is not in passthrough mode";
+ }
ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
- ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
- ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
}
- public:
- BufferDescriptor createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo) {
+ private:
+ BufferDescriptor createDescriptor(const BufferDescriptorInfo& descriptorInfo) {
BufferDescriptor descriptor;
- mMapper->createDescriptor(
- descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
+ mMapper4->createDescriptor(
+ convert(descriptorInfo), [&](const auto& tmpError, const auto& tmpDescriptor) {
ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
descriptor = tmpDescriptor;
});
@@ -140,14 +172,22 @@
return descriptor;
}
- std::unique_ptr<BufferHandle> allocate(const IMapper::BufferDescriptorInfo& descriptorInfo) {
- auto descriptor = createDescriptor(descriptorInfo);
- if (::testing::Test::HasFatalFailure()) {
- return nullptr;
- }
-
+ public:
+ std::unique_ptr<BufferHandle> allocate(const BufferDescriptorInfo& descriptorInfo) {
AllocationResult result;
- auto status = mAllocator->allocate(descriptor, 1, &result);
+ ::ndk::ScopedAStatus status;
+ if (mIAllocatorVersion >= 2) {
+ status = mAllocator->allocate2(descriptorInfo, 1, &result);
+ } else {
+ auto descriptor = createDescriptor(descriptorInfo);
+ if (::testing::Test::HasFatalFailure()) {
+ return nullptr;
+ }
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ status = mAllocator->allocate(descriptor, 1, &result);
+#pragma clang diagnostic pop // deprecation
+ }
if (!status.isOk()) {
status_t error = status.getExceptionCode();
if (error == EX_SERVICE_SPECIFIC) {
@@ -158,28 +198,48 @@
}
return nullptr;
} else {
- return std::make_unique<BufferHandle>(mMapper, dupFromAidl(result.buffers[0]), false,
+ return std::make_unique<BufferHandle>(*this, dupFromAidl(result.buffers[0]), false,
result.stride, descriptorInfo);
}
}
- bool isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo) {
+ bool isSupported(const BufferDescriptorInfo& descriptorInfo) {
bool ret = false;
- EXPECT_TRUE(mMapper->isSupported(descriptorInfo,
- [&](auto error, bool supported) {
- ASSERT_EQ(Error::NONE, error);
- ret = supported;
- })
- .isOk());
+ if (mIAllocatorVersion >= 2) {
+ EXPECT_TRUE(mAllocator->isSupported(descriptorInfo, &ret).isOk());
+ } else {
+ EXPECT_TRUE(mMapper4->isSupported(convert(descriptorInfo),
+ [&](auto error, bool supported) {
+ ASSERT_EQ(Error::NONE, error);
+ ret = supported;
+ })
+ .isOk());
+ }
return ret;
}
};
-class GraphicsAllocatorAidlTests
- : public GraphicsTestsBase,
- public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+BufferHandle::~BufferHandle() {
+ if (mRawHandle == nullptr) return;
+
+ if (mImported) {
+ if (mTestBase.mAIMapper) {
+ AIMapper_Error error = mTestBase.mAIMapper->v5.freeBuffer(mRawHandle);
+ EXPECT_EQ(AIMAPPER_ERROR_NONE, error);
+ } else {
+ Error error = mTestBase.mMapper4->freeBuffer(mRawHandle);
+ EXPECT_EQ(Error::NONE, error) << "failed to free buffer " << mRawHandle;
+ }
+ } else {
+ native_handle_close(mRawHandle);
+ native_handle_delete(mRawHandle);
+ }
+}
+
+class GraphicsAllocatorAidlTests : public GraphicsTestsBase,
+ public ::testing::TestWithParam<std::string> {
public:
- void SetUp() override { Initialize(std::get<0>(GetParam()), std::get<1>(GetParam())); }
+ void SetUp() override { Initialize(GetParam()); }
void TearDown() override {}
};
@@ -191,22 +251,22 @@
class GraphicsFrontBufferTests
: public GraphicsTestsBase,
- public ::testing::TestWithParam<std::tuple<std::string, std::string, FlushMethod>> {
+ public ::testing::TestWithParam<std::tuple<std::string, FlushMethod>> {
private:
EglManager eglManager;
std::function<void(EglManager&)> flush;
public:
void SetUp() override {
- Initialize(std::get<0>(GetParam()), std::get<1>(GetParam()));
- flush = std::get<2>(GetParam()).func;
+ Initialize(std::get<0>(GetParam()));
+ flush = std::get<1>(GetParam()).func;
eglManager.initialize();
}
void TearDown() override { eglManager.destroy(); }
void fillWithGpu(AHardwareBuffer* buffer, float red, float green, float blue, float alpha) {
- const EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(buffer);
+ EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(buffer);
AutoEglImage eglImage(eglManager.eglDisplay(), clientBuffer);
AutoSkiaGlTexture glTexture;
AutoGLFramebuffer glFbo;
@@ -235,26 +295,14 @@
}
};
-TEST_P(GraphicsAllocatorAidlTests, CreateDescriptorBasic) {
- ASSERT_NO_FATAL_FAILURE(createDescriptor({
- .name = "CPU_8888",
- .width = 64,
- .height = 64,
- .layerCount = 1,
- .format = cast(PixelFormat::RGBA_8888),
- .usage = pack({BufferUsage::CPU_WRITE_OFTEN, BufferUsage::CPU_READ_OFTEN}),
- .reservedSize = 0,
- }));
-}
-
TEST_P(GraphicsAllocatorAidlTests, CanAllocate) {
auto buffer = allocate({
- .name = "CPU_8888",
+ .name = {"CPU_8888"},
.width = 64,
.height = 64,
.layerCount = 1,
- .format = cast(PixelFormat::RGBA_8888),
- .usage = pack({BufferUsage::CPU_WRITE_OFTEN, BufferUsage::CPU_READ_OFTEN}),
+ .format = PixelFormat::RGBA_8888,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
.reservedSize = 0,
});
ASSERT_NE(nullptr, buffer.get());
@@ -262,14 +310,14 @@
}
TEST_P(GraphicsFrontBufferTests, FrontBufferGpuToCpu) {
- IMapper::BufferDescriptorInfo info{
- .name = "CPU_8888",
+ BufferDescriptorInfo info{
+ .name = {"CPU_8888"},
.width = 64,
.height = 64,
.layerCount = 1,
- .format = cast(PixelFormat::RGBA_8888),
- .usage = pack({BufferUsage::GPU_RENDER_TARGET, BufferUsage::CPU_READ_OFTEN,
- BufferUsage::FRONT_BUFFER}),
+ .format = PixelFormat::RGBA_8888,
+ .usage = BufferUsage::GPU_RENDER_TARGET | BufferUsage::CPU_READ_OFTEN |
+ BufferUsage::FRONT_BUFFER,
.reservedSize = 0,
};
const bool supported = isSupported(info);
@@ -304,14 +352,14 @@
}
TEST_P(GraphicsFrontBufferTests, FrontBufferGpuToGpu) {
- IMapper::BufferDescriptorInfo info{
- .name = "CPU_8888",
+ BufferDescriptorInfo info{
+ .name = {"CPU_8888"},
.width = 64,
.height = 64,
.layerCount = 1,
- .format = cast(PixelFormat::RGBA_8888),
- .usage = pack({BufferUsage::GPU_RENDER_TARGET, BufferUsage::GPU_TEXTURE,
- BufferUsage::FRONT_BUFFER}),
+ .format = PixelFormat::RGBA_8888,
+ .usage = BufferUsage::GPU_RENDER_TARGET | BufferUsage::GPU_TEXTURE |
+ BufferUsage::FRONT_BUFFER,
.reservedSize = 0,
};
const bool supported = isSupported(info);
@@ -344,11 +392,9 @@
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsAllocatorAidlTests);
-INSTANTIATE_TEST_CASE_P(
- PerInstance, GraphicsAllocatorAidlTests,
- testing::Combine(testing::ValuesIn(getAidlHalInstanceNames(IAllocator::descriptor)),
- testing::ValuesIn(getAllHalInstanceNames(IMapper::descriptor))),
- PrintInstanceTupleNameToString<>);
+INSTANTIATE_TEST_CASE_P(PerInstance, GraphicsAllocatorAidlTests,
+ testing::ValuesIn(getAidlHalInstanceNames(IAllocator::descriptor)),
+ PrintInstanceNameToString);
const auto FlushMethodsValues = testing::Values(
FlushMethod{"glFinish", [](EglManager&) { glFinish(); }},
@@ -362,7 +408,7 @@
}},
FlushMethod{"eglClientWaitSync", [](EglManager& eglManager) {
EGLDisplay display = eglManager.eglDisplay();
- EGLSyncKHR fence = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, NULL);
+ EGLSyncKHR fence = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
eglClientWaitSyncKHR(display, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
EGL_FOREVER_KHR);
eglDestroySyncKHR(display, fence);
@@ -371,9 +417,8 @@
INSTANTIATE_TEST_CASE_P(
PerInstance, GraphicsFrontBufferTests,
testing::Combine(testing::ValuesIn(getAidlHalInstanceNames(IAllocator::descriptor)),
- testing::ValuesIn(getAllHalInstanceNames(IMapper::descriptor)),
FlushMethodsValues),
[](auto info) -> std::string {
- std::string name = std::to_string(info.index) + "/" + std::get<2>(info.param).name;
+ std::string name = std::to_string(info.index) + "/" + std::get<1>(info.param).name;
return Sanitize(name);
- });
+ });
\ No newline at end of file
diff --git a/graphics/common/aidl/Android.bp b/graphics/common/aidl/Android.bp
index cb96663..84bc1af 100644
--- a/graphics/common/aidl/Android.bp
+++ b/graphics/common/aidl/Android.bp
@@ -40,6 +40,7 @@
min_sdk_version: "29",
},
},
+ frozen: false,
versions_with_info: [
{
version: "1",
diff --git a/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
index 8126143..4bca795 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
@@ -22,9 +22,9 @@
* This is an enum that defines the common types of gralloc 4 buffer metadata. The comments for
* each enum include a description of the metadata that is associated with the type.
*
- * IMapper@4.x must support getting the following standard buffer metadata types, with the exception
- * of SMPTE 2094-10 metadata. IMapper@4.x may support setting these standard buffer metadata types
- * as well.
+ * IMapper@4.x & later must support getting the following standard buffer metadata types, with the
+ * exception of SMPTE 2094-10 and SMPTE 2094-40 metadata. IMapper@4.x & later may support setting
+ * these standard buffer metadata types as well.
*
* When encoding these StandardMetadataTypes into a byte stream, the associated MetadataType is
* is first encoded followed by the StandardMetadataType value. The MetadataType is encoded by
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index 0ba320d..1e08221 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -31,6 +31,8 @@
enabled: true,
support_system_process: true,
},
+ frozen: false,
+ vndk_use_version: "1",
srcs: [
"android/hardware/graphics/composer3/*.aidl",
],
diff --git a/graphics/mapper/stable-c/Android.bp b/graphics/mapper/stable-c/Android.bp
new file mode 100644
index 0000000..c03f67e
--- /dev/null
+++ b/graphics/mapper/stable-c/Android.bp
@@ -0,0 +1,104 @@
+/**
+ * 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library_headers {
+ name: "libimapper_stablec",
+ export_include_dirs: ["include"],
+ vendor_available: true,
+ header_libs: [
+ "libarect_headers",
+ ],
+ export_header_lib_headers: [
+ "libarect_headers",
+ ],
+}
+
+cc_library_headers {
+ name: "libimapper_providerutils",
+ vendor_available: true,
+ export_include_dirs: ["implutils/include"],
+ header_libs: [
+ "libbase_headers",
+ "libimapper_stablec",
+ ],
+ export_header_lib_headers: [
+ "libbase_headers",
+ "libimapper_stablec",
+ ],
+}
+
+cc_test {
+ name: "libimapper_providerutils_tests",
+ defaults: [
+ "android.hardware.graphics.allocator-ndk_shared",
+ "android.hardware.graphics.common-ndk_shared",
+ ],
+ header_libs: [
+ "libimapper_providerutils",
+ ],
+ srcs: [
+ "implutils/impltests.cpp",
+ ],
+ visibility: [":__subpackages__"],
+ cpp_std: "experimental",
+}
+
+cc_test {
+ name: "VtsHalGraphicsMapperStableC_TargetTest",
+ cpp_std: "experimental",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ "android.hardware.graphics.allocator-ndk_shared",
+ "android.hardware.graphics.common-ndk_shared",
+ ],
+ srcs: [
+ "vts/VtsHalGraphicsMapperStableC_TargetTest.cpp",
+ ],
+
+ shared_libs: [
+ "libbinder_ndk",
+ "libbase",
+ "libsync",
+ "libvndksupport",
+ ],
+ static_libs: [
+ "libaidlcommonsupport",
+ "libgralloctypes",
+ "libgtest",
+ ],
+ header_libs: [
+ "libimapper_stablec",
+ "libimapper_providerutils",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/graphics/mapper/stable-c/implutils/impltests.cpp b/graphics/mapper/stable-c/implutils/impltests.cpp
new file mode 100644
index 0000000..9c5d70b
--- /dev/null
+++ b/graphics/mapper/stable-c/implutils/impltests.cpp
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
+#include <android/hardware/graphics/mapper/utils/IMapperProvider.h>
+#include <vector>
+
+using namespace ::android::hardware::graphics::mapper;
+using namespace ::aidl::android::hardware::graphics::common;
+
+// These tests are primarily interested in hitting all the different *types* that can be
+// serialized/deserialized than in exhaustively testing all the StandardMetadataTypes.
+// Exhaustive testing of the actual metadata types is relegated for IMapper's VTS suite
+// where meaning & correctness of values are more narrowly defined (eg, read-only values)
+
+TEST(Metadata, setGetBufferId) {
+ using BufferId = StandardMetadata<StandardMetadataType::BUFFER_ID>::value;
+
+ std::vector<char> buffer;
+ buffer.resize(12, 0);
+ *reinterpret_cast<int64_t*>(buffer.data()) = 42;
+
+ EXPECT_EQ(8, BufferId::encode(18, buffer.data(), 0));
+ EXPECT_EQ(42, *reinterpret_cast<int64_t*>(buffer.data()));
+ EXPECT_EQ(8, BufferId::encode(18, buffer.data(), buffer.size()));
+ EXPECT_EQ(18, *reinterpret_cast<int64_t*>(buffer.data()));
+ EXPECT_FALSE(BufferId::decode(buffer.data(), 0));
+ auto read = BufferId::decode(buffer.data(), buffer.size());
+ EXPECT_TRUE(read.has_value());
+ EXPECT_EQ(18, read.value_or(0));
+}
+
+TEST(Metadata, setGetDataspace) {
+ using DataspaceValue = StandardMetadata<StandardMetadataType::DATASPACE>::value;
+ using intType = std::underlying_type_t<Dataspace>;
+ std::vector<char> buffer;
+ buffer.resize(12, 0);
+
+ EXPECT_EQ(4, DataspaceValue::encode(Dataspace::BT2020, buffer.data(), 0));
+ EXPECT_EQ(0, *reinterpret_cast<intType*>(buffer.data()));
+ EXPECT_EQ(4, DataspaceValue::encode(Dataspace::BT2020, buffer.data(), buffer.size()));
+ EXPECT_EQ(static_cast<intType>(Dataspace::BT2020), *reinterpret_cast<intType*>(buffer.data()));
+ EXPECT_FALSE(DataspaceValue::decode(buffer.data(), 0));
+ auto read = DataspaceValue::decode(buffer.data(), buffer.size());
+ ASSERT_TRUE(read.has_value());
+ EXPECT_EQ(Dataspace::BT2020, *read);
+}
+
+TEST(Metadata, setGetValidName) {
+ using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;
+
+ std::vector<char> buffer;
+ buffer.resize(100, 'a');
+ buffer[buffer.size() - 1] = '\0';
+
+ // len("Hello") + sizeof(int64)
+ constexpr int expectedSize = 5 + sizeof(int64_t);
+ EXPECT_EQ(expectedSize, NameValue::encode("Hello", buffer.data(), buffer.size()));
+ EXPECT_EQ(5, *reinterpret_cast<int64_t*>(buffer.data()));
+ // Verify didn't write past the end of the desired size
+ EXPECT_EQ('a', buffer[expectedSize]);
+
+ auto readValue = NameValue::decode(buffer.data(), buffer.size());
+ ASSERT_TRUE(readValue.has_value());
+ EXPECT_EQ(5, readValue->length());
+ EXPECT_EQ("Hello", *readValue);
+}
+
+TEST(Metadata, setGetInvalidName) {
+ using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;
+
+ std::vector<char> buffer;
+ buffer.resize(12, 'a');
+ buffer[buffer.size() - 1] = '\0';
+
+ // len("This is a long string") + sizeof(int64)
+ constexpr int expectedSize = 21 + sizeof(int64_t);
+ EXPECT_EQ(expectedSize,
+ NameValue::encode("This is a long string", buffer.data(), buffer.size()));
+ EXPECT_EQ(21, *reinterpret_cast<int64_t*>(buffer.data()));
+ // Verify didn't write the too-long string
+ EXPECT_EQ('a', buffer[9]);
+ EXPECT_EQ('\0', buffer[buffer.size() - 1]);
+
+ auto readValue = NameValue::decode(buffer.data(), buffer.size());
+ EXPECT_FALSE(readValue.has_value());
+ readValue = NameValue::decode(buffer.data(), 0);
+ ASSERT_FALSE(readValue.has_value());
+}
+
+TEST(Metadata, wouldOverflowName) {
+ using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;
+ std::vector<char> buffer(100, 0);
+
+ // int_max + sizeof(int64) overflows int32
+ std::string_view bad_string{"badbeef", std::numeric_limits<int32_t>::max()};
+ EXPECT_EQ(-AIMAPPER_ERROR_BAD_VALUE,
+ NameValue::encode(bad_string, buffer.data(), buffer.size()));
+
+ // check barely overflows
+ bad_string = std::string_view{"badbeef", std::numeric_limits<int32_t>::max() - 7};
+ EXPECT_EQ(-AIMAPPER_ERROR_BAD_VALUE,
+ NameValue::encode(bad_string, buffer.data(), buffer.size()));
+}
+
+TEST(Metadata, setGetCompression) {
+ using CompressionValue = StandardMetadata<StandardMetadataType::COMPRESSION>::value;
+ ExtendableType myCompression{"bestest_compression_ever", 42};
+ std::vector<char> buffer(100, '\0');
+ const int expectedSize = myCompression.name.length() + sizeof(int64_t) + sizeof(int64_t);
+ EXPECT_EQ(expectedSize, CompressionValue::encode(myCompression, buffer.data(), 0));
+ EXPECT_EQ(0, buffer[0]);
+ EXPECT_EQ(expectedSize, CompressionValue::encode(myCompression, buffer.data(), buffer.size()));
+ EXPECT_EQ(myCompression.name.length(), *reinterpret_cast<int64_t*>(buffer.data()));
+ EXPECT_FALSE(CompressionValue::decode(buffer.data(), 0).has_value());
+ auto read = CompressionValue::decode(buffer.data(), buffer.size());
+ ASSERT_TRUE(read.has_value());
+ EXPECT_EQ(myCompression, read.value());
+}
+
+TEST(Metadata, setGetPlaneLayout) {
+ using PlaneLayoutValue = StandardMetadata<StandardMetadataType::PLANE_LAYOUTS>::value;
+ PlaneLayout myPlaneLayout;
+ myPlaneLayout.offsetInBytes = 10;
+ myPlaneLayout.sampleIncrementInBits = 11;
+ myPlaneLayout.strideInBytes = 12;
+ myPlaneLayout.widthInSamples = 13;
+ myPlaneLayout.heightInSamples = 14;
+ myPlaneLayout.totalSizeInBytes = 15;
+ myPlaneLayout.horizontalSubsampling = 16;
+ myPlaneLayout.verticalSubsampling = 17;
+
+ myPlaneLayout.components.resize(3);
+ for (int i = 0; i < myPlaneLayout.components.size(); i++) {
+ auto& it = myPlaneLayout.components[i];
+ it.type = ExtendableType{"Plane ID", 40 + i};
+ it.offsetInBits = 20 + i;
+ it.sizeInBits = 30 + i;
+ }
+
+ std::vector<PlaneLayout> layouts{myPlaneLayout, PlaneLayout{}};
+
+ std::vector<char> buffer(5000, '\0');
+ constexpr int componentSize = 8 + (4 * sizeof(int64_t));
+ constexpr int firstLayoutSize = (8 + 1) * sizeof(int64_t) + (3 * componentSize);
+ constexpr int secondLayoutSize = (8 + 1) * sizeof(int64_t);
+ constexpr int expectedSize = firstLayoutSize + secondLayoutSize + sizeof(int64_t);
+ EXPECT_EQ(expectedSize, PlaneLayoutValue::encode(layouts, buffer.data(), 0));
+ EXPECT_EQ(0, buffer[0]);
+ EXPECT_EQ(expectedSize, PlaneLayoutValue::encode(layouts, buffer.data(), buffer.size()));
+ EXPECT_EQ(3, reinterpret_cast<int64_t*>(buffer.data())[1]);
+ EXPECT_EQ(8, reinterpret_cast<int64_t*>(buffer.data())[2]);
+ EXPECT_EQ(40, reinterpret_cast<int64_t*>(buffer.data())[4]);
+ EXPECT_EQ(31, reinterpret_cast<int64_t*>(buffer.data())[11]);
+ EXPECT_EQ(22, reinterpret_cast<int64_t*>(buffer.data())[15]);
+ EXPECT_EQ(10, reinterpret_cast<int64_t*>(buffer.data())[17]);
+ EXPECT_EQ(11, reinterpret_cast<int64_t*>(buffer.data())[18]);
+ EXPECT_FALSE(PlaneLayoutValue::decode(buffer.data(), 0).has_value());
+ auto read = PlaneLayoutValue::decode(buffer.data(), buffer.size());
+ ASSERT_TRUE(read.has_value());
+ EXPECT_EQ(layouts, *read);
+}
+
+TEST(Metadata, setGetRects) {
+ using RectsValue = StandardMetadata<StandardMetadataType::CROP>::value;
+ std::vector<uint8_t> buffer(500, 0);
+ std::vector<Rect> cropRects{2};
+ cropRects[0] = Rect{10, 11, 12, 13};
+ cropRects[1] = Rect{20, 21, 22, 23};
+
+ constexpr int expectedSize = sizeof(int64_t) + (8 * sizeof(int32_t));
+ EXPECT_EQ(expectedSize, RectsValue::encode(cropRects, buffer.data(), buffer.size()));
+ EXPECT_EQ(2, reinterpret_cast<int64_t*>(buffer.data())[0]);
+ EXPECT_EQ(10, reinterpret_cast<int32_t*>(buffer.data())[2]);
+ auto read = RectsValue::decode(buffer.data(), buffer.size());
+ ASSERT_TRUE(read.has_value());
+ EXPECT_EQ(cropRects.size(), read->size());
+ EXPECT_EQ(cropRects, *read);
+}
+
+TEST(Metadata, setGetSmpte2086) {
+ using Smpte2086Value = StandardMetadata<StandardMetadataType::SMPTE2086>::value;
+ Smpte2086 source;
+ source.minLuminance = 12.335f;
+ source.maxLuminance = 452.889f;
+ source.whitePoint = XyColor{-6.f, -9.f};
+ source.primaryRed = XyColor{.1f, .2f};
+ source.primaryGreen = XyColor{.3f, .4f};
+ source.primaryBlue = XyColor{.5f, .6f};
+
+ constexpr int expectedSize = 10 * sizeof(float);
+ std::vector<uint8_t> buffer(500, 0);
+ EXPECT_EQ(expectedSize, Smpte2086Value::encode(source, buffer.data(), buffer.size()));
+ auto read = Smpte2086Value::decode(buffer.data(), buffer.size());
+ ASSERT_TRUE(read.has_value());
+ ASSERT_TRUE(read->has_value());
+ EXPECT_EQ(source, read->value());
+
+ // A valid encoding of a nullopt
+ read = Smpte2086Value::decode(nullptr, 0);
+ ASSERT_TRUE(read.has_value());
+ EXPECT_FALSE(read->has_value());
+}
+
+TEST(Metadata, setGetCta861_3) {
+ using Cta861_3Value = StandardMetadata<StandardMetadataType::CTA861_3>::value;
+ Cta861_3 source;
+ source.maxFrameAverageLightLevel = 244.55f;
+ source.maxContentLightLevel = 202.202f;
+
+ constexpr int expectedSize = 2 * sizeof(float);
+ std::vector<uint8_t> buffer(500, 0);
+ EXPECT_EQ(expectedSize, Cta861_3Value::encode(source, buffer.data(), buffer.size()));
+ auto read = Cta861_3Value::decode(buffer.data(), buffer.size());
+ ASSERT_TRUE(read.has_value());
+ ASSERT_TRUE(read->has_value());
+ EXPECT_EQ(source, read->value());
+
+ // A valid encoding of a nullopt
+ read = Cta861_3Value::decode(nullptr, 0);
+ ASSERT_TRUE(read.has_value());
+ EXPECT_FALSE(read->has_value());
+}
+
+TEST(Metadata, setGetSmpte2094_10) {
+ using SMPTE2094_10Value = StandardMetadata<StandardMetadataType::SMPTE2094_10>::value;
+
+ std::vector<uint8_t> buffer(500, 0);
+ EXPECT_EQ(0, SMPTE2094_10Value::encode(std::nullopt, buffer.data(), buffer.size()));
+ auto read = SMPTE2094_10Value::decode(buffer.data(), 0);
+ ASSERT_TRUE(read.has_value());
+ EXPECT_FALSE(read->has_value());
+
+ const std::vector<uint8_t> emptyBuffer;
+ EXPECT_EQ(sizeof(int64_t),
+ SMPTE2094_10Value::encode(emptyBuffer, buffer.data(), buffer.size()));
+ read = SMPTE2094_10Value::decode(buffer.data(), buffer.size());
+ ASSERT_TRUE(read.has_value());
+ ASSERT_TRUE(read->has_value());
+ EXPECT_EQ(0, read->value().size());
+
+ const std::vector<uint8_t> simpleBuffer{0, 1, 2, 3, 4, 5};
+ EXPECT_EQ(sizeof(int64_t) + 6,
+ SMPTE2094_10Value::encode(simpleBuffer, buffer.data(), buffer.size()));
+ read = SMPTE2094_10Value::decode(buffer.data(), buffer.size());
+ ASSERT_TRUE(read.has_value());
+ ASSERT_TRUE(read->has_value());
+ EXPECT_EQ(6, read->value().size());
+ EXPECT_EQ(simpleBuffer, read->value());
+}
+
+TEST(MetadataProvider, bufferId) {
+ using BufferId = StandardMetadata<StandardMetadataType::BUFFER_ID>::value;
+ std::vector<uint8_t> buffer(500, 0);
+ int result = provideStandardMetadata(StandardMetadataType::BUFFER_ID, buffer.data(),
+ buffer.size(), []<StandardMetadataType T>(auto&& provide) {
+ if constexpr (T == StandardMetadataType::BUFFER_ID) {
+ return provide(42);
+ }
+ return 0;
+ });
+
+ EXPECT_EQ(8, result);
+ auto read = BufferId::decode(buffer.data(), buffer.size());
+ EXPECT_EQ(42, read.value_or(0));
+}
+
+TEST(MetadataProvider, allJumpsWork) {
+ const auto& values = ndk::internal::enum_values<StandardMetadataType>;
+ auto get = [](StandardMetadataType type) -> int {
+ return provideStandardMetadata(type, nullptr, 0, []<StandardMetadataType T>(auto&&) {
+ return static_cast<int>(T) + 100;
+ });
+ };
+
+ for (auto& type : values) {
+ const int expected = type == StandardMetadataType::INVALID ? -AIMAPPER_ERROR_UNSUPPORTED
+ : static_cast<int>(type) + 100;
+ EXPECT_EQ(expected, get(type));
+ }
+}
+
+TEST(MetadataProvider, invalid) {
+ int result = provideStandardMetadata(StandardMetadataType::INVALID, nullptr, 0,
+ []<StandardMetadataType T>(auto&&) { return 10; });
+
+ EXPECT_EQ(-AIMAPPER_ERROR_UNSUPPORTED, result);
+}
+
+TEST(MetadataProvider, outOfBounds) {
+ int result = provideStandardMetadata(static_cast<StandardMetadataType>(-1), nullptr, 0,
+ []<StandardMetadataType T>(auto&&) { return 10; });
+ EXPECT_EQ(-AIMAPPER_ERROR_UNSUPPORTED, result) << "-1 should have resulted in UNSUPPORTED";
+
+ result = provideStandardMetadata(static_cast<StandardMetadataType>(100), nullptr, 0,
+ []<StandardMetadataType T>(auto&&) { return 10; });
+ EXPECT_EQ(-AIMAPPER_ERROR_UNSUPPORTED, result)
+ << "100 (out of range) should have resulted in UNSUPPORTED";
+}
diff --git a/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h
new file mode 100644
index 0000000..7861af8
--- /dev/null
+++ b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h
@@ -0,0 +1,576 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/Cta861_3.h>
+#include <aidl/android/hardware/graphics/common/Dataspace.h>
+#include <aidl/android/hardware/graphics/common/ExtendableType.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <aidl/android/hardware/graphics/common/PlaneLayout.h>
+#include <aidl/android/hardware/graphics/common/PlaneLayoutComponent.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
+#include <aidl/android/hardware/graphics/common/Smpte2086.h>
+#include <aidl/android/hardware/graphics/common/StandardMetadataType.h>
+#include <aidl/android/hardware/graphics/common/XyColor.h>
+#include <android/hardware/graphics/mapper/IMapper.h>
+
+#include <cinttypes>
+#include <string_view>
+#include <type_traits>
+#include <vector>
+
+namespace android::hardware::graphics::mapper {
+
+using ::aidl::android::hardware::graphics::common::BlendMode;
+using ::aidl::android::hardware::graphics::common::BufferUsage;
+using ::aidl::android::hardware::graphics::common::Cta861_3;
+using ::aidl::android::hardware::graphics::common::Dataspace;
+using ::aidl::android::hardware::graphics::common::ExtendableType;
+using ::aidl::android::hardware::graphics::common::PixelFormat;
+using ::aidl::android::hardware::graphics::common::PlaneLayout;
+using ::aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+using ::aidl::android::hardware::graphics::common::Rect;
+using ::aidl::android::hardware::graphics::common::Smpte2086;
+using ::aidl::android::hardware::graphics::common::StandardMetadataType;
+using ::aidl::android::hardware::graphics::common::XyColor;
+
+class MetadataWriter {
+ private:
+ uint8_t* _Nonnull mDest;
+ size_t mSizeRemaining = 0;
+ int32_t mDesiredSize = 0;
+
+ void* _Nullable reserve(size_t sizeToWrite) {
+ if (mDesiredSize < 0) {
+ // Error state
+ return nullptr;
+ }
+ if (__builtin_add_overflow(mDesiredSize, sizeToWrite, &mDesiredSize)) {
+ // Overflowed, abort writing any further data
+ mDesiredSize = -AIMAPPER_ERROR_BAD_VALUE;
+ mSizeRemaining = 0;
+ return nullptr;
+ }
+ if (sizeToWrite > mSizeRemaining) {
+ mSizeRemaining = 0;
+ return nullptr;
+ } else {
+ mSizeRemaining -= sizeToWrite;
+ uint8_t* whereToWrite = mDest;
+ mDest += sizeToWrite;
+ return whereToWrite;
+ }
+ }
+
+ public:
+ explicit MetadataWriter(void* _Nullable destBuffer, size_t destBufferSize)
+ : mDest(reinterpret_cast<uint8_t*>(destBuffer)), mSizeRemaining(destBufferSize) {}
+
+ int32_t desiredSize() const { return mDesiredSize; }
+
+ template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
+ MetadataWriter& write(T value) {
+ auto sizeToWrite = sizeof(T);
+ if (void* dest = reserve(sizeToWrite)) {
+ memcpy(dest, &value, sizeToWrite);
+ }
+ return *this;
+ }
+
+ MetadataWriter& write(float value) {
+ auto sizeToWrite = sizeof(float);
+ if (void* dest = reserve(sizeToWrite)) {
+ memcpy(dest, &value, sizeToWrite);
+ }
+ return *this;
+ }
+
+ MetadataWriter& write(const std::string_view& value) {
+ auto sizeToWrite = value.length();
+ write<int64_t>(sizeToWrite);
+ if (void* dest = reserve(sizeToWrite)) {
+ memcpy(dest, value.data(), sizeToWrite);
+ }
+ return *this;
+ }
+
+ MetadataWriter& write(const std::vector<uint8_t>& value) {
+ auto sizeToWrite = value.size();
+ write<int64_t>(sizeToWrite);
+ if (void* dest = reserve(sizeToWrite)) {
+ memcpy(dest, value.data(), sizeToWrite);
+ }
+ return *this;
+ }
+
+ MetadataWriter& write(const ExtendableType& value) {
+ return write(value.name).write(value.value);
+ }
+
+ MetadataWriter& write(const XyColor& value) { return write(value.x).write(value.y); }
+};
+
+class MetadataReader {
+ private:
+ const uint8_t* _Nonnull mSrc;
+ size_t mSizeRemaining = 0;
+ bool mOk = true;
+
+ const void* _Nullable advance(size_t size) {
+ if (mOk && mSizeRemaining >= size) {
+ const void* buf = mSrc;
+ mSrc += size;
+ mSizeRemaining -= size;
+ return buf;
+ }
+ mOk = false;
+ return nullptr;
+ }
+
+ public:
+ explicit MetadataReader(const void* _Nonnull metadata, size_t metadataSize)
+ : mSrc(reinterpret_cast<const uint8_t*>(metadata)), mSizeRemaining(metadataSize) {}
+
+ [[nodiscard]] size_t remaining() const { return mSizeRemaining; }
+ [[nodiscard]] bool ok() const { return mOk; }
+
+ template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
+ MetadataReader& read(T& dest) {
+ if (const void* src = advance(sizeof(T))) {
+ memcpy(&dest, src, sizeof(T));
+ }
+ return *this;
+ }
+
+ MetadataReader& read(float& dest) {
+ if (const void* src = advance(sizeof(float))) {
+ memcpy(&dest, src, sizeof(float));
+ }
+ return *this;
+ }
+
+ MetadataReader& read(std::string& dest) {
+ dest = readString();
+ return *this;
+ }
+
+ MetadataReader& read(ExtendableType& dest) {
+ dest.name = readString();
+ read(dest.value);
+ return *this;
+ }
+
+ MetadataReader& read(XyColor& dest) {
+ read(dest.x);
+ read(dest.y);
+ return *this;
+ }
+
+ template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
+ [[nodiscard]] std::optional<T> readInt() {
+ auto sizeToRead = sizeof(T);
+ if (const void* src = advance(sizeof(T))) {
+ T ret;
+ memcpy(&ret, src, sizeToRead);
+ return ret;
+ }
+ return std::nullopt;
+ }
+
+ [[nodiscard]] std::string_view readString() {
+ auto lengthOpt = readInt<int64_t>();
+ if (!lengthOpt) {
+ return std::string_view{};
+ }
+ size_t length = lengthOpt.value();
+ if (const void* src = advance(length)) {
+ return std::string_view{reinterpret_cast<const char*>(src), length};
+ }
+ return std::string_view{};
+ }
+
+ [[nodiscard]] std::optional<ExtendableType> readExtendable() {
+ ExtendableType ret;
+ ret.name = readString();
+ auto value = readInt<int64_t>();
+ if (value) {
+ ret.value = value.value();
+ return ret;
+ } else {
+ return std::nullopt;
+ }
+ }
+
+ [[nodiscard]] std::vector<uint8_t> readBuffer() {
+ std::vector<uint8_t> ret;
+ size_t length = readInt<int64_t>().value_or(0);
+ if (const void* src = advance(length)) {
+ ret.resize(length);
+ memcpy(ret.data(), src, length);
+ }
+ return ret;
+ }
+};
+
+template <typename T, class Enable = void>
+struct MetadataValue {};
+
+template <typename T>
+struct MetadataValue<T, std::enable_if_t<std::is_integral_v<T>>> {
+ [[nodiscard]] static int32_t encode(T value, void* _Nullable destBuffer,
+ size_t destBufferSize) {
+ return MetadataWriter{destBuffer, destBufferSize}.write(value).desiredSize();
+ }
+
+ [[nodiscard]] static std::optional<T> decode(const void* _Nonnull metadata,
+ size_t metadataSize) {
+ return MetadataReader{metadata, metadataSize}.readInt<T>();
+ }
+};
+
+template <typename T>
+struct MetadataValue<T, std::enable_if_t<std::is_enum_v<T>>> {
+ [[nodiscard]] static int32_t encode(T value, void* _Nullable destBuffer,
+ size_t destBufferSize) {
+ return MetadataWriter{destBuffer, destBufferSize}
+ .write(static_cast<std::underlying_type_t<T>>(value))
+ .desiredSize();
+ }
+
+ [[nodiscard]] static std::optional<T> decode(const void* _Nonnull metadata,
+ size_t metadataSize) {
+ std::underlying_type_t<T> temp;
+ return MetadataReader{metadata, metadataSize}.read(temp).ok()
+ ? std::optional<T>(static_cast<T>(temp))
+ : std::nullopt;
+ }
+};
+
+template <>
+struct MetadataValue<std::string> {
+ [[nodiscard]] static int32_t encode(const std::string_view& value, void* _Nullable destBuffer,
+ size_t destBufferSize) {
+ return MetadataWriter{destBuffer, destBufferSize}.write(value).desiredSize();
+ }
+
+ [[nodiscard]] static std::optional<std::string> decode(const void* _Nonnull metadata,
+ size_t metadataSize) {
+ auto reader = MetadataReader{metadata, metadataSize};
+ auto result = reader.readString();
+ return reader.ok() ? std::optional<std::string>{result} : std::nullopt;
+ }
+};
+
+template <>
+struct MetadataValue<ExtendableType> {
+ static_assert(sizeof(int64_t) == sizeof(ExtendableType::value));
+
+ [[nodiscard]] static int32_t encode(const ExtendableType& value, void* _Nullable destBuffer,
+ size_t destBufferSize) {
+ return MetadataWriter{destBuffer, destBufferSize}.write(value).desiredSize();
+ }
+
+ [[nodiscard]] static std::optional<ExtendableType> decode(const void* _Nonnull metadata,
+ size_t metadataSize) {
+ return MetadataReader{metadata, metadataSize}.readExtendable();
+ }
+};
+
+template <>
+struct MetadataValue<std::vector<PlaneLayout>> {
+ [[nodiscard]] static int32_t encode(const std::vector<PlaneLayout>& values,
+ void* _Nullable destBuffer, size_t destBufferSize) {
+ MetadataWriter writer{destBuffer, destBufferSize};
+ writer.write<int64_t>(values.size());
+ for (const auto& value : values) {
+ writer.write<int64_t>(value.components.size());
+ for (const auto& component : value.components) {
+ writer.write(component.type)
+ .write<int64_t>(component.offsetInBits)
+ .write<int64_t>(component.sizeInBits);
+ }
+ writer.write<int64_t>(value.offsetInBytes)
+ .write<int64_t>(value.sampleIncrementInBits)
+ .write<int64_t>(value.strideInBytes)
+ .write<int64_t>(value.widthInSamples)
+ .write<int64_t>(value.heightInSamples)
+ .write<int64_t>(value.totalSizeInBytes)
+ .write<int64_t>(value.horizontalSubsampling)
+ .write<int64_t>(value.verticalSubsampling);
+ }
+ return writer.desiredSize();
+ }
+
+ using DecodeResult = std::optional<std::vector<PlaneLayout>>;
+ [[nodiscard]] static DecodeResult decode(const void* _Nonnull metadata, size_t metadataSize) {
+ std::vector<PlaneLayout> values;
+ MetadataReader reader{metadata, metadataSize};
+ auto numPlanes = reader.readInt<int64_t>().value_or(0);
+ values.reserve(numPlanes);
+ for (int i = 0; i < numPlanes && reader.ok(); i++) {
+ PlaneLayout& value = values.emplace_back();
+ auto numPlaneComponents = reader.readInt<int64_t>().value_or(0);
+ value.components.reserve(numPlaneComponents);
+ for (int i = 0; i < numPlaneComponents && reader.ok(); i++) {
+ PlaneLayoutComponent& component = value.components.emplace_back();
+ reader.read(component.type)
+ .read<int64_t>(component.offsetInBits)
+ .read<int64_t>(component.sizeInBits);
+ }
+ reader.read<int64_t>(value.offsetInBytes)
+ .read<int64_t>(value.sampleIncrementInBits)
+ .read<int64_t>(value.strideInBytes)
+ .read<int64_t>(value.widthInSamples)
+ .read<int64_t>(value.heightInSamples)
+ .read<int64_t>(value.totalSizeInBytes)
+ .read<int64_t>(value.horizontalSubsampling)
+ .read<int64_t>(value.verticalSubsampling);
+ }
+ return reader.ok() ? DecodeResult{std::move(values)} : std::nullopt;
+ }
+};
+
+template <>
+struct MetadataValue<std::vector<Rect>> {
+ [[nodiscard]] static int32_t encode(const std::vector<Rect>& value, void* _Nullable destBuffer,
+ size_t destBufferSize) {
+ MetadataWriter writer{destBuffer, destBufferSize};
+ writer.write<int64_t>(value.size());
+ for (auto& rect : value) {
+ writer.write<int32_t>(rect.left)
+ .write<int32_t>(rect.top)
+ .write<int32_t>(rect.right)
+ .write<int32_t>(rect.bottom);
+ }
+ return writer.desiredSize();
+ }
+
+ using DecodeResult = std::optional<std::vector<Rect>>;
+ [[nodiscard]] static DecodeResult decode(const void* _Nonnull metadata, size_t metadataSize) {
+ MetadataReader reader{metadata, metadataSize};
+ std::vector<Rect> value;
+ auto numRects = reader.readInt<int64_t>().value_or(0);
+ value.reserve(numRects);
+ for (int i = 0; i < numRects && reader.ok(); i++) {
+ Rect& rect = value.emplace_back();
+ reader.read<int32_t>(rect.left)
+ .read<int32_t>(rect.top)
+ .read<int32_t>(rect.right)
+ .read<int32_t>(rect.bottom);
+ }
+ return reader.ok() ? DecodeResult{std::move(value)} : std::nullopt;
+ }
+};
+
+template <>
+struct MetadataValue<std::optional<Smpte2086>> {
+ [[nodiscard]] static int32_t encode(const std::optional<Smpte2086>& optValue,
+ void* _Nullable destBuffer, size_t destBufferSize) {
+ if (optValue.has_value()) {
+ const auto& value = *optValue;
+ return MetadataWriter{destBuffer, destBufferSize}
+ .write(value.primaryRed)
+ .write(value.primaryGreen)
+ .write(value.primaryBlue)
+ .write(value.whitePoint)
+ .write(value.maxLuminance)
+ .write(value.minLuminance)
+ .desiredSize();
+ } else {
+ return 0;
+ }
+ }
+
+ // Double optional because the value type itself is an optional<>
+ using DecodeResult = std::optional<std::optional<Smpte2086>>;
+ [[nodiscard]] static DecodeResult decode(const void* _Nullable metadata, size_t metadataSize) {
+ std::optional<Smpte2086> optValue{std::nullopt};
+ if (metadataSize > 0) {
+ Smpte2086 value;
+ MetadataReader reader{metadata, metadataSize};
+ reader.read(value.primaryRed)
+ .read(value.primaryGreen)
+ .read(value.primaryBlue)
+ .read(value.whitePoint)
+ .read(value.maxLuminance)
+ .read(value.minLuminance);
+ if (reader.ok()) {
+ optValue = std::move(value);
+ } else {
+ return std::nullopt;
+ }
+ }
+ return DecodeResult{std::move(optValue)};
+ }
+};
+
+template <>
+struct MetadataValue<std::optional<Cta861_3>> {
+ [[nodiscard]] static int32_t encode(const std::optional<Cta861_3>& optValue,
+ void* _Nullable destBuffer, size_t destBufferSize) {
+ if (optValue.has_value()) {
+ const auto& value = *optValue;
+ return MetadataWriter{destBuffer, destBufferSize}
+ .write(value.maxContentLightLevel)
+ .write(value.maxFrameAverageLightLevel)
+ .desiredSize();
+ } else {
+ return 0;
+ }
+ }
+
+ // Double optional because the value type itself is an optional<>
+ using DecodeResult = std::optional<std::optional<Cta861_3>>;
+ [[nodiscard]] static DecodeResult decode(const void* _Nullable metadata, size_t metadataSize) {
+ std::optional<Cta861_3> optValue{std::nullopt};
+ if (metadataSize > 0) {
+ MetadataReader reader{metadata, metadataSize};
+ Cta861_3 value;
+ reader.read(value.maxContentLightLevel).read(value.maxFrameAverageLightLevel);
+ if (reader.ok()) {
+ optValue = std::move(value);
+ } else {
+ return std::nullopt;
+ }
+ }
+ return DecodeResult{std::move(optValue)};
+ }
+};
+
+template <>
+struct MetadataValue<std::optional<std::vector<uint8_t>>> {
+ [[nodiscard]] static int32_t encode(const std::optional<std::vector<uint8_t>>& value,
+ void* _Nullable destBuffer, size_t destBufferSize) {
+ if (!value.has_value()) {
+ return 0;
+ }
+ return MetadataWriter{destBuffer, destBufferSize}.write(*value).desiredSize();
+ }
+
+ using DecodeResult = std::optional<std::optional<std::vector<uint8_t>>>;
+ [[nodiscard]] static DecodeResult decode(const void* _Nonnull metadata, size_t metadataSize) {
+ std::optional<std::vector<uint8_t>> optValue;
+ if (metadataSize > 0) {
+ MetadataReader reader{metadata, metadataSize};
+ auto value = reader.readBuffer();
+ if (reader.ok()) {
+ optValue = std::move(value);
+ } else {
+ return std::nullopt;
+ }
+ }
+ return DecodeResult{std::move(optValue)};
+ }
+};
+
+template <StandardMetadataType>
+struct StandardMetadata {};
+
+#define DEFINE_TYPE(name, typeArg) \
+ template <> \
+ struct StandardMetadata<StandardMetadataType::name> { \
+ using value_type = typeArg; \
+ using value = MetadataValue<value_type>; \
+ static_assert( \
+ StandardMetadataType::name == \
+ ndk::internal::enum_values<StandardMetadataType>[static_cast<size_t>( \
+ StandardMetadataType::name)], \
+ "StandardMetadataType must have equivalent value to index"); \
+ }
+
+DEFINE_TYPE(BUFFER_ID, uint64_t);
+DEFINE_TYPE(NAME, std::string);
+DEFINE_TYPE(WIDTH, uint64_t);
+DEFINE_TYPE(HEIGHT, uint64_t);
+DEFINE_TYPE(LAYER_COUNT, uint64_t);
+DEFINE_TYPE(PIXEL_FORMAT_REQUESTED, PixelFormat);
+DEFINE_TYPE(PIXEL_FORMAT_FOURCC, uint32_t);
+DEFINE_TYPE(PIXEL_FORMAT_MODIFIER, uint64_t);
+DEFINE_TYPE(USAGE, BufferUsage);
+DEFINE_TYPE(ALLOCATION_SIZE, uint64_t);
+DEFINE_TYPE(PROTECTED_CONTENT, uint64_t);
+DEFINE_TYPE(COMPRESSION, ExtendableType);
+DEFINE_TYPE(INTERLACED, ExtendableType);
+DEFINE_TYPE(CHROMA_SITING, ExtendableType);
+DEFINE_TYPE(PLANE_LAYOUTS, std::vector<PlaneLayout>);
+DEFINE_TYPE(CROP, std::vector<Rect>);
+DEFINE_TYPE(DATASPACE, Dataspace);
+DEFINE_TYPE(BLEND_MODE, BlendMode);
+DEFINE_TYPE(SMPTE2086, std::optional<Smpte2086>);
+DEFINE_TYPE(CTA861_3, std::optional<Cta861_3>);
+DEFINE_TYPE(SMPTE2094_10, std::optional<std::vector<uint8_t>>);
+DEFINE_TYPE(SMPTE2094_40, std::optional<std::vector<uint8_t>>);
+
+#undef DEFINE_TYPE
+
+template <typename F, std::size_t... I>
+void invokeWithStandardMetadata(F&& f, StandardMetadataType type, std::index_sequence<I...>) {
+ // Setup the jump table, mapping from each type to a springboard that invokes the template
+ // function with the appropriate concrete type
+ using F_PTR = decltype(&f);
+ using THUNK = void (*)(F_PTR);
+ static constexpr auto jump = std::array<THUNK, sizeof...(I)>{[](F_PTR fp) {
+ constexpr StandardMetadataType type = ndk::internal::enum_values<StandardMetadataType>[I];
+ if constexpr (type != StandardMetadataType::INVALID) {
+ (*fp)(StandardMetadata<type>{});
+ }
+ }...};
+
+ auto index = static_cast<size_t>(type);
+ if (index >= 0 && index < jump.size()) {
+ jump[index](&f);
+ }
+}
+
+template <typename F, typename StandardMetadataSequence = std::make_index_sequence<
+ ndk::internal::enum_values<StandardMetadataType>.size()>>
+int32_t provideStandardMetadata(StandardMetadataType type, void* _Nullable destBuffer,
+ size_t destBufferSize, F&& f) {
+ int32_t retVal = -AIMAPPER_ERROR_UNSUPPORTED;
+ invokeWithStandardMetadata(
+ [&]<StandardMetadataType T>(StandardMetadata<T>) {
+ retVal = f.template operator()<T>(
+ [&](const typename StandardMetadata<T>::value_type& value) -> int32_t {
+ return StandardMetadata<T>::value::encode(value, destBuffer,
+ destBufferSize);
+ });
+ },
+ type, StandardMetadataSequence{});
+ return retVal;
+}
+
+template <typename F, typename StandardMetadataSequence = std::make_index_sequence<
+ ndk::internal::enum_values<StandardMetadataType>.size()>>
+AIMapper_Error applyStandardMetadata(StandardMetadataType type, const void* _Nonnull metadata,
+ size_t metadataSize, F&& f) {
+ AIMapper_Error retVal = AIMAPPER_ERROR_UNSUPPORTED;
+ invokeWithStandardMetadata(
+ [&]<StandardMetadataType T>(StandardMetadata<T>) {
+ auto value = StandardMetadata<T>::value::decode(metadata, metadataSize);
+ if (value.has_value()) {
+ retVal = f.template operator()<T>(std::move(*value));
+ } else {
+ retVal = AIMAPPER_ERROR_BAD_VALUE;
+ }
+ },
+ type, StandardMetadataSequence{});
+ return retVal;
+}
+
+} // namespace android::hardware::graphics::mapper
\ No newline at end of file
diff --git a/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperProvider.h b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperProvider.h
new file mode 100644
index 0000000..957fdc9
--- /dev/null
+++ b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperProvider.h
@@ -0,0 +1,222 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android-base/unique_fd.h>
+#include <android/hardware/graphics/mapper/IMapper.h>
+#include <log/log.h>
+
+#include <mutex>
+#include <optional>
+#include <type_traits>
+
+/**
+ * Helper utilities for providing an IMapper-StableC implementation.
+ */
+
+namespace vendor::mapper {
+
+/**
+ * Extend from this interface to provide Version 5 of the IMapper interface
+ */
+struct IMapperV5Impl {
+ static const auto version = AIMAPPER_VERSION_5;
+ virtual ~IMapperV5Impl() = default;
+
+ virtual AIMapper_Error importBuffer(const native_handle_t* _Nonnull handle,
+ buffer_handle_t _Nullable* _Nonnull outBufferHandle) = 0;
+
+ virtual AIMapper_Error freeBuffer(buffer_handle_t _Nonnull buffer) = 0;
+
+ virtual AIMapper_Error getTransportSize(buffer_handle_t _Nonnull buffer,
+ uint32_t* _Nonnull outNumFds,
+ uint32_t* _Nonnull outNumInts) = 0;
+
+ virtual AIMapper_Error lock(buffer_handle_t _Nonnull buffer, uint64_t cpuUsage,
+ ARect accessRegion, int acquireFence,
+ void* _Nullable* _Nonnull outData) = 0;
+
+ virtual AIMapper_Error unlock(buffer_handle_t _Nonnull buffer, int* _Nonnull releaseFence) = 0;
+
+ virtual AIMapper_Error flushLockedBuffer(buffer_handle_t _Nonnull buffer) = 0;
+
+ virtual AIMapper_Error rereadLockedBuffer(buffer_handle_t _Nonnull buffer) = 0;
+
+ virtual int32_t getMetadata(buffer_handle_t _Nonnull buffer, AIMapper_MetadataType metadataType,
+ void* _Nullable destBuffer, size_t destBufferSize) = 0;
+
+ virtual int32_t getStandardMetadata(buffer_handle_t _Nonnull buffer,
+ int64_t standardMetadataType, void* _Nullable destBuffer,
+ size_t destBufferSize) = 0;
+
+ virtual AIMapper_Error setMetadata(buffer_handle_t _Nonnull buffer,
+ AIMapper_MetadataType metadataType,
+ const void* _Nonnull metadata, size_t metadataSize) = 0;
+
+ virtual AIMapper_Error setStandardMetadata(buffer_handle_t _Nonnull buffer,
+ int64_t standardMetadataType,
+ const void* _Nonnull metadata,
+ size_t metadataSize) = 0;
+
+ virtual AIMapper_Error listSupportedMetadataTypes(
+ const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
+ size_t* _Nonnull outNumberOfDescriptions) = 0;
+
+ virtual AIMapper_Error dumpBuffer(buffer_handle_t _Nonnull bufferHandle,
+ AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+ void* _Null_unspecified context) = 0;
+
+ virtual AIMapper_Error dumpAllBuffers(
+ AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,
+ AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+ void* _Null_unspecified context) = 0;
+
+ virtual AIMapper_Error getReservedRegion(buffer_handle_t _Nonnull buffer,
+ void* _Nullable* _Nonnull outReservedRegion,
+ uint64_t* _Nonnull outReservedSize) = 0;
+};
+
+namespace provider {
+#ifndef __cpp_inline_variables
+#error "Only C++17 & newer is supported; inline variables is missing"
+#endif
+
+inline void* _Nullable sIMapperInstance = nullptr;
+} // namespace provider
+
+template <typename IMPL>
+class IMapperProvider {
+ private:
+ static_assert(IMPL::version >= AIMAPPER_VERSION_5, "Must be at least AIMAPPER_VERSION_5");
+ static_assert(std::is_final_v<IMPL>, "Implementation must be final");
+ static_assert(std::is_constructible_v<IMPL>, "Implementation must have a no-args constructor");
+
+ std::once_flag mLoadOnceFlag;
+ std::optional<IMPL> mImpl;
+ AIMapper mMapper = {};
+
+ static IMPL& impl() {
+ return *reinterpret_cast<IMapperProvider<IMPL>*>(provider::sIMapperInstance)->mImpl;
+ }
+
+ void bindV5() {
+ mMapper.v5 = {
+ .importBuffer = [](const native_handle_t* _Nonnull handle,
+ buffer_handle_t _Nullable* _Nonnull outBufferHandle)
+ -> AIMapper_Error { return impl().importBuffer(handle, outBufferHandle); },
+
+ .freeBuffer = [](buffer_handle_t _Nonnull buffer) -> AIMapper_Error {
+ return impl().freeBuffer(buffer);
+ },
+
+ .getTransportSize = [](buffer_handle_t _Nonnull buffer,
+ uint32_t* _Nonnull outNumFds,
+ uint32_t* _Nonnull outNumInts) -> AIMapper_Error {
+ return impl().getTransportSize(buffer, outNumFds, outNumInts);
+ },
+
+ .lock = [](buffer_handle_t _Nonnull buffer, uint64_t cpuUsage, ARect accessRegion,
+ int acquireFence, void* _Nullable* _Nonnull outData) -> AIMapper_Error {
+ return impl().lock(buffer, cpuUsage, accessRegion, acquireFence, outData);
+ },
+
+ .unlock = [](buffer_handle_t _Nonnull buffer, int* _Nonnull releaseFence)
+ -> AIMapper_Error { return impl().unlock(buffer, releaseFence); },
+
+ .flushLockedBuffer = [](buffer_handle_t _Nonnull buffer) -> AIMapper_Error {
+ return impl().flushLockedBuffer(buffer);
+ },
+
+ .rereadLockedBuffer = [](buffer_handle_t _Nonnull buffer) -> AIMapper_Error {
+ return impl().rereadLockedBuffer(buffer);
+ },
+
+ .getMetadata = [](buffer_handle_t _Nonnull buffer,
+ AIMapper_MetadataType metadataType, void* _Nullable destBuffer,
+ size_t destBufferSize) -> int32_t {
+ return impl().getMetadata(buffer, metadataType, destBuffer, destBufferSize);
+ },
+
+ .getStandardMetadata = [](buffer_handle_t _Nonnull buffer,
+ int64_t standardMetadataType, void* _Nullable destBuffer,
+ size_t destBufferSize) -> int32_t {
+ return impl().getStandardMetadata(buffer, standardMetadataType, destBuffer,
+ destBufferSize);
+ },
+
+ .setMetadata = [](buffer_handle_t _Nonnull buffer,
+ AIMapper_MetadataType metadataType, const void* _Nonnull metadata,
+ size_t metadataSize) -> AIMapper_Error {
+ return impl().setMetadata(buffer, metadataType, metadata, metadataSize);
+ },
+
+ .setStandardMetadata =
+ [](buffer_handle_t _Nonnull buffer, int64_t standardMetadataType,
+ const void* _Nonnull metadata, size_t metadataSize) -> AIMapper_Error {
+ return impl().setStandardMetadata(buffer, standardMetadataType, metadata,
+ metadataSize);
+ },
+
+ .listSupportedMetadataTypes =
+ [](const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
+ size_t* _Nonnull outNumberOfDescriptions) -> AIMapper_Error {
+ return impl().listSupportedMetadataTypes(outDescriptionList,
+ outNumberOfDescriptions);
+ },
+
+ .dumpBuffer = [](buffer_handle_t _Nonnull bufferHandle,
+ AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+ void* _Null_unspecified context) -> AIMapper_Error {
+ return impl().dumpBuffer(bufferHandle, dumpBufferCallback, context);
+ },
+
+ .dumpAllBuffers =
+ [](AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,
+ AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+ void* _Null_unspecified context) {
+ return impl().dumpAllBuffers(beginDumpBufferCallback,
+ dumpBufferCallback, context);
+ },
+
+ .getReservedRegion = [](buffer_handle_t _Nonnull buffer,
+ void* _Nullable* _Nonnull outReservedRegion,
+ uint64_t* _Nonnull outReservedSize) -> AIMapper_Error {
+ return impl().getReservedRegion(buffer, outReservedRegion, outReservedSize);
+ },
+ };
+ }
+
+ public:
+ explicit IMapperProvider() = default;
+
+ AIMapper_Error load(AIMapper* _Nullable* _Nonnull outImplementation) {
+ std::call_once(mLoadOnceFlag, [this] {
+ LOG_ALWAYS_FATAL_IF(provider::sIMapperInstance != nullptr,
+ "AIMapper implementation already loaded!");
+ provider::sIMapperInstance = this;
+ mImpl.emplace();
+ mMapper.version = IMPL::version;
+ if (IMPL::version >= AIMAPPER_VERSION_5) {
+ bindV5();
+ }
+ });
+ *outImplementation = &mMapper;
+ return AIMAPPER_ERROR_NONE;
+ }
+};
+
+} // namespace vendor::mapper
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
new file mode 100644
index 0000000..0f6d146
--- /dev/null
+++ b/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
@@ -0,0 +1,691 @@
+/*
+ * 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.
+ */
+
+/**
+ * IMapper Stable-C HAL interface
+ *
+ * This file represents the sphal interface between libui & the IMapper HAL implementation.
+ * A vendor implementation of this interface is retrieved by looking up the vendor imapper
+ * implementation library via the IAllocator AIDL interface.
+ *
+ * This interface is not intended for general use.
+ */
+
+#pragma once
+
+#include <sys/cdefs.h>
+#include <cinttypes>
+#include <cstddef>
+#include <type_traits>
+
+#include <android/rect.h>
+#include <cutils/native_handle.h>
+
+__BEGIN_DECLS
+
+/**
+ * AIMapper versioning
+ *
+ * IMapper versions 0-1 are pre-treble
+ * IMapper versions 2-4 are HIDL
+ * C-style AIMapper API starts at 5
+ */
+enum AIMapper_Version : uint32_t {
+ AIMAPPER_VERSION_5 = 5,
+};
+
+/**
+ * Possible AIMapper errors
+ * Values are the same as IMapper 4.0's Error type for simplicity
+ */
+enum AIMapper_Error : int32_t {
+ /**
+ * No error.
+ */
+ AIMAPPER_ERROR_NONE = 0,
+ /**
+ * Invalid BufferDescriptor.
+ */
+ AIMAPPER_ERROR_BAD_DESCRIPTOR = 1,
+ /**
+ * Invalid buffer handle.
+ */
+ AIMAPPER_ERROR_BAD_BUFFER = 2,
+ /**
+ * Invalid HardwareBufferDescription.
+ */
+ AIMAPPER_ERROR_BAD_VALUE = 3,
+ /**
+ * Resource unavailable.
+ */
+ AIMAPPER_ERROR_NO_RESOURCES = 5,
+ /**
+ * Permanent failure.
+ */
+ AIMAPPER_ERROR_UNSUPPORTED = 7,
+};
+
+/**
+ * MetadataType represents the different types of buffer metadata that could be
+ * associated with a buffer. It is used by IMapper to help get and set buffer metadata
+ * on the buffer's native handle.
+ *
+ * Standard buffer metadata will have the name field set to
+ * "android.hardware.graphics.common.StandardMetadataType" and will contain values
+ * from StandardMetadataType.aidl.
+ *
+ * Vendor-provided metadata should be prefixed with a "vendor.mycompanyname.*" namespace. It is
+ * recommended that the metadata follows the pattern of StandardMetadaType.aidl. That is, an
+ * aidl-defined enum with @VendorStability on it and the naming then matching that type such
+ * as "vendor.mycompanyname.graphics.common.MetadataType" with the value field then set to the
+ * aidl's enum value.
+ *
+ * Each company should create their own enum & namespace. The name
+ * field prevents values from different companies from colliding.
+ */
+typedef struct AIMapper_MetadataType {
+ const char* _Nonnull name;
+ int64_t value;
+} AIMapper_MetadataType;
+
+typedef struct AIMapper_MetadataTypeDescription {
+ /**
+ * The `name` of the metadataType must be valid for the lifetime of the process
+ */
+ AIMapper_MetadataType metadataType;
+ /**
+ * description should contain a string representation of the MetadataType.
+ *
+ * For example: "MyExampleMetadataType is a 64-bit timestamp in nanoseconds
+ * that indicates when a buffer is decoded. It is set by the media HAL after
+ * a buffer is decoded. It is used by the display HAL for hardware
+ * synchronization".
+ *
+ * This field is required for any non-StandardMetadataTypes. For StandardMetadataTypes this
+ * field may be null. The lifetime of this pointer must be valid for the duration of the
+ * process (that is, a static const char*).
+ */
+ const char* _Nullable description;
+ /**
+ * isGettable represents if the MetadataType can be get.
+ */
+ bool isGettable;
+ /**
+ * isSettable represents if the MetadataType can be set.
+ */
+ bool isSettable;
+
+ /** Reserved for future use; must be zero-initialized currently */
+ uint8_t reserved[32];
+} AIMapper_MetadataTypeDescription;
+
+/**
+ * Callback that is passed to dumpBuffer.
+ *
+ * @param context The caller-provided void* that was passed to dumpBuffer.
+ * @param metadataType The type of the metadata passed to the callback
+ * @param value A pointer to the value of the metadata. The lifetime of this pointer is only
+ * valid for the duration of the call
+ * @param valueSize The size of the value buffer.
+ */
+typedef void (*AIMapper_DumpBufferCallback)(void* _Null_unspecified context,
+ AIMapper_MetadataType metadataType,
+ const void* _Nonnull value, size_t valueSize);
+
+/**
+ * Callback that is passed to dumpAllBuffers.
+ *
+ * Indicates that a buffer is about to be dumped. Will be followed by N calls to
+ * AIMapper_DumpBufferCallback for all the metadata for this buffer.
+ *
+ * @param context The caller-provided void* that was passed to dumpAllBuffers.
+ */
+typedef void (*AIMapper_BeginDumpBufferCallback)(void* _Null_unspecified context);
+
+/**
+ * Implementation of AIMAPPER_VERSION_5
+ * All functions must not be null & must provide a valid implementation.
+ */
+typedef struct AIMapperV5 {
+ /**
+ * Imports a raw buffer handle to create an imported buffer handle for use
+ * with the rest of the mapper or with other in-process libraries.
+ *
+ * A buffer handle is considered raw when it is cloned (e.g., with
+ * `native_handle_clone()`) from another buffer handle locally, or when it
+ * is received from another HAL server/client or another process. A raw
+ * buffer handle must not be used to access the underlying graphic
+ * buffer. It must be imported to create an imported handle first.
+ *
+ * This function must at least validate the raw handle before creating the
+ * imported handle. It must also support importing the same raw handle
+ * multiple times to create multiple imported handles. The imported handle
+ * must be considered valid everywhere in the process, including in
+ * another instance of the mapper.
+ *
+ * Because of passthrough HALs, a raw buffer handle received from a HAL
+ * may actually have been imported in the process. importBuffer() must treat
+ * such a handle as if it is raw and must not return `BAD_BUFFER`. The
+ * returned handle is independent from the input handle as usual, and
+ * freeBuffer() must be called on it when it is no longer needed.
+ *
+ * @param handle Raw buffer handle to import.
+ * @param outBufferHandle The resulting imported buffer handle.
+ * @return Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `NO_RESOURCES` if the raw handle cannot be imported due to
+ * unavailability of resources.
+ */
+ AIMapper_Error (*_Nonnull importBuffer)(const native_handle_t* _Nonnull handle,
+ buffer_handle_t _Nullable* _Nonnull outBufferHandle);
+
+ /**
+ * Frees a buffer handle. Buffer handles returned by importBuffer() must be
+ * freed with this function when no longer needed.
+ *
+ * This function must free up all resources allocated by importBuffer() for
+ * the imported handle. For example, if the imported handle was created
+ * with `native_handle_create()`, this function must call
+ * `native_handle_close()` and `native_handle_delete()`.
+ *
+ * @param buffer Imported buffer handle.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid.
+ */
+ AIMapper_Error (*_Nonnull freeBuffer)(buffer_handle_t _Nonnull buffer);
+
+ /**
+ * Calculates the transport size of a buffer. An imported buffer handle is a
+ * raw buffer handle with the process-local runtime data appended. This
+ * function, for example, allows a caller to omit the process-local runtime
+ * data at the tail when serializing the imported buffer handle.
+ *
+ * Note that a client might or might not omit the process-local runtime data
+ * when sending an imported buffer handle. The mapper must support both
+ * cases on the receiving end.
+ *
+ * @param buffer Buffer to get the transport size from.
+ * @param outNumFds The number of file descriptors needed for transport.
+ * @param outNumInts The number of integers needed for transport.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid.
+ */
+ AIMapper_Error (*_Nonnull getTransportSize)(buffer_handle_t _Nonnull buffer,
+ uint32_t* _Nonnull outNumFds,
+ uint32_t* _Nonnull outNumInts);
+
+ /**
+ * Locks the given buffer for the specified CPU usage.
+ *
+ * Locking the same buffer simultaneously from multiple threads is
+ * permitted, but if any of the threads attempt to lock the buffer for
+ * writing, the behavior is undefined, except that it must not cause
+ * process termination or block the client indefinitely. Leaving the
+ * buffer content in an indeterminate state or returning an error are both
+ * acceptable.
+ *
+ * 1D buffers (width = size in bytes, height = 1, pixel_format = BLOB) must
+ * "lock in place". The buffers must be directly accessible via mapping.
+ *
+ * The client must not modify the content of the buffer outside of
+ * @p accessRegion, and the device need not guarantee that content outside
+ * of @p accessRegion is valid for reading. The result of reading or writing
+ * outside of @p accessRegion is undefined, except that it must not cause
+ * process termination.
+ *
+ * An accessRegion of all-zeros means the entire buffer. That is, it is
+ * equivalent to '(0,0)-(buffer width, buffer height)'.
+ *
+ * This function can lock both single-planar and multi-planar formats. The caller
+ * should use get() to get information about the buffer they are locking.
+ * get() can be used to get information about the planes, offsets, stride,
+ * etc.
+ *
+ * This function must also work on buffers with
+ * `AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_*` if supported by the device, as well
+ * as with any other formats requested by multimedia codecs when they are
+ * configured with a flexible-YUV-compatible color format.
+ *
+ * On success, @p data must be filled with a pointer to the locked buffer
+ * memory. This address will represent the top-left corner of the entire
+ * buffer, even if @p accessRegion does not begin at the top-left corner.
+ *
+ * The locked buffer must adhere to the format requested at allocation time
+ * in the BufferDescriptorInfo.
+ *
+ * @param buffer Buffer to lock.
+ * @param cpuUsage CPU usage flags to request. See BufferUsage.aidl for possible values.
+ * @param accessRegion Portion of the buffer that the client intends to
+ * access.
+ * @param acquireFence Handle containing a file descriptor referring to a
+ * sync fence object, which will be signaled when it is safe for the
+ * mapper to lock the buffer. @p acquireFence may be an empty fence (-1) if
+ * it is already safe to lock. Ownership is passed to the callee and it is the
+ * implementations responsibility to ensure it is closed even when an error
+ * occurs.
+ * @param outData CPU-accessible pointer to the buffer data.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid or is incompatible with this
+ * function.
+ * - `BAD_VALUE` if @p cpuUsage is 0, contains non-CPU usage flags, or
+ * is incompatible with the buffer. Also if the @p accessRegion is
+ * outside the bounds of the buffer or the accessRegion is invalid.
+ * - `NO_RESOURCES` if the buffer cannot be locked at this time. Note
+ * that locking may succeed at a later time.
+ * @return data CPU-accessible pointer to the buffer data.
+ */
+ AIMapper_Error (*_Nonnull lock)(buffer_handle_t _Nonnull buffer, uint64_t cpuUsage,
+ ARect accessRegion, int acquireFence,
+ void* _Nullable* _Nonnull outData);
+
+ /**
+ * Unlocks a buffer to indicate all CPU accesses to the buffer have
+ * completed.
+ *
+ * @param buffer Buffer to unlock.
+ * @param releaseFence Handle containing a file descriptor referring to a
+ * sync fence object. The sync fence object will be signaled when the
+ * mapper has completed any pending work. @p releaseFence may be an
+ * empty fence (-1).
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid or not locked.
+ */
+ AIMapper_Error (*_Nonnull unlock)(buffer_handle_t _Nonnull buffer, int* _Nonnull releaseFence);
+
+ /**
+ * Flushes the contents of a locked buffer.
+ *
+ * This function flushes the CPUs caches for the range of all the buffer's
+ * planes and metadata. This should behave similarly to unlock() except the
+ * buffer should remain mapped to the CPU.
+ *
+ * The client is still responsible for calling unlock() when it is done
+ * with all CPU accesses to the buffer.
+ *
+ * If non-CPU blocks are simultaneously writing the buffer, the locked
+ * copy should still be flushed but what happens is undefined except that
+ * it should not cause any crashes.
+ *
+ * @param buffer Buffer to flush.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid or not locked.
+ */
+ AIMapper_Error (*_Nonnull flushLockedBuffer)(buffer_handle_t _Nonnull buffer);
+
+ /**
+ * Rereads the contents of a locked buffer.
+ *
+ * This should fetch the most recent copy of the locked buffer.
+ *
+ * It may reread locked copies of the buffer in other processes.
+ *
+ * The client is still responsible for calling unlock() when it is done
+ * with all CPU accesses to the buffer.
+ *
+ * @param buffer Buffer to reread.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid or not locked.
+ * - `NO_RESOURCES` if the buffer cannot be reread at this time. Note
+ * that rereading may succeed at a later time.
+ */
+ AIMapper_Error (*_Nonnull rereadLockedBuffer)(buffer_handle_t _Nonnull buffer);
+
+ /**
+ * Description for get(...), set(...) and getFromBufferDescriptorInfo(...)
+ *
+ * ------------ Overview -----------------------------------
+ * Gralloc 4 adds support for getting and setting buffer metadata on a buffer.
+ *
+ * To get buffer metadata, the client passes in a buffer handle and a token that
+ * represents the type of buffer metadata they would like to get. IMapper returns
+ * a byte stream that contains the buffer metadata. To set the buffer metadata, the
+ * client passes in a buffer handle and a token that represents the type of buffer
+ * metadata they would like to set and a byte stream that contains the buffer metadata
+ * they are setting.
+ *
+ * Buffer metadata is global for a buffer. When the metadata is set on the buffer
+ * in a process, the updated metadata should be available to all other processes.
+ * Please see "Storing and Propagating Metadata" below for more details.
+ *
+ * The getter and setter functions have been optimized for easy vendor extension.
+ * They do not require a formal extension to add support for getting and setting
+ * vendor defined buffer metadata. See "Buffer Metadata Token" and
+ * "Buffer Metadata Stream" below for more details.
+ *
+ * ------------ Storing and Propagating Metadata -----------
+ * Buffer metadata must be global. Any changes to the metadata must be propagated
+ * to all other processes immediately. Vendors may chose how they would like support
+ * this functionality.
+ *
+ * We recommend supporting this functionality by allocating an extra page of shared
+ * memory and storing it in the buffer's native_handle_t. The buffer metadata can
+ * be stored in the extra page of shared memory. Set operations are automatically
+ * propagated to all other processes.
+ *
+ * ------------ Buffer Metadata Synchronization ------------
+ * There are no explicit buffer metadata synchronization primitives. Many devices
+ * before gralloc 4 already support getting and setting of global buffer metadata
+ * with no explicit synchronization primitives. Adding synchronization primitives
+ * would just add unnecessary complexity.
+ *
+ * The general rule is if a process has permission to write to a buffer, they
+ * have permission to write to the buffer's writable metadata. If a process has permission
+ * to read from a buffer, they have permission to read the buffer's metadata.
+ *
+ * There is one exception to this rule. Fences CANNOT be used to protect a buffer's
+ * metadata. A process should finish writing to a buffer's metadata before
+ * sending the buffer to another process that will read or write to the buffer.
+ * This exception is needed because sometimes userspace needs to read the
+ * buffer's metadata before the buffer's contents are ready.
+ *
+ * As a simple example: an app renders to a buffer and then displays the buffer.
+ * In this example when the app renders to the buffer, both the buffer and its
+ * metadata need to be updated. The app's process queues up its work on the GPU
+ * and gets back an acquire fence. The app's process must update the buffer's
+ * metadata before enqueuing the buffer to SurfaceFlinger. The app process CANNOT
+ * update the buffer's metadata after enqueuing the buffer. When HardwareComposer
+ * receives the buffer, it is immediately safe to read the buffer's metadata
+ * and use it to program the display driver. To read the buffer's contents,
+ * display driver must still wait on the acquire fence.
+ *
+ * ------------ Buffer Metadata Token ----------------------
+ * In order to allow arbitrary vendor defined metadata, the token used to access
+ * metadata is defined defined as a struct that has a string representing
+ * the enum type and an int that represents the enum value. The string protects
+ * different enum values from colliding.
+ *
+ * The token struct (MetadataType) is defined as a C struct since it
+ * is passed into a C function. The standard buffer metadata types are NOT
+ * defined as a C enum but instead as an AIDL enum to allow for broader usage across
+ * other HALs and libraries. By putting the enum in the
+ * stable AIDL (hardware/interfaces/graphics/common/aidl/android/hardware/
+ * graphics/common/StandardMetadataType.aidl), vendors will be able to optionally
+ * choose to support future standard buffer metadata types without upgrading
+ * IMapper versions. For more information see the description of "struct MetadataType".
+ *
+ * ------------ Buffer Metadata Stream ---------------------
+ * The buffer metadata is get and set as a void* buffer. By getting
+ * and setting buffer metadata as a generic buffer, vendors can use the standard
+ * getters and setter functions defined here. Vendors do NOT need to add their own
+ * getters and setter functions for each new type of buffer metadata.
+ *
+ * Converting buffer metadata into a byte stream can be non-trivial. For the standard
+ * buffer metadata types defined in StandardMetadataType.aidl, there are also
+ * support functions that will encode the buffer metadata into a byte stream
+ * and decode the buffer metadata from a byte stream. We STRONGLY recommend using
+ * these support functions. The framework will use them when getting and setting
+ * metadata. The support functions are defined in
+ * frameworks/native/libs/gralloc/types/include/gralloctypes/Gralloc4.h.
+ */
+
+ /**
+ * Gets the buffer metadata for a given MetadataType.
+ *
+ * Buffer metadata can be changed after allocation so clients should avoid "caching"
+ * the buffer metadata. For example, if the video resolution changes and the buffers
+ * are not reallocated, several buffer metadata values may change without warning.
+ * Clients should not expect the values to be constant. They should requery them every
+ * frame. The only exception is buffer metadata that is determined at allocation
+ * time. For StandardMetadataType values, only BUFFER_ID, NAME, WIDTH,
+ * HEIGHT, LAYER_COUNT, PIXEL_FORMAT_REQUESTED and USAGE are safe to cache because
+ * they are determined at allocation time.
+ *
+ * @param buffer Buffer containing desired metadata
+ * @param metadataType MetadataType for the metadata value being queried
+ * @param destBuffer Pointer to a buffer in which to store the result of the get() call; if
+ * null, the computed output size or error must still be returned.
+ * @param destBufferSize How large the destBuffer buffer is. If destBuffer is null this must be
+ * 0.
+ * @return The number of bytes written to `destBuffer` or which would have been written
+ * if `destBufferSize` was large enough.
+ * A negative value indicates an error, which may be
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `UNSUPPORTED` when metadataType is unknown/unsupported.
+ * IMapper must support getting all StandardMetadataType.aidl values defined
+ * at the time the device first launches.
+ */
+ int32_t (*_Nonnull getMetadata)(buffer_handle_t _Nonnull buffer,
+ AIMapper_MetadataType metadataType, void* _Nullable destBuffer,
+ size_t destBufferSize);
+
+ /**
+ * Gets the buffer metadata for a StandardMetadataType.
+ *
+ * This is equivalent to `getMetadata` when passed an AIMapper_MetadataType with name
+ * set to "android.hardware.graphics.common.StandardMetadataType"
+ *
+ * Buffer metadata can be changed after allocation so clients should avoid "caching"
+ * the buffer metadata. For example, if the video resolution changes and the buffers
+ * are not reallocated, several buffer metadata values may change without warning.
+ * Clients should not expect the values to be constant. They should requery them every
+ * frame. The only exception is buffer metadata that is determined at allocation
+ * time. For StandardMetadataType values, only BUFFER_ID, NAME, WIDTH,
+ * HEIGHT, LAYER_COUNT, PIXEL_FORMAT_REQUESTED and USAGE are safe to cache because
+ * they are determined at allocation time.
+ *
+ * @param buffer Buffer containing desired metadata
+ * @param standardMetadataType StandardMetadataType for the metadata value being queried
+ * @param destBuffer Pointer to a buffer in which to store the result of the get() call; if
+ * null, the computed output size or error must still be returned.
+ * @param destBufferSize How large the destBuffer buffer is. If destBuffer is null this must be
+ * 0.
+ * @return The number of bytes written to `destBuffer` or which would have been written
+ * if `destBufferSize` was large enough.
+ * A negative value indicates an error, which may be
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `UNSUPPORTED` when metadataType is unknown/unsupported.
+ * IMapper must support getting all StandardMetadataType.aidl values defined
+ * at the time the device first launches.
+ */
+ int32_t (*_Nonnull getStandardMetadata)(buffer_handle_t _Nonnull buffer,
+ int64_t standardMetadataType,
+ void* _Nullable destBuffer, size_t destBufferSize);
+
+ /**
+ * Sets the global value for a given MetadataType.
+ *
+ * Metadata fields are not required to be settable. This function can
+ * return Error::UNSUPPORTED whenever it doesn't support setting a
+ * particular Metadata field.
+ *
+ * The framework will attempt to set the following StandardMetadataType
+ * values: DATASPACE, SMPTE2086, CTA861_3, and BLEND_MODE.
+ * We require everyone to support setting those fields. Framework will also attempt to set
+ * SMPTE2094_40 and SMPTE2094_10 if available, and it is required to support setting those
+ * if it is possible to get them. If a device's Composer implementation supports a field,
+ * it should be supported here. Over time these metadata fields will be moved out of
+ * Composer/BufferQueue/etc. and into the buffer's Metadata fields.
+ *
+ * @param buffer Buffer receiving desired metadata
+ * @param metadataType MetadataType for the metadata value being set
+ * @param metadata Pointer to a buffer of bytes representing the value associated with
+ * @param metadataSize The size of the metadata buffer
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `BAD_VALUE` when the field is constant and can never be set (such as
+ * BUFFER_ID, NAME, WIDTH, HEIGHT, LAYER_COUNT, PIXEL_FORMAT_REQUESTED and
+ * USAGE)
+ * - `NO_RESOURCES` if the set cannot be fulfilled due to unavailability of
+ * resources.
+ * - `UNSUPPORTED` when metadataType is unknown/unsupported or setting
+ * it is unsupported. Unsupported should also be returned if the metadata
+ * is malformed.
+ */
+ AIMapper_Error (*_Nonnull setMetadata)(buffer_handle_t _Nonnull buffer,
+ AIMapper_MetadataType metadataType,
+ const void* _Nonnull metadata, size_t metadataSize);
+
+ /**
+ * Sets the global value for a given MetadataType.
+ *
+ * This is equivalent to `setMetadata` when passed an AIMapper_MetadataType with name
+ * set to "android.hardware.graphics.common.StandardMetadataType"
+ *
+ * Metadata fields are not required to be settable. This function can
+ * return Error::UNSUPPORTED whenever it doesn't support setting a
+ * particular Metadata field.
+ *
+ * The framework will attempt to set the following StandardMetadataType
+ * values: DATASPACE, SMPTE2086, CTA861_3, and BLEND_MODE.
+ * We require everyone to support setting those fields. Framework will also attempt to set
+ * SMPTE2094_40 and SMPTE2094_10 if available, and it is required to support setting those
+ * if it is possible to get them. If a device's Composer implementation supports a field,
+ * it should be supported here. Over time these metadata fields will be moved out of
+ * Composer/BufferQueue/etc. and into the buffer's Metadata fields.
+ *
+ * @param buffer Buffer receiving desired metadata
+ * @param standardMetadataType StandardMetadataType for the metadata value being set
+ * @param metadata Pointer to a buffer of bytes representing the value associated with
+ * @param metadataSize The size of the metadata buffer
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `BAD_VALUE` when the field is constant and can never be set (such as
+ * BUFFER_ID, NAME, WIDTH, HEIGHT, LAYER_COUNT, PIXEL_FORMAT_REQUESTED and
+ * USAGE)
+ * - `NO_RESOURCES` if the set cannot be fulfilled due to unavailability of
+ * resources.
+ * - `UNSUPPORTED` when metadataType is unknown/unsupported or setting
+ * it is unsupported. Unsupported should also be returned if the metadata
+ * is malformed.
+ */
+ AIMapper_Error (*_Nonnull setStandardMetadata)(buffer_handle_t _Nonnull buffer,
+ int64_t standardMetadataType,
+ const void* _Nonnull metadata,
+ size_t metadataSize);
+
+ /**
+ * Lists all the MetadataTypes supported by IMapper as well as a description
+ * of each supported MetadataType. For StandardMetadataTypes, the description
+ * string can be left empty.
+ *
+ * This list is expected to be static & thus the returned array must be valid for the
+ * lifetime of the process.
+ *
+ * @param outDescriptionList The list of descriptions
+ * @param outNumberOfDescriptions How many descriptions are in `outDescriptionList`
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `UNSUPPORTED` if there's any error
+ */
+ AIMapper_Error (*_Nonnull listSupportedMetadataTypes)(
+ const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
+ size_t* _Nonnull outNumberOfDescriptions);
+
+ /**
+ * Dumps a buffer's metadata.
+ *
+ * @param buffer The buffer to dump the metadata for
+ * @param dumpBufferCallback Callback that will be invoked for each of the metadata fields
+ * @param context A caller-provided context to be passed to the dumpBufferCallback
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `NO_RESOURCES` if the get cannot be fulfilled due to unavailability of
+ * resources.
+ */
+ AIMapper_Error (*_Nonnull dumpBuffer)(buffer_handle_t _Nonnull buffer,
+ AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+ void* _Null_unspecified context);
+
+ /**
+ * Dump the metadata for all imported buffers in the current process
+ *
+ * The HAL implementation should invoke beginDumpCallback before dumping a buffer's metadata,
+ * followed by N calls to dumpBufferCallback for that buffer's metadata fields. The call
+ * sequence should follow this pseudocode:
+ *
+ * for (auto buffer : gListOfImportedBuffers) {
+ * beginDumpCallback(context);
+ * for (auto metadata : buffer->allMetadata()) {
+ * dumpBufferCallback(context, metadata...);
+ * }
+ * }
+ *
+ * @param beginDumpCallback Signals that a buffer is about to be dumped
+ * @param dumpBufferCallback Callback that will be invoked for each of the metadata fields
+ * @param context A caller-provided context to be passed to beginDumpCallback and
+ * dumpBufferCallback
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `NO_RESOURCES` if the get cannot be fulfilled due to unavailability of
+ * resources.
+ */
+ AIMapper_Error (*_Nonnull dumpAllBuffers)(
+ AIMapper_BeginDumpBufferCallback _Nonnull beginDumpCallback,
+ AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+ void* _Null_unspecified context);
+
+ /**
+ * Returns the region of shared memory associated with the buffer that is
+ * reserved for client use.
+ *
+ * The shared memory may be allocated from any shared memory allocator.
+ * The shared memory must be CPU-accessible and virtually contiguous. The
+ * starting address must be word-aligned.
+ *
+ * This function may only be called after importBuffer() has been called by the
+ * client. The reserved region must remain accessible until freeBuffer() has
+ * been called. After freeBuffer() has been called, the client must not access
+ * the reserved region.
+ *
+ * This reserved memory may be used in future versions of Android to
+ * help clients implement backwards compatible features without requiring
+ * IAllocator/IMapper updates.
+ *
+ * @param buffer Imported buffer handle.
+ * @param outReservedRegion CPU-accessible pointer to the reserved region
+ * @param outReservedSize the size of the reservedRegion that was requested
+ * in the BufferDescriptorInfo.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid.
+ */
+ AIMapper_Error (*_Nonnull getReservedRegion)(buffer_handle_t _Nonnull buffer,
+ void* _Nullable* _Nonnull outReservedRegion,
+ uint64_t* _Nonnull outReservedSize);
+
+} AIMapperV5;
+
+/**
+ * Return value for AIMapper_loadIMapper
+ *
+ * Note: This struct's size is not fixed and callers must never store it by-value as a result.
+ * Only fields up to those covered by `version` are allowed to be accessed.
+ */
+typedef struct AIMapper {
+ alignas(alignof(max_align_t)) AIMapper_Version version;
+ AIMapperV5 v5;
+} AIMapper;
+
+/**
+ * Loads the vendor-provided implementation of AIMapper
+ * @return Error status of the call.
+ * - `NONE` upon success
+ * - `UNSUPPORTED` if no implementation is available
+ */
+AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation);
+
+__END_DECLS
\ No newline at end of file
diff --git a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
new file mode 100644
index 0000000..326346c
--- /dev/null
+++ b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
@@ -0,0 +1,1763 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "VtsHalGraphicsMapperStableC_TargetTest"
+
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/graphics/allocator/AllocationError.h>
+#include <aidl/android/hardware/graphics/allocator/AllocationResult.h>
+#include <aidl/android/hardware/graphics/allocator/IAllocator.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android/binder_enums.h>
+#include <android/binder_manager.h>
+#include <android/dlext.h>
+#include <android/hardware/graphics/mapper/IMapper.h>
+#include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
+#include <gralloctypes/Gralloc4.h>
+#include <hidl/GtestPrinter.h>
+#include <system/graphics.h>
+
+#include <dlfcn.h>
+#include <drm/drm_fourcc.h>
+#include <gtest/gtest.h>
+#include <vndksupport/linker.h>
+#include <initializer_list>
+#include <optional>
+#include <string>
+#include <tuple>
+#include <vector>
+
+using namespace aidl::android::hardware::graphics::allocator;
+using namespace aidl::android::hardware::graphics::common;
+using namespace android;
+using namespace android::hardware;
+using namespace ::android::hardware::graphics::mapper;
+
+typedef AIMapper_Error (*AIMapper_loadIMapperFn)(AIMapper* _Nullable* _Nonnull outImplementation);
+
+inline constexpr BufferUsage operator|(BufferUsage lhs, BufferUsage rhs) {
+ using T = std::underlying_type_t<BufferUsage>;
+ return static_cast<BufferUsage>(static_cast<T>(lhs) | static_cast<T>(rhs));
+}
+
+inline BufferUsage& operator|=(BufferUsage& lhs, BufferUsage rhs) {
+ lhs = lhs | rhs;
+ return lhs;
+}
+
+struct YCbCr {
+ android_ycbcr yCbCr;
+ int64_t horizontalSubSampling;
+ int64_t verticalSubSampling;
+};
+
+constexpr const char* STANDARD_METADATA_NAME =
+ "android.hardware.graphics.common.StandardMetadataType";
+
+static bool isStandardMetadata(AIMapper_MetadataType metadataType) {
+ return strcmp(STANDARD_METADATA_NAME, metadataType.name) == 0;
+}
+
+static std::string toString(const std::vector<StandardMetadataType> types) {
+ std::stringstream buf;
+ buf << "[";
+ for (auto type : types) {
+ buf << toString(type) << ", ";
+ }
+ buf.seekp(-2, buf.cur);
+ buf << "]";
+ return buf.str();
+}
+
+class BufferHandle {
+ AIMapper* mIMapper;
+ buffer_handle_t mHandle = nullptr;
+
+ public:
+ explicit BufferHandle(AIMapper* mapper, native_handle_t* rawHandle) : mIMapper(mapper) {
+ EXPECT_EQ(AIMAPPER_ERROR_NONE, mIMapper->v5.importBuffer(rawHandle, &mHandle));
+ }
+
+ explicit BufferHandle(BufferHandle&& other) { *this = std::move(other); }
+
+ BufferHandle& operator=(BufferHandle&& other) noexcept {
+ reset();
+ mIMapper = other.mIMapper;
+ mHandle = other.mHandle;
+ other.mHandle = nullptr;
+ return *this;
+ }
+
+ ~BufferHandle() { reset(); }
+
+ constexpr explicit operator bool() const noexcept { return mHandle != nullptr; }
+
+ buffer_handle_t operator*() const noexcept { return mHandle; }
+
+ void reset() {
+ if (mHandle != nullptr) {
+ EXPECT_EQ(AIMAPPER_ERROR_NONE, mIMapper->v5.freeBuffer(mHandle));
+ mHandle = nullptr;
+ }
+ }
+};
+
+class BufferAllocation {
+ AIMapper* mIMapper;
+ native_handle_t* mRawHandle;
+ uint32_t mStride;
+ const BufferDescriptorInfo mInfo;
+
+ public:
+ BufferAllocation(const BufferAllocation&) = delete;
+ void operator=(const BufferAllocation&) = delete;
+
+ BufferAllocation(AIMapper* mapper, native_handle_t* handle, uint32_t stride,
+ const BufferDescriptorInfo& info)
+ : mIMapper(mapper), mRawHandle(handle), mStride(stride), mInfo(info) {}
+
+ ~BufferAllocation() {
+ if (mRawHandle == nullptr) return;
+
+ native_handle_close(mRawHandle);
+ native_handle_delete(mRawHandle);
+ }
+
+ uint32_t stride() const { return mStride; }
+ const BufferDescriptorInfo& info() const { return mInfo; }
+
+ BufferHandle import() { return BufferHandle{mIMapper, mRawHandle}; }
+
+ const native_handle_t* rawHandle() const { return mRawHandle; }
+};
+
+class GraphicsTestsBase {
+ private:
+ friend class BufferAllocation;
+ int32_t mIAllocatorVersion = 1;
+ std::shared_ptr<IAllocator> mAllocator;
+ AIMapper* mIMapper = nullptr;
+ AIMapper_loadIMapperFn mIMapperLoader;
+
+ protected:
+ void Initialize(std::shared_ptr<IAllocator> allocator) {
+ mAllocator = allocator;
+ ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
+ ASSERT_TRUE(mAllocator->getInterfaceVersion(&mIAllocatorVersion).isOk());
+ ASSERT_GE(mIAllocatorVersion, 2);
+ std::string mapperSuffix;
+ auto status = mAllocator->getIMapperLibrarySuffix(&mapperSuffix);
+ ASSERT_TRUE(status.isOk()) << "Failed to get IMapper library suffix";
+ std::string lib_name = "mapper." + mapperSuffix + ".so";
+ void* so = android_load_sphal_library(lib_name.c_str(), RTLD_LOCAL | RTLD_NOW);
+ ASSERT_NE(nullptr, so) << "Failed to load " << lib_name;
+ mIMapperLoader = (AIMapper_loadIMapperFn)dlsym(so, "AIMapper_loadIMapper");
+ ASSERT_NE(nullptr, mIMapperLoader) << "AIMapper_locaIMapper missing from " << lib_name;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mIMapperLoader(&mIMapper));
+ ASSERT_NE(mIMapper, nullptr);
+ }
+
+ public:
+ AIMapper_loadIMapperFn getIMapperLoader() const { return mIMapperLoader; }
+
+ std::unique_ptr<BufferAllocation> allocate(const BufferDescriptorInfo& descriptorInfo) {
+ AllocationResult result;
+ ::ndk::ScopedAStatus status = mAllocator->allocate2(descriptorInfo, 1, &result);
+ if (!status.isOk()) {
+ status_t error = status.getExceptionCode();
+ if (error == EX_SERVICE_SPECIFIC) {
+ error = status.getServiceSpecificError();
+ EXPECT_NE(OK, error) << "Failed to set error properly";
+ } else {
+ EXPECT_EQ(OK, error) << "Allocation transport failure";
+ }
+ return nullptr;
+ } else {
+ return std::make_unique<BufferAllocation>(mIMapper, dupFromAidl(result.buffers[0]),
+ result.stride, descriptorInfo);
+ }
+ }
+
+ std::unique_ptr<BufferAllocation> allocateGeneric() {
+ return allocate({
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::RGBA_8888,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ });
+ }
+
+ bool isSupported(const BufferDescriptorInfo& descriptorInfo) {
+ bool ret = false;
+ EXPECT_TRUE(mAllocator->isSupported(descriptorInfo, &ret).isOk());
+ return ret;
+ }
+
+ AIMapper* mapper() const { return mIMapper; }
+
+ template <StandardMetadataType T>
+ auto getStandardMetadata(buffer_handle_t bufferHandle)
+ -> decltype(StandardMetadata<T>::value::decode(nullptr, 0)) {
+ using Value = typename StandardMetadata<T>::value;
+ std::vector<uint8_t> buffer;
+ // Initial guess
+ buffer.resize(512);
+ int32_t sizeRequired = mapper()->v5.getStandardMetadata(
+ bufferHandle, static_cast<int64_t>(T), buffer.data(), buffer.size());
+ if (sizeRequired < 0) {
+ EXPECT_EQ(-AIMAPPER_ERROR_UNSUPPORTED, sizeRequired)
+ << "Received something other than UNSUPPORTED from valid getStandardMetadata "
+ "call";
+ return std::nullopt;
+ }
+ if (sizeRequired > buffer.size()) {
+ buffer.resize(sizeRequired);
+ sizeRequired = mapper()->v5.getStandardMetadata(bufferHandle, static_cast<int64_t>(T),
+ buffer.data(), buffer.size());
+ }
+ if (sizeRequired < 0 || sizeRequired >= buffer.size()) {
+ ADD_FAILURE() << "getStandardMetadata failed, received " << sizeRequired
+ << " with buffer size " << buffer.size();
+ // Generate a fail type
+ return std::nullopt;
+ }
+ return Value::decode(buffer.data(), sizeRequired);
+ }
+
+ template <StandardMetadataType T>
+ AIMapper_Error setStandardMetadata(buffer_handle_t bufferHandle,
+ const typename StandardMetadata<T>::value_type& value) {
+ using Value = typename StandardMetadata<T>::value;
+ int32_t sizeRequired = Value::encode(value, nullptr, 0);
+ if (sizeRequired < 0) {
+ EXPECT_GE(sizeRequired, 0) << "Failed to calculate required size";
+ return static_cast<AIMapper_Error>(-sizeRequired);
+ }
+ std::vector<uint8_t> buffer;
+ buffer.resize(sizeRequired);
+ sizeRequired = Value::encode(value, buffer.data(), buffer.size());
+ if (sizeRequired < 0 || sizeRequired > buffer.size()) {
+ ADD_FAILURE() << "Failed to encode with calculated size " << sizeRequired
+ << "; buffer size" << buffer.size();
+ return static_cast<AIMapper_Error>(-sizeRequired);
+ }
+ return mapper()->v5.setStandardMetadata(bufferHandle, static_cast<int64_t>(T),
+ buffer.data(), sizeRequired);
+ }
+
+ void verifyRGBA8888PlaneLayouts(const std::vector<PlaneLayout>& planeLayouts) {
+ ASSERT_EQ(1, planeLayouts.size());
+
+ const auto& planeLayout = planeLayouts.front();
+
+ ASSERT_EQ(4, planeLayout.components.size());
+
+ int64_t offsetInBitsR = -1;
+ int64_t offsetInBitsG = -1;
+ int64_t offsetInBitsB = -1;
+ int64_t offsetInBitsA = -1;
+
+ for (const auto& component : planeLayout.components) {
+ if (!gralloc4::isStandardPlaneLayoutComponentType(component.type)) {
+ continue;
+ }
+ EXPECT_EQ(8, component.sizeInBits);
+ if (component.type.value == gralloc4::PlaneLayoutComponentType_R.value) {
+ offsetInBitsR = component.offsetInBits;
+ }
+ if (component.type.value == gralloc4::PlaneLayoutComponentType_G.value) {
+ offsetInBitsG = component.offsetInBits;
+ }
+ if (component.type.value == gralloc4::PlaneLayoutComponentType_B.value) {
+ offsetInBitsB = component.offsetInBits;
+ }
+ if (component.type.value == gralloc4::PlaneLayoutComponentType_A.value) {
+ offsetInBitsA = component.offsetInBits;
+ }
+ }
+
+ EXPECT_EQ(0, offsetInBitsR);
+ EXPECT_EQ(8, offsetInBitsG);
+ EXPECT_EQ(16, offsetInBitsB);
+ EXPECT_EQ(24, offsetInBitsA);
+
+ EXPECT_EQ(0, planeLayout.offsetInBytes);
+ EXPECT_EQ(32, planeLayout.sampleIncrementInBits);
+ // Skip testing stride because any stride is valid
+ EXPECT_LE(planeLayout.widthInSamples * planeLayout.heightInSamples * 4,
+ planeLayout.totalSizeInBytes);
+ EXPECT_EQ(1, planeLayout.horizontalSubsampling);
+ EXPECT_EQ(1, planeLayout.verticalSubsampling);
+ }
+
+ void fillRGBA8888(uint8_t* data, uint32_t height, size_t strideInBytes, size_t widthInBytes) {
+ for (uint32_t y = 0; y < height; y++) {
+ memset(data, y, widthInBytes);
+ data += strideInBytes;
+ }
+ }
+
+ void verifyRGBA8888(const buffer_handle_t bufferHandle, const uint8_t* data, uint32_t height,
+ size_t strideInBytes, size_t widthInBytes) {
+ auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(bufferHandle);
+ ASSERT_TRUE(decodeResult.has_value());
+ const auto& planeLayouts = *decodeResult;
+ ASSERT_TRUE(planeLayouts.size() > 0);
+
+ verifyRGBA8888PlaneLayouts(planeLayouts);
+
+ for (uint32_t y = 0; y < height; y++) {
+ for (size_t i = 0; i < widthInBytes; i++) {
+ EXPECT_EQ(static_cast<uint8_t>(y), data[i]);
+ }
+ data += strideInBytes;
+ }
+ }
+
+ void traverseYCbCrData(const android_ycbcr& yCbCr, int32_t width, int32_t height,
+ int64_t hSubsampling, int64_t vSubsampling,
+ std::function<void(uint8_t*, uint8_t)> traverseFuncion) {
+ auto yData = static_cast<uint8_t*>(yCbCr.y);
+ auto cbData = static_cast<uint8_t*>(yCbCr.cb);
+ auto crData = static_cast<uint8_t*>(yCbCr.cr);
+ auto yStride = yCbCr.ystride;
+ auto cStride = yCbCr.cstride;
+ auto chromaStep = yCbCr.chroma_step;
+
+ for (uint32_t y = 0; y < height; y++) {
+ for (uint32_t x = 0; x < width; x++) {
+ auto val = static_cast<uint8_t>(height * y + x);
+
+ traverseFuncion(yData + yStride * y + x, val);
+
+ if (y % vSubsampling == 0 && x % hSubsampling == 0) {
+ uint32_t subSampleX = x / hSubsampling;
+ uint32_t subSampleY = y / vSubsampling;
+ const auto subSampleOffset = cStride * subSampleY + chromaStep * subSampleX;
+ const auto subSampleVal =
+ static_cast<uint8_t>(height * subSampleY + subSampleX);
+
+ traverseFuncion(cbData + subSampleOffset, subSampleVal);
+ traverseFuncion(crData + subSampleOffset, subSampleVal + 1);
+ }
+ }
+ }
+ }
+
+ void fillYCbCrData(const android_ycbcr& yCbCr, int32_t width, int32_t height,
+ int64_t hSubsampling, int64_t vSubsampling) {
+ traverseYCbCrData(yCbCr, width, height, hSubsampling, vSubsampling,
+ [](auto address, auto fillingData) { *address = fillingData; });
+ }
+
+ void verifyYCbCrData(const android_ycbcr& yCbCr, int32_t width, int32_t height,
+ int64_t hSubsampling, int64_t vSubsampling) {
+ traverseYCbCrData(
+ yCbCr, width, height, hSubsampling, vSubsampling,
+ [](auto address, auto expectedData) { EXPECT_EQ(*address, expectedData); });
+ }
+
+ constexpr uint64_t bitsToBytes(int64_t bits) { return bits / 8; }
+ constexpr uint64_t bytesToBits(int64_t bytes) { return bytes * 8; }
+
+ void getAndroidYCbCr(buffer_handle_t bufferHandle, uint8_t* data, android_ycbcr* outYCbCr,
+ int64_t* hSubsampling, int64_t* vSubsampling) {
+ auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(bufferHandle);
+ ASSERT_TRUE(decodeResult.has_value());
+ const auto& planeLayouts = *decodeResult;
+ ASSERT_TRUE(planeLayouts.size() > 0);
+
+ outYCbCr->y = nullptr;
+ outYCbCr->cb = nullptr;
+ outYCbCr->cr = nullptr;
+ outYCbCr->ystride = 0;
+ outYCbCr->cstride = 0;
+ outYCbCr->chroma_step = 0;
+
+ for (const auto& planeLayout : planeLayouts) {
+ for (const auto& planeLayoutComponent : planeLayout.components) {
+ if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
+ continue;
+ }
+ ASSERT_EQ(0, planeLayoutComponent.offsetInBits % 8);
+
+ uint8_t* tmpData = data + planeLayout.offsetInBytes +
+ bitsToBytes(planeLayoutComponent.offsetInBits);
+ uint64_t sampleIncrementInBytes;
+
+ auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
+ switch (type) {
+ case PlaneLayoutComponentType::Y:
+ ASSERT_EQ(nullptr, outYCbCr->y);
+ ASSERT_EQ(8, planeLayoutComponent.sizeInBits);
+ ASSERT_EQ(8, planeLayout.sampleIncrementInBits);
+ outYCbCr->y = tmpData;
+ outYCbCr->ystride = planeLayout.strideInBytes;
+ break;
+
+ case PlaneLayoutComponentType::CB:
+ case PlaneLayoutComponentType::CR:
+ ASSERT_EQ(0, planeLayout.sampleIncrementInBits % 8);
+
+ sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
+ ASSERT_TRUE(sampleIncrementInBytes == 1 || sampleIncrementInBytes == 2);
+
+ if (outYCbCr->cstride == 0 && outYCbCr->chroma_step == 0) {
+ outYCbCr->cstride = planeLayout.strideInBytes;
+ outYCbCr->chroma_step = sampleIncrementInBytes;
+ } else {
+ ASSERT_EQ(outYCbCr->cstride, planeLayout.strideInBytes);
+ ASSERT_EQ(outYCbCr->chroma_step, sampleIncrementInBytes);
+ }
+
+ if (*hSubsampling == 0 && *vSubsampling == 0) {
+ *hSubsampling = planeLayout.horizontalSubsampling;
+ *vSubsampling = planeLayout.verticalSubsampling;
+ } else {
+ ASSERT_EQ(*hSubsampling, planeLayout.horizontalSubsampling);
+ ASSERT_EQ(*vSubsampling, planeLayout.verticalSubsampling);
+ }
+
+ if (type == PlaneLayoutComponentType::CB) {
+ ASSERT_EQ(nullptr, outYCbCr->cb);
+ outYCbCr->cb = tmpData;
+ } else {
+ ASSERT_EQ(nullptr, outYCbCr->cr);
+ outYCbCr->cr = tmpData;
+ }
+ break;
+ default:
+ break;
+ };
+ }
+ }
+
+ ASSERT_NE(nullptr, outYCbCr->y);
+ ASSERT_NE(nullptr, outYCbCr->cb);
+ ASSERT_NE(nullptr, outYCbCr->cr);
+ }
+
+ YCbCr getAndroidYCbCr_P010(const native_handle_t* bufferHandle, uint8_t* data) {
+ YCbCr yCbCr_P010;
+ auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(bufferHandle);
+ if (!decodeResult.has_value()) {
+ ADD_FAILURE() << "failed to get plane layout";
+ return YCbCr{};
+ }
+ const auto& planeLayouts = *decodeResult;
+ EXPECT_EQ(2, planeLayouts.size());
+ EXPECT_EQ(1, planeLayouts[0].components.size());
+ EXPECT_EQ(2, planeLayouts[1].components.size());
+
+ yCbCr_P010.yCbCr.y = nullptr;
+ yCbCr_P010.yCbCr.cb = nullptr;
+ yCbCr_P010.yCbCr.cr = nullptr;
+ yCbCr_P010.yCbCr.ystride = 0;
+ yCbCr_P010.yCbCr.cstride = 0;
+ yCbCr_P010.yCbCr.chroma_step = 0;
+ int64_t cb_offset = 0;
+ int64_t cr_offset = 0;
+
+ for (const auto& planeLayout : planeLayouts) {
+ for (const auto& planeLayoutComponent : planeLayout.components) {
+ if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
+ continue;
+ }
+
+ uint8_t* tmpData = data + planeLayout.offsetInBytes +
+ bitsToBytes(planeLayoutComponent.offsetInBits);
+ uint64_t sampleIncrementInBytes = 0;
+ auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
+ switch (type) {
+ case PlaneLayoutComponentType::Y:
+ // For specs refer:
+ // https://docs.microsoft.com/en-us/windows/win32/medfound/10-bit-and-16-bit-yuv-video-formats
+ EXPECT_EQ(6, planeLayoutComponent.offsetInBits);
+ EXPECT_EQ(nullptr, yCbCr_P010.yCbCr.y);
+ EXPECT_EQ(10, planeLayoutComponent.sizeInBits);
+ EXPECT_EQ(16, planeLayout.sampleIncrementInBits);
+
+ yCbCr_P010.yCbCr.y = tmpData;
+ yCbCr_P010.yCbCr.ystride = planeLayout.strideInBytes;
+ break;
+
+ case PlaneLayoutComponentType::CB:
+ case PlaneLayoutComponentType::CR:
+ sampleIncrementInBytes = bitsToBytes(planeLayout.sampleIncrementInBits);
+ EXPECT_EQ(4, sampleIncrementInBytes);
+
+ if (yCbCr_P010.yCbCr.cstride == 0 && yCbCr_P010.yCbCr.chroma_step == 0) {
+ yCbCr_P010.yCbCr.cstride = planeLayout.strideInBytes;
+ yCbCr_P010.yCbCr.chroma_step = sampleIncrementInBytes;
+ } else {
+ EXPECT_EQ(yCbCr_P010.yCbCr.cstride, planeLayout.strideInBytes);
+ EXPECT_EQ(yCbCr_P010.yCbCr.chroma_step, sampleIncrementInBytes);
+ }
+
+ if (yCbCr_P010.horizontalSubSampling == 0 &&
+ yCbCr_P010.verticalSubSampling == 0) {
+ yCbCr_P010.horizontalSubSampling = planeLayout.horizontalSubsampling;
+ yCbCr_P010.verticalSubSampling = planeLayout.verticalSubsampling;
+ } else {
+ EXPECT_EQ(yCbCr_P010.horizontalSubSampling,
+ planeLayout.horizontalSubsampling);
+ EXPECT_EQ(yCbCr_P010.verticalSubSampling,
+ planeLayout.verticalSubsampling);
+ }
+
+ if (type == PlaneLayoutComponentType::CB) {
+ EXPECT_EQ(nullptr, yCbCr_P010.yCbCr.cb);
+ yCbCr_P010.yCbCr.cb = tmpData;
+ cb_offset = planeLayoutComponent.offsetInBits;
+ } else {
+ EXPECT_EQ(nullptr, yCbCr_P010.yCbCr.cr);
+ yCbCr_P010.yCbCr.cr = tmpData;
+ cr_offset = planeLayoutComponent.offsetInBits;
+ }
+ break;
+ default:
+ break;
+ };
+ }
+ }
+
+ EXPECT_EQ(cb_offset + bytesToBits(2), cr_offset);
+ EXPECT_NE(nullptr, yCbCr_P010.yCbCr.y);
+ EXPECT_NE(nullptr, yCbCr_P010.yCbCr.cb);
+ EXPECT_NE(nullptr, yCbCr_P010.yCbCr.cr);
+ return yCbCr_P010;
+ }
+};
+
+class GraphicsMapperStableCTests
+ : public GraphicsTestsBase,
+ public ::testing::TestWithParam<std::tuple<std::string, std::shared_ptr<IAllocator>>> {
+ public:
+ void SetUp() override { Initialize(std::get<1>(GetParam())); }
+
+ void TearDown() override {}
+};
+
+TEST_P(GraphicsMapperStableCTests, AllV5CallbacksDefined) {
+ ASSERT_GE(mapper()->version, AIMAPPER_VERSION_5);
+
+ EXPECT_TRUE(mapper()->v5.importBuffer);
+ EXPECT_TRUE(mapper()->v5.freeBuffer);
+ EXPECT_TRUE(mapper()->v5.getTransportSize);
+ EXPECT_TRUE(mapper()->v5.lock);
+ EXPECT_TRUE(mapper()->v5.unlock);
+ EXPECT_TRUE(mapper()->v5.flushLockedBuffer);
+ EXPECT_TRUE(mapper()->v5.rereadLockedBuffer);
+ EXPECT_TRUE(mapper()->v5.getMetadata);
+ EXPECT_TRUE(mapper()->v5.getStandardMetadata);
+ EXPECT_TRUE(mapper()->v5.setMetadata);
+ EXPECT_TRUE(mapper()->v5.setStandardMetadata);
+ EXPECT_TRUE(mapper()->v5.listSupportedMetadataTypes);
+ EXPECT_TRUE(mapper()->v5.dumpBuffer);
+ EXPECT_TRUE(mapper()->v5.getReservedRegion);
+}
+
+TEST_P(GraphicsMapperStableCTests, DualLoadIsIdentical) {
+ ASSERT_GE(mapper()->version, AIMAPPER_VERSION_5);
+ AIMapper* secondMapper;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, getIMapperLoader()(&secondMapper));
+
+ EXPECT_EQ(secondMapper->v5.importBuffer, mapper()->v5.importBuffer);
+ EXPECT_EQ(secondMapper->v5.freeBuffer, mapper()->v5.freeBuffer);
+ EXPECT_EQ(secondMapper->v5.getTransportSize, mapper()->v5.getTransportSize);
+ EXPECT_EQ(secondMapper->v5.lock, mapper()->v5.lock);
+ EXPECT_EQ(secondMapper->v5.unlock, mapper()->v5.unlock);
+ EXPECT_EQ(secondMapper->v5.flushLockedBuffer, mapper()->v5.flushLockedBuffer);
+ EXPECT_EQ(secondMapper->v5.rereadLockedBuffer, mapper()->v5.rereadLockedBuffer);
+ EXPECT_EQ(secondMapper->v5.getMetadata, mapper()->v5.getMetadata);
+ EXPECT_EQ(secondMapper->v5.getStandardMetadata, mapper()->v5.getStandardMetadata);
+ EXPECT_EQ(secondMapper->v5.setMetadata, mapper()->v5.setMetadata);
+ EXPECT_EQ(secondMapper->v5.setStandardMetadata, mapper()->v5.setStandardMetadata);
+ EXPECT_EQ(secondMapper->v5.listSupportedMetadataTypes, mapper()->v5.listSupportedMetadataTypes);
+ EXPECT_EQ(secondMapper->v5.dumpBuffer, mapper()->v5.dumpBuffer);
+ EXPECT_EQ(secondMapper->v5.getReservedRegion, mapper()->v5.getReservedRegion);
+}
+
+TEST_P(GraphicsMapperStableCTests, CanAllocate) {
+ auto buffer = allocate({
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::RGBA_8888,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ });
+ ASSERT_NE(nullptr, buffer.get());
+ EXPECT_GE(buffer->stride(), 64);
+}
+
+TEST_P(GraphicsMapperStableCTests, ImportFreeBuffer) {
+ auto buffer = allocate({
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::RGBA_8888,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ });
+ ASSERT_NE(nullptr, buffer.get());
+ EXPECT_GE(buffer->stride(), 64);
+
+ {
+ auto import1 = buffer->import();
+ auto import2 = buffer->import();
+ EXPECT_TRUE(import1);
+ EXPECT_TRUE(import2);
+ EXPECT_NE(*import1, *import2);
+ }
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer cross mapper instances.
+ */
+TEST_P(GraphicsMapperStableCTests, ImportFreeBufferSingleton) {
+ auto buffer = allocate({
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::RGBA_8888,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ });
+ ASSERT_NE(nullptr, buffer.get());
+ EXPECT_GE(buffer->stride(), 64);
+
+ buffer_handle_t bufferHandle = nullptr;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.importBuffer(buffer->rawHandle(), &bufferHandle));
+ ASSERT_NE(nullptr, bufferHandle);
+
+ AIMapper* secondMapper;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, getIMapperLoader()(&secondMapper));
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, secondMapper->v5.freeBuffer(bufferHandle));
+}
+
+/**
+ * Test IMapper::importBuffer with invalid buffers.
+ */
+TEST_P(GraphicsMapperStableCTests, ImportBufferNegative) {
+ native_handle_t* invalidHandle = nullptr;
+ buffer_handle_t bufferHandle = nullptr;
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.importBuffer(invalidHandle, &bufferHandle))
+ << "importBuffer with nullptr did not fail with BAD_BUFFER";
+
+ invalidHandle = native_handle_create(0, 0);
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.importBuffer(invalidHandle, &bufferHandle))
+ << "importBuffer with invalid handle did not fail with BAD_BUFFER";
+ native_handle_delete(invalidHandle);
+}
+
+/**
+ * Test IMapper::freeBuffer with invalid buffers.
+ */
+TEST_P(GraphicsMapperStableCTests, FreeBufferNegative) {
+ native_handle_t* bufferHandle = nullptr;
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.freeBuffer(bufferHandle))
+ << "freeBuffer with nullptr did not fail with BAD_BUFFER";
+
+ bufferHandle = native_handle_create(0, 0);
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.freeBuffer(bufferHandle))
+ << "freeBuffer with invalid handle did not fail with BAD_BUFFER";
+ native_handle_delete(bufferHandle);
+
+ auto buffer = allocateGeneric();
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.freeBuffer(buffer->rawHandle()))
+ << "freeBuffer with un-imported handle did not fail with BAD_BUFFER";
+}
+
+/**
+ * Test IMapper::lock and IMapper::unlock.
+ */
+TEST_P(GraphicsMapperStableCTests, LockUnlockBasic) {
+ constexpr auto usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN;
+ auto buffer = allocate({
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::RGBA_8888,
+ .usage = usage,
+ .reservedSize = 0,
+ });
+ ASSERT_NE(nullptr, buffer.get());
+
+ // lock buffer for writing
+ const auto& info = buffer->info();
+ const auto stride = buffer->stride();
+ const ARect region{0, 0, info.width, info.height};
+ auto handle = buffer->import();
+ uint8_t* data = nullptr;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE,
+ mapper()->v5.lock(*handle, static_cast<int64_t>(usage), region, -1, (void**)&data));
+
+ // RGBA_8888
+ fillRGBA8888(data, info.height, stride * 4, info.width * 4);
+
+ int releaseFence = -1;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+
+ // lock again for reading
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(usage), region,
+ releaseFence, (void**)&data));
+ releaseFence = -1;
+
+ ASSERT_NO_FATAL_FAILURE(verifyRGBA8888(*handle, data, info.height, stride * 4, info.width * 4));
+
+ releaseFence = -1;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+ if (releaseFence != -1) {
+ close(releaseFence);
+ }
+}
+
+/**
+ * Test multiple operations associated with different color formats
+ */
+TEST_P(GraphicsMapperStableCTests, Lock_YCRCB_420_SP) {
+ BufferDescriptorInfo info{
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::YCRCB_420_SP,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ };
+ auto buffer = allocate(info);
+ if (!buffer) {
+ ASSERT_FALSE(isSupported(info));
+ GTEST_SUCCEED() << "YCRCB_420_SP format is unsupported";
+ return;
+ }
+
+ // lock buffer for writing
+ const ARect region{0, 0, info.width, info.height};
+ auto handle = buffer->import();
+ uint8_t* data = nullptr;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+ region, -1, (void**)&data));
+
+ android_ycbcr yCbCr;
+ int64_t hSubsampling = 0;
+ int64_t vSubsampling = 0;
+ ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
+
+ constexpr uint32_t kCbCrSubSampleFactor = 2;
+ ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
+ ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);
+
+ auto cbData = static_cast<uint8_t*>(yCbCr.cb);
+ auto crData = static_cast<uint8_t*>(yCbCr.cr);
+ ASSERT_EQ(crData + 1, cbData);
+ ASSERT_EQ(2, yCbCr.chroma_step);
+
+ fillYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
+
+ int releaseFence = -1;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+
+ // lock again for reading
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+ region, releaseFence, (void**)&data));
+ releaseFence = -1;
+
+ ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
+
+ verifyYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
+
+ releaseFence = -1;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+ if (releaseFence != -1) {
+ close(releaseFence);
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, YV12SubsampleMetadata) {
+ BufferDescriptorInfo info{
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::YV12,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ };
+ auto buffer = allocate(info);
+ ASSERT_NE(nullptr, buffer.get());
+
+ // lock buffer for writing
+ const ARect region{0, 0, info.width, info.height};
+ auto handle = buffer->import();
+ uint8_t* data = nullptr;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+ region, -1, (void**)&data));
+
+ auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(*handle);
+ ASSERT_TRUE(decodeResult.has_value());
+ const auto& planeLayouts = *decodeResult;
+
+ ASSERT_EQ(3, planeLayouts.size());
+
+ auto yPlane = planeLayouts[0];
+ auto crPlane = planeLayouts[1];
+ auto cbPlane = planeLayouts[2];
+
+ constexpr uint32_t kCbCrSubSampleFactor = 2;
+ EXPECT_EQ(kCbCrSubSampleFactor, crPlane.horizontalSubsampling);
+ EXPECT_EQ(kCbCrSubSampleFactor, crPlane.verticalSubsampling);
+
+ EXPECT_EQ(kCbCrSubSampleFactor, cbPlane.horizontalSubsampling);
+ EXPECT_EQ(kCbCrSubSampleFactor, cbPlane.verticalSubsampling);
+
+ const long chromaSampleWidth = info.width / kCbCrSubSampleFactor;
+ const long chromaSampleHeight = info.height / kCbCrSubSampleFactor;
+
+ EXPECT_EQ(info.width, yPlane.widthInSamples);
+ EXPECT_EQ(info.height, yPlane.heightInSamples);
+
+ EXPECT_EQ(chromaSampleWidth, crPlane.widthInSamples);
+ EXPECT_EQ(chromaSampleHeight, crPlane.heightInSamples);
+
+ EXPECT_EQ(chromaSampleWidth, cbPlane.widthInSamples);
+ EXPECT_EQ(chromaSampleHeight, cbPlane.heightInSamples);
+
+ EXPECT_LE(crPlane.widthInSamples, crPlane.strideInBytes);
+ EXPECT_LE(cbPlane.widthInSamples, cbPlane.strideInBytes);
+
+ int releaseFence = -1;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+ if (releaseFence != -1) {
+ close(releaseFence);
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, Lock_YV12) {
+ BufferDescriptorInfo info{
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::YV12,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ };
+ auto buffer = allocate(info);
+ ASSERT_NE(nullptr, buffer.get());
+
+ // lock buffer for writing
+ const ARect region{0, 0, info.width, info.height};
+ auto handle = buffer->import();
+ uint8_t* data = nullptr;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+ region, -1, (void**)&data));
+
+ android_ycbcr yCbCr;
+ int64_t hSubsampling = 0;
+ int64_t vSubsampling = 0;
+ ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
+
+ constexpr uint32_t kCbCrSubSampleFactor = 2;
+ ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
+ ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);
+
+ auto cbData = static_cast<uint8_t*>(yCbCr.cb);
+ auto crData = static_cast<uint8_t*>(yCbCr.cr);
+ ASSERT_EQ(crData + yCbCr.cstride * info.height / vSubsampling, cbData);
+ ASSERT_EQ(1, yCbCr.chroma_step);
+
+ fillYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
+
+ int releaseFence = -1;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+
+ // lock again for reading
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+ region, releaseFence, (void**)&data));
+ releaseFence = -1;
+
+ ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
+
+ verifyYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
+
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+ if (releaseFence != -1) {
+ close(releaseFence);
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, Lock_YCBCR_420_888) {
+ BufferDescriptorInfo info{
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::YCBCR_420_888,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ };
+ auto buffer = allocate(info);
+ ASSERT_NE(nullptr, buffer.get());
+
+ // lock buffer for writing
+ const ARect region{0, 0, info.width, info.height};
+ auto handle = buffer->import();
+ uint8_t* data = nullptr;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+ region, -1, (void**)&data));
+
+ android_ycbcr yCbCr;
+ int64_t hSubsampling = 0;
+ int64_t vSubsampling = 0;
+ ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
+
+ constexpr uint32_t kCbCrSubSampleFactor = 2;
+ ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
+ ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);
+
+ fillYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
+
+ int releaseFence = -1;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+
+ // lock again for reading
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+ region, releaseFence, (void**)&data));
+ releaseFence = -1;
+
+ ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
+
+ verifyYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
+
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+ if (releaseFence != -1) {
+ close(releaseFence);
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, Lock_RAW10) {
+ BufferDescriptorInfo info{
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::RAW10,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ };
+ auto buffer = allocate(info);
+ if (!buffer) {
+ ASSERT_FALSE(isSupported(info));
+ GTEST_SUCCEED() << "RAW10 format is unsupported";
+ return;
+ }
+
+ // lock buffer for writing
+ const ARect region{0, 0, info.width, info.height};
+ auto handle = buffer->import();
+ uint8_t* data = nullptr;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+ region, -1, (void**)&data));
+
+ auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(*handle);
+ ASSERT_TRUE(decodeResult.has_value());
+ const auto& planeLayouts = *decodeResult;
+
+ ASSERT_EQ(1, planeLayouts.size());
+ auto planeLayout = planeLayouts[0];
+
+ EXPECT_EQ(0, planeLayout.sampleIncrementInBits);
+ EXPECT_EQ(1, planeLayout.horizontalSubsampling);
+ EXPECT_EQ(1, planeLayout.verticalSubsampling);
+
+ ASSERT_EQ(1, planeLayout.components.size());
+ auto planeLayoutComponent = planeLayout.components[0];
+
+ EXPECT_EQ(PlaneLayoutComponentType::RAW,
+ static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value));
+ EXPECT_EQ(0, planeLayoutComponent.offsetInBits % 8);
+ EXPECT_EQ(-1, planeLayoutComponent.sizeInBits);
+
+ int releaseFence = -1;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+ if (releaseFence != -1) {
+ close(releaseFence);
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, Lock_RAW12) {
+ BufferDescriptorInfo info{
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::RAW12,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ };
+ auto buffer = allocate(info);
+ if (!buffer) {
+ ASSERT_FALSE(isSupported(info));
+ GTEST_SUCCEED() << "RAW12 format is unsupported";
+ return;
+ }
+
+ // lock buffer for writing
+ const ARect region{0, 0, info.width, info.height};
+ auto handle = buffer->import();
+ uint8_t* data = nullptr;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+ region, -1, (void**)&data));
+
+ auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(*handle);
+ ASSERT_TRUE(decodeResult.has_value());
+ const auto& planeLayouts = *decodeResult;
+
+ ASSERT_EQ(1, planeLayouts.size());
+ auto planeLayout = planeLayouts[0];
+
+ EXPECT_EQ(0, planeLayout.sampleIncrementInBits);
+ EXPECT_EQ(1, planeLayout.horizontalSubsampling);
+ EXPECT_EQ(1, planeLayout.verticalSubsampling);
+
+ ASSERT_EQ(1, planeLayout.components.size());
+ auto planeLayoutComponent = planeLayout.components[0];
+
+ EXPECT_EQ(PlaneLayoutComponentType::RAW,
+ static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value));
+ EXPECT_EQ(0, planeLayoutComponent.offsetInBits % 8);
+ EXPECT_EQ(-1, planeLayoutComponent.sizeInBits);
+
+ int releaseFence = -1;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+ if (releaseFence != -1) {
+ close(releaseFence);
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, Lock_YCBCR_P010) {
+ BufferDescriptorInfo info{
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::YCBCR_P010,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ };
+ auto buffer = allocate(info);
+ if (!buffer) {
+ ASSERT_FALSE(isSupported(info));
+ GTEST_SUCCEED() << "YCBCR_P010 format is unsupported";
+ return;
+ }
+
+ // lock buffer for writing
+ const ARect region{0, 0, info.width, info.height};
+ auto handle = buffer->import();
+ uint8_t* data = nullptr;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+ region, -1, (void**)&data));
+
+ YCbCr yCbCr;
+ ASSERT_NO_FATAL_FAILURE(yCbCr = getAndroidYCbCr_P010(*handle, data));
+
+ constexpr uint32_t kCbCrSubSampleFactor = 2;
+ ASSERT_EQ(kCbCrSubSampleFactor, yCbCr.horizontalSubSampling);
+ ASSERT_EQ(kCbCrSubSampleFactor, yCbCr.verticalSubSampling);
+
+ ASSERT_EQ(0, info.height % 2);
+
+ // fill the data
+ fillYCbCrData(yCbCr.yCbCr, info.width, info.height, yCbCr.horizontalSubSampling,
+ yCbCr.verticalSubSampling);
+ // verify the YCbCr data
+ verifyYCbCrData(yCbCr.yCbCr, info.width, info.height, yCbCr.horizontalSubSampling,
+ yCbCr.verticalSubSampling);
+
+ int releaseFence = -1;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+ if (releaseFence != -1) {
+ close(releaseFence);
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, LockBadAccessRegion) {
+ auto buffer = allocateGeneric();
+ ASSERT_NE(nullptr, buffer);
+ const auto& info = buffer->info();
+
+ // lock buffer for writing
+ const ARect region{0, 0, info.width * 2, info.height * 2};
+ auto handle = buffer->import();
+ uint8_t* data = nullptr;
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_VALUE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+ region, -1, (void**)&data));
+}
+
+TEST_P(GraphicsMapperStableCTests, UnlockNegative) {
+ native_handle_t* invalidHandle = nullptr;
+ int releaseFence = -1;
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(invalidHandle, &releaseFence))
+ << "unlock with nullptr did not fail with BAD_BUFFER";
+
+ invalidHandle = native_handle_create(0, 0);
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(invalidHandle, &releaseFence))
+ << "unlock with invalid handle did not fail with BAD_BUFFER";
+ native_handle_delete(invalidHandle);
+
+ auto buffer = allocateGeneric();
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(buffer->rawHandle(), &releaseFence))
+ << "unlock with un-imported handle did not fail with BAD_BUFFER";
+}
+
+TEST_P(GraphicsMapperStableCTests, UnlockNotImported) {
+ int releaseFence = -1;
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(buffer->rawHandle(), &releaseFence))
+ << "unlock with un-imported handle did not fail with BAD_BUFFER";
+}
+
+TEST_P(GraphicsMapperStableCTests, UnlockNotLocked) {
+ int releaseFence = -1;
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(*bufferHandle, &releaseFence))
+ << "unlock with unlocked handle did not fail with BAD_BUFFER";
+}
+
+TEST_P(GraphicsMapperStableCTests, LockUnlockNested) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ const ARect region{0, 0, buffer->info().width, buffer->info().height};
+ auto usage = static_cast<int64_t>(buffer->info().usage);
+ auto handle = buffer->import();
+ uint8_t* data = nullptr;
+ EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, usage, region, -1, (void**)&data));
+ EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, usage, region, -1, (void**)&data))
+ << "Second lock failed";
+ int releaseFence = -1;
+ EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+ if (releaseFence != -1) {
+ close(releaseFence);
+ releaseFence = -1;
+ }
+ EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence))
+ << "Second unlock failed";
+ if (releaseFence != -1) {
+ close(releaseFence);
+ releaseFence = -1;
+ }
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(*handle, &releaseFence))
+ << "Third, unmatched, unlock should have failed with BAD_BUFFER";
+}
+
+TEST_P(GraphicsMapperStableCTests, FlushRereadBasic) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ const auto& info = buffer->info();
+ const auto stride = buffer->stride();
+ const ARect region{0, 0, buffer->info().width, buffer->info().height};
+
+ auto writeHandle = buffer->import();
+ auto readHandle = buffer->import();
+ ASSERT_TRUE(writeHandle && readHandle);
+
+ // lock buffer for writing
+
+ uint8_t* writeData;
+ EXPECT_EQ(AIMAPPER_ERROR_NONE,
+ mapper()->v5.lock(*writeHandle, static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN),
+ region, -1, (void**)&writeData));
+
+ uint8_t* readData;
+ EXPECT_EQ(AIMAPPER_ERROR_NONE,
+ mapper()->v5.lock(*readHandle, static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN),
+ region, -1, (void**)&readData));
+
+ fillRGBA8888(writeData, info.height, stride * 4, info.width * 4);
+
+ EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.flushLockedBuffer(*writeHandle));
+ EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.rereadLockedBuffer(*readHandle));
+
+ ASSERT_NO_FATAL_FAILURE(
+ verifyRGBA8888(*readHandle, readData, info.height, stride * 4, info.width * 4));
+
+ int releaseFence = -1;
+
+ EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*readHandle, &releaseFence));
+ if (releaseFence != -1) {
+ close(releaseFence);
+ releaseFence = -1;
+ }
+
+ EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*writeHandle, &releaseFence));
+ if (releaseFence != -1) {
+ close(releaseFence);
+ releaseFence = -1;
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, FlushLockedBufferBadBuffer) {
+ // Amazingly this is enough to make the compiler happy even though flushLockedBuffer
+ // is _Nonnull :shrug:
+ buffer_handle_t badBuffer = nullptr;
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.flushLockedBuffer(badBuffer));
+}
+
+TEST_P(GraphicsMapperStableCTests, RereadLockedBufferBadBuffer) {
+ buffer_handle_t badBuffer = nullptr;
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.rereadLockedBuffer(badBuffer));
+}
+
+TEST_P(GraphicsMapperStableCTests, GetBufferId) {
+ auto buffer = allocateGeneric();
+ auto bufferHandle = buffer->import();
+ auto bufferId = getStandardMetadata<StandardMetadataType::BUFFER_ID>(*bufferHandle);
+ ASSERT_TRUE(bufferId.has_value());
+
+ auto buffer2 = allocateGeneric();
+ auto bufferHandle2 = buffer2->import();
+ auto bufferId2 = getStandardMetadata<StandardMetadataType::BUFFER_ID>(*bufferHandle2);
+ ASSERT_TRUE(bufferId2.has_value());
+
+ EXPECT_NE(*bufferId, *bufferId2);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetName) {
+ auto buffer = allocate({
+ .name = {"Hello, World!"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::RGBA_8888,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ });
+ auto bufferHandle = buffer->import();
+ auto name = getStandardMetadata<StandardMetadataType::NAME>(*bufferHandle);
+ ASSERT_TRUE(name.has_value());
+ EXPECT_EQ(*name, "Hello, World!");
+}
+
+TEST_P(GraphicsMapperStableCTests, GetWidthHeight) {
+ auto buffer = allocate({
+ .name = {"Hello, World!"},
+ .width = 64,
+ .height = 128,
+ .layerCount = 1,
+ .format = PixelFormat::RGBA_8888,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ });
+ auto bufferHandle = buffer->import();
+ auto value = getStandardMetadata<StandardMetadataType::WIDTH>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(*value, 64);
+ value = getStandardMetadata<StandardMetadataType::HEIGHT>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(*value, 128);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetLayerCount) {
+ auto buffer = allocateGeneric();
+ auto bufferHandle = buffer->import();
+ auto value = getStandardMetadata<StandardMetadataType::LAYER_COUNT>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(*value, buffer->info().layerCount);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetPixelFormatRequested) {
+ auto buffer = allocateGeneric();
+ auto bufferHandle = buffer->import();
+ auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(*value, buffer->info().format);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetPixelFormatFourCC) {
+ auto buffer = allocate({
+ .name = {"Hello, World!"},
+ .width = 64,
+ .height = 128,
+ .layerCount = 1,
+ .format = PixelFormat::RGBA_8888,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ });
+ {
+ auto bufferHandle = buffer->import();
+ auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_FOURCC>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(*value, DRM_FORMAT_ABGR8888);
+ }
+
+ buffer = allocate({
+ .name = {"yv12"},
+ .width = 64,
+ .height = 128,
+ .layerCount = 1,
+ .format = PixelFormat::YV12,
+ .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+ .reservedSize = 0,
+ });
+ {
+ auto bufferHandle = buffer->import();
+ auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_FOURCC>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(*value, DRM_FORMAT_YVU420);
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, GetPixelFormatModifier) {
+ auto buffer = allocateGeneric();
+ auto bufferHandle = buffer->import();
+ auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_MODIFIER>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ // Only the upper 8-bits are defined and is just the vendor ID, the lower 56 bits are
+ // then vendor specific. So there's not anything useful to assert here beyond just that
+ // we successfully queried a value
+}
+
+TEST_P(GraphicsMapperStableCTests, GetUsage) {
+ auto buffer = allocateGeneric();
+ auto bufferHandle = buffer->import();
+ auto value = getStandardMetadata<StandardMetadataType::USAGE>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(buffer->info().usage, *value);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetAllocationSize) {
+ auto buffer = allocateGeneric();
+ auto bufferHandle = buffer->import();
+ auto value = getStandardMetadata<StandardMetadataType::ALLOCATION_SIZE>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ const auto estimatedSize = buffer->stride() * buffer->info().height * 4;
+ // This buffer has CPU usage, so we expect at least stride * height * 4 since it should be
+ // generally linear uncompressed.
+ EXPECT_GE(*value, estimatedSize)
+ << "Expected allocation size to be at least stride * height * 4bpp";
+ // Might need refining, but hopefully this a generous-enough upper-bound?
+ EXPECT_LT(*value, estimatedSize * 2)
+ << "Expected allocation size to less than double stride * height * 4bpp";
+}
+
+TEST_P(GraphicsMapperStableCTests, GetProtectedContent) {
+ const BufferDescriptorInfo info{
+ .name = {"prot8888"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::RGBA_8888,
+ .usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY,
+ .reservedSize = 0,
+ };
+ auto buffer = allocate(info);
+ if (!buffer) {
+ ASSERT_FALSE(isSupported(info))
+ << "Allocation of trivial sized buffer failed, so isSupported() must be false";
+ GTEST_SUCCEED() << "PROTECTED RGBA_8888 is unsupported";
+ return;
+ }
+ auto bufferHandle = buffer->import();
+ auto value = getStandardMetadata<StandardMetadataType::PROTECTED_CONTENT>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(*value, 1);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetCompression) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ auto value = getStandardMetadata<StandardMetadataType::COMPRESSION>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(gralloc4::Compression_None.name, value->name);
+ EXPECT_EQ(gralloc4::Compression_None.value, value->value);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetInterlaced) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ auto value = getStandardMetadata<StandardMetadataType::INTERLACED>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(gralloc4::Interlaced_None.name, value->name);
+ EXPECT_EQ(gralloc4::Interlaced_None.value, value->value);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetChromaSiting) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ auto value = getStandardMetadata<StandardMetadataType::CHROMA_SITING>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(gralloc4::ChromaSiting_None.name, value->name);
+ EXPECT_EQ(gralloc4::ChromaSiting_None.value, value->value);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetPlaneLayouts) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ auto value = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ ASSERT_NO_FATAL_FAILURE(verifyRGBA8888PlaneLayouts(*value));
+}
+
+TEST_P(GraphicsMapperStableCTests, GetCrop) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ auto value = getStandardMetadata<StandardMetadataType::CROP>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(1, value->size());
+ const Rect expected{0, 0, buffer->info().width, buffer->info().height};
+ EXPECT_EQ(expected, value->at(0));
+}
+
+TEST_P(GraphicsMapperStableCTests, GetSetDataspace) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ auto value = getStandardMetadata<StandardMetadataType::DATASPACE>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(Dataspace::UNKNOWN, *value);
+ EXPECT_EQ(AIMAPPER_ERROR_NONE, setStandardMetadata<StandardMetadataType::DATASPACE>(
+ *bufferHandle, Dataspace::DISPLAY_P3));
+ value = getStandardMetadata<StandardMetadataType::DATASPACE>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(Dataspace::DISPLAY_P3, *value);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetSetBlendMode) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ auto value = getStandardMetadata<StandardMetadataType::BLEND_MODE>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(BlendMode::INVALID, *value);
+ EXPECT_EQ(AIMAPPER_ERROR_NONE, setStandardMetadata<StandardMetadataType::BLEND_MODE>(
+ *bufferHandle, BlendMode::COVERAGE));
+ value = getStandardMetadata<StandardMetadataType::BLEND_MODE>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(BlendMode::COVERAGE, *value);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetSetSmpte2086) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ auto value = getStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_FALSE(value->has_value());
+
+ // TODO: Maybe use something resembling real values, but validation isn't supposed to happen
+ // here anyway so :shrug:
+ const Smpte2086 awesomeHdr{
+ XyColor{1.f, 1.f}, XyColor{2.f, 2.f}, XyColor{3.f, 3.f},
+ XyColor{400.f, 1000.f}, 100000.0f, 0.0001f,
+ };
+ EXPECT_EQ(AIMAPPER_ERROR_NONE,
+ setStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle, awesomeHdr));
+ value = getStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ ASSERT_TRUE(value->has_value());
+ EXPECT_EQ(awesomeHdr, *value);
+
+ EXPECT_EQ(AIMAPPER_ERROR_NONE,
+ setStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle, std::nullopt));
+ value = getStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_FALSE(value->has_value());
+}
+
+TEST_P(GraphicsMapperStableCTests, GetCta861_3) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ auto value = getStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_FALSE(value->has_value());
+
+ const Cta861_3 genericHlgish{1000.f, 140.f};
+ EXPECT_EQ(AIMAPPER_ERROR_NONE,
+ setStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle, genericHlgish));
+ value = getStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ ASSERT_TRUE(value->has_value());
+ EXPECT_EQ(genericHlgish, *value);
+
+ EXPECT_EQ(AIMAPPER_ERROR_NONE,
+ setStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle, std::nullopt));
+ value = getStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_FALSE(value->has_value());
+}
+
+TEST_P(GraphicsMapperStableCTests, GetSmpte2094_10) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_10>(*bufferHandle);
+ if (value.has_value()) {
+ EXPECT_FALSE(value->has_value());
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, GetSmpte2094_40) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_40>(*bufferHandle);
+ if (value.has_value()) {
+ EXPECT_FALSE(value->has_value());
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, SupportsRequiredGettersSetters) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ const AIMapper_MetadataTypeDescription* descriptions = nullptr;
+ size_t descriptionCount = 0;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE,
+ mapper()->v5.listSupportedMetadataTypes(&descriptions, &descriptionCount));
+ std::vector<StandardMetadataType> requiredGetters = {
+ StandardMetadataType::BUFFER_ID,
+ StandardMetadataType::NAME,
+ StandardMetadataType::WIDTH,
+ StandardMetadataType::HEIGHT,
+ StandardMetadataType::LAYER_COUNT,
+ StandardMetadataType::PIXEL_FORMAT_REQUESTED,
+ StandardMetadataType::PIXEL_FORMAT_FOURCC,
+ StandardMetadataType::PIXEL_FORMAT_MODIFIER,
+ StandardMetadataType::USAGE,
+ StandardMetadataType::ALLOCATION_SIZE,
+ StandardMetadataType::PROTECTED_CONTENT,
+ StandardMetadataType::COMPRESSION,
+ StandardMetadataType::INTERLACED,
+ StandardMetadataType::CHROMA_SITING,
+ StandardMetadataType::PLANE_LAYOUTS,
+ StandardMetadataType::CROP,
+ StandardMetadataType::DATASPACE,
+ StandardMetadataType::BLEND_MODE,
+ StandardMetadataType::SMPTE2086,
+ StandardMetadataType::CTA861_3,
+ };
+
+ std::vector<StandardMetadataType> requiredSetters = {
+ StandardMetadataType::DATASPACE,
+ StandardMetadataType::BLEND_MODE,
+ StandardMetadataType::SMPTE2086,
+ StandardMetadataType::CTA861_3,
+ };
+
+ for (int i = 0; i < descriptionCount; i++) {
+ const auto& it = descriptions[i];
+ if (isStandardMetadata(it.metadataType)) {
+ EXPECT_GT(it.metadataType.value, static_cast<int64_t>(StandardMetadataType::INVALID));
+ EXPECT_LT(it.metadataType.value,
+ ndk::internal::enum_values<StandardMetadataType>.size());
+
+ if (it.isGettable) {
+ std::erase(requiredGetters,
+ static_cast<StandardMetadataType>(it.metadataType.value));
+ }
+ if (it.isSettable) {
+ std::erase(requiredSetters,
+ static_cast<StandardMetadataType>(it.metadataType.value));
+ }
+ } else {
+ EXPECT_NE(nullptr, it.description) << "Non-standard metadata must have a description";
+ int len = strlen(it.description);
+ EXPECT_GE(len, 0) << "Non-standard metadata must have a description";
+ }
+ }
+
+ EXPECT_EQ(0, requiredGetters.size()) << "Missing required getters" << toString(requiredGetters);
+ EXPECT_EQ(0, requiredSetters.size()) << "Missing required setters" << toString(requiredSetters);
+}
+
+/*
+ * Test that verifies that if the optional StandardMetadataTypes have getters, they have
+ * the required setters as well
+ */
+TEST_P(GraphicsMapperStableCTests, CheckRequiredSettersIfHasGetters) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ const AIMapper_MetadataTypeDescription* descriptions = nullptr;
+ size_t descriptionCount = 0;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE,
+ mapper()->v5.listSupportedMetadataTypes(&descriptions, &descriptionCount));
+
+ for (int i = 0; i < descriptionCount; i++) {
+ const auto& it = descriptions[i];
+ if (isStandardMetadata(it.metadataType)) {
+ const auto type = static_cast<StandardMetadataType>(it.metadataType.value);
+ switch (type) {
+ case StandardMetadataType::SMPTE2094_10:
+ case StandardMetadataType::SMPTE2094_40:
+ if (it.isGettable) {
+ EXPECT_TRUE(it.isSettable)
+ << "Type " << toString(type) << " must be settable if gettable";
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, ListSupportedWorks) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+ const AIMapper_MetadataTypeDescription* descriptions = nullptr;
+ size_t descriptionCount = 0;
+ ASSERT_EQ(AIMAPPER_ERROR_NONE,
+ mapper()->v5.listSupportedMetadataTypes(&descriptions, &descriptionCount));
+
+ std::vector<uint8_t> metadataBuffer;
+ auto get = [&](AIMapper_MetadataType metadataType) -> int32_t {
+ int32_t size = mapper()->v5.getMetadata(*bufferHandle, metadataType, nullptr, 0);
+ if (size >= 0) {
+ metadataBuffer.resize(size);
+ size = mapper()->v5.getMetadata(*bufferHandle, metadataType, metadataBuffer.data(),
+ metadataBuffer.size());
+ EXPECT_EQ(size, metadataBuffer.size());
+ }
+ return size;
+ };
+
+ for (int i = 0; i < descriptionCount; i++) {
+ const auto& it = descriptions[i];
+ if (!isStandardMetadata(it.metadataType)) {
+ continue;
+ }
+ if (!it.isGettable) {
+ EXPECT_FALSE(it.isSettable)
+ << "StandardMetadata that isn't gettable must not be settable";
+ continue;
+ }
+ EXPECT_GE(get(it.metadataType), 0)
+ << "Get failed for claimed supported getter of "
+ << toString(static_cast<StandardMetadataType>(it.metadataType.value));
+ if (it.isSettable) {
+ EXPECT_EQ(AIMAPPER_ERROR_NONE,
+ mapper()->v5.setMetadata(*bufferHandle, it.metadataType,
+ metadataBuffer.data(), metadataBuffer.size()))
+ << "Failed to set metadata for "
+ << toString(static_cast<StandardMetadataType>(it.metadataType.value));
+ }
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, GetMetadataBadValue) {
+ auto get = [this](StandardMetadataType type) -> AIMapper_Error {
+ // This is a _Nonnull parameter, but this is enough obfuscation to fool the linter
+ buffer_handle_t buffer = nullptr;
+ int32_t ret =
+ mapper()->v5.getStandardMetadata(buffer, static_cast<int64_t>(type), nullptr, 0);
+ return (ret < 0) ? (AIMapper_Error)-ret : AIMAPPER_ERROR_NONE;
+ };
+
+ for (auto type : ndk::enum_range<StandardMetadataType>()) {
+ if (type == StandardMetadataType::INVALID) {
+ continue;
+ }
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, get(type)) << "Wrong error for " << toString(type);
+ }
+}
+
+TEST_P(GraphicsMapperStableCTests, GetUnsupportedMetadata) {
+ auto buffer = allocateGeneric();
+ ASSERT_TRUE(buffer);
+ auto bufferHandle = buffer->import();
+ ASSERT_TRUE(bufferHandle);
+
+ int result = mapper()->v5.getMetadata(*bufferHandle, {"Fake", 1}, nullptr, 0);
+ EXPECT_EQ(AIMAPPER_ERROR_UNSUPPORTED, -result);
+
+ result = mapper()->v5.getStandardMetadata(
+ *bufferHandle, static_cast<int64_t>(StandardMetadataType::INVALID), nullptr, 0);
+ EXPECT_EQ(AIMAPPER_ERROR_UNSUPPORTED, -result);
+
+ constexpr int64_t unknownStandardType = ndk::internal::enum_values<StandardMetadataType>.size();
+ result = mapper()->v5.getStandardMetadata(*bufferHandle, unknownStandardType, nullptr, 0);
+ EXPECT_EQ(AIMAPPER_ERROR_UNSUPPORTED, -result);
+}
+
+std::vector<std::tuple<std::string, std::shared_ptr<IAllocator>>> getIAllocatorsAtLeastVersion(
+ int32_t minVersion) {
+ auto instanceNames = getAidlHalInstanceNames(IAllocator::descriptor);
+ std::vector<std::tuple<std::string, std::shared_ptr<IAllocator>>> filteredInstances;
+ filteredInstances.reserve(instanceNames.size());
+ for (const auto& name : instanceNames) {
+ auto allocator =
+ IAllocator::fromBinder(ndk::SpAIBinder(AServiceManager_checkService(name.c_str())));
+ int32_t version = 0;
+ if (allocator->getInterfaceVersion(&version).isOk()) {
+ if (version >= minVersion) {
+ filteredInstances.emplace_back(name, std::move(allocator));
+ }
+ }
+ }
+ return filteredInstances;
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsMapperStableCTests);
+INSTANTIATE_TEST_CASE_P(PerInstance, GraphicsMapperStableCTests,
+ testing::ValuesIn(getIAllocatorsAtLeastVersion(2)),
+ [](auto info) -> std::string {
+ std::string name =
+ std::to_string(info.index) + "/" + std::get<0>(info.param);
+ return Sanitize(name);
+ });
\ No newline at end of file
diff --git a/identity/aidl/default/EicOpsImpl.cc b/identity/aidl/default/EicOpsImpl.cc
index b6d324f..803df64 100644
--- a/identity/aidl/default/EicOpsImpl.cc
+++ b/identity/aidl/default/EicOpsImpl.cc
@@ -489,7 +489,7 @@
}
bool eicOpsEcdh(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
- const uint8_t privateKey[EIC_P256_PUB_KEY_SIZE],
+ const uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
uint8_t sharedSecret[EIC_P256_COORDINATE_SIZE]) {
vector<uint8_t> pubKeyVec(EIC_P256_PUB_KEY_SIZE + 1);
pubKeyVec[0] = 0x04;
diff --git a/media/c2/aidl/Android.bp b/media/c2/aidl/Android.bp
new file mode 100644
index 0000000..10867c0
--- /dev/null
+++ b/media/c2/aidl/Android.bp
@@ -0,0 +1,29 @@
+// This is the expected build file, but it may not be right in all cases
+
+aidl_interface {
+ name: "android.hardware.media.c2",
+ vendor_available: true,
+ srcs: ["android/hardware/media/c2/*.aidl"],
+ include_dirs: [
+ "frameworks/native/aidl/gui",
+ ],
+ imports: [
+ "android.hardware.common-V2",
+ "android.hardware.media.bufferpool2-V1",
+ ],
+ stability: "vintf",
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ enabled: false,
+ },
+ ndk: {
+ enabled: true,
+ additional_shared_libraries: [
+ "libnativewindow",
+ ],
+ },
+ },
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/BaseBlock.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/BaseBlock.aidl
new file mode 100644
index 0000000..460ff97
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/BaseBlock.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+union BaseBlock {
+ android.hardware.common.NativeHandle nativeBlock;
+ android.hardware.media.bufferpool2.BufferStatusMessage pooledBlock;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Block.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Block.aidl
new file mode 100644
index 0000000..7b3005e
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Block.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable Block {
+ int index;
+ android.hardware.media.c2.Params meta;
+ android.hardware.common.NativeHandle fence;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Buffer.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Buffer.aidl
new file mode 100644
index 0000000..b632932
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Buffer.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable Buffer {
+ android.hardware.media.c2.Params info;
+ android.hardware.media.c2.Block[] blocks;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl
new file mode 100644
index 0000000..d0e4cbf
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable FieldDescriptor {
+ android.hardware.media.c2.FieldId fieldId;
+ android.hardware.media.c2.FieldDescriptor.Type type;
+ int structIndex;
+ int extent;
+ String name;
+ android.hardware.media.c2.FieldDescriptor.NamedValue[] namedValues;
+ @Backing(type="int") @VintfStability
+ enum Type {
+ NO_INIT = 0,
+ INT32 = 1,
+ UINT32 = 2,
+ CNTR32 = 3,
+ INT64 = 4,
+ UINT64 = 5,
+ CNTR64 = 6,
+ FLOAT = 7,
+ STRING = 256,
+ BLOB = 257,
+ STRUCT = 131072,
+ }
+ @VintfStability
+ parcelable NamedValue {
+ String name;
+ long value;
+ }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldId.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldId.aidl
new file mode 100644
index 0000000..935b85d
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldId.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable FieldId {
+ int offset;
+ int sizeBytes;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValues.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValues.aidl
new file mode 100644
index 0000000..69060be
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValues.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+union FieldSupportedValues {
+ boolean empty;
+ android.hardware.media.c2.ValueRange range;
+ long[] values;
+ long[] flags;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
new file mode 100644
index 0000000..22f7c84
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable FieldSupportedValuesQuery {
+ android.hardware.media.c2.ParamField field;
+ android.hardware.media.c2.FieldSupportedValuesQuery.Type type;
+ @Backing(type="int") @VintfStability
+ enum Type {
+ POSSIBLE = 0,
+ CURRENT = 1,
+ }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl
new file mode 100644
index 0000000..187e3eb
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable FieldSupportedValuesQueryResult {
+ android.hardware.media.c2.Status status;
+ android.hardware.media.c2.FieldSupportedValues values;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl
new file mode 100644
index 0000000..e73b05e
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable FrameData {
+ int flags;
+ android.hardware.media.c2.WorkOrdinal ordinal;
+ android.hardware.media.c2.Buffer[] buffers;
+ android.hardware.media.c2.Params configUpdate;
+ android.hardware.media.c2.InfoBuffer[] infoBuffers;
+ const int DROP_FRAME = 1;
+ const int END_OF_STREAM = 2;
+ const int DISCARD_FRAME = 4;
+ const int FLAG_INCOMPLETE = 8;
+ const int CODEC_CONFIG = -2147483648;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
new file mode 100644
index 0000000..7ed09af
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+interface IComponent {
+ android.hardware.common.NativeHandle configureVideoTunnel(in int avSyncHwId);
+ android.hardware.media.c2.IComponent.BlockPool createBlockPool(in int allocatorId);
+ void destroyBlockPool(in long blockPoolId);
+ void drain(in boolean withEos);
+ android.hardware.media.c2.WorkBundle flush();
+ android.hardware.media.c2.IComponentInterface getInterface();
+ void queue(in android.hardware.media.c2.WorkBundle workBundle);
+ void release();
+ void reset();
+ void setOutputSurface(in long blockPoolId, in android.view.Surface surface, in android.hardware.media.c2.SurfaceSyncObj syncObject);
+ void start();
+ void stop();
+ parcelable BlockPool {
+ long blockPoolId;
+ android.hardware.media.c2.IConfigurable configurable;
+ }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentInterface.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentInterface.aidl
new file mode 100644
index 0000000..2350dae
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentInterface.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+interface IComponentInterface {
+ android.hardware.media.c2.IConfigurable getConfigurable();
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentListener.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentListener.aidl
new file mode 100644
index 0000000..f6f2a63
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentListener.aidl
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+interface IComponentListener {
+ oneway void onError(in android.hardware.media.c2.Status status, in int errorCode);
+ oneway void onFramesRendered(in android.hardware.media.c2.IComponentListener.RenderedFrame[] renderedFrames);
+ oneway void onInputBuffersReleased(in android.hardware.media.c2.IComponentListener.InputBuffer[] inputBuffers);
+ oneway void onTripped(in android.hardware.media.c2.SettingResult[] settingResults);
+ oneway void onWorkDone(in android.hardware.media.c2.WorkBundle workBundle);
+ @VintfStability
+ parcelable InputBuffer {
+ long frameIndex;
+ int arrayIndex;
+ }
+ @VintfStability
+ parcelable RenderedFrame {
+ long bufferQueueId;
+ int slotId;
+ long timestampNs;
+ }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl
new file mode 100644
index 0000000..35532be
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+interface IComponentStore {
+ void copyBuffer(in android.hardware.media.c2.Buffer src, in android.hardware.media.c2.Buffer dst);
+ android.hardware.media.c2.IComponent createComponent(in String name, in android.hardware.media.c2.IComponentListener listener, in android.hardware.media.bufferpool2.IClientManager pool);
+ android.hardware.media.c2.IComponentInterface createInterface(in String name);
+ android.hardware.media.c2.IConfigurable getConfigurable();
+ android.hardware.media.bufferpool2.IClientManager getPoolClientManager();
+ android.hardware.media.c2.StructDescriptor[] getStructDescriptors(in int[] indices);
+ android.hardware.media.c2.IComponentStore.ComponentTraits[] listComponents();
+ @VintfStability
+ parcelable ComponentTraits {
+ String name;
+ android.hardware.media.c2.IComponentStore.ComponentTraits.Domain domain;
+ android.hardware.media.c2.IComponentStore.ComponentTraits.Kind kind;
+ int rank;
+ String mediaType;
+ String[] aliases;
+ @Backing(type="int") @VintfStability
+ enum Kind {
+ OTHER = 0,
+ DECODER = 1,
+ ENCODER = 2,
+ }
+ @Backing(type="int") @VintfStability
+ enum Domain {
+ OTHER = 0,
+ VIDEO = 1,
+ AUDIO = 2,
+ IMAGE = 3,
+ }
+ }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl
new file mode 100644
index 0000000..32f5abd
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+interface IConfigurable {
+ android.hardware.media.c2.IConfigurable.ConfigResult config(in android.hardware.media.c2.Params inParams, in boolean mayBlock);
+ int getId();
+ String getName();
+ android.hardware.media.c2.Params query(in int[] indices, in boolean mayBlock);
+ android.hardware.media.c2.ParamDescriptor[] querySupportedParams(in int start, in int count);
+ android.hardware.media.c2.FieldSupportedValuesQueryResult[] querySupportedValues(in android.hardware.media.c2.FieldSupportedValuesQuery[] inFields, in boolean mayBlock);
+ @VintfStability
+ parcelable ConfigResult {
+ android.hardware.media.c2.Params params;
+ android.hardware.media.c2.SettingResult[] failures;
+ }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/InfoBuffer.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/InfoBuffer.aidl
new file mode 100644
index 0000000..94cd77d
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/InfoBuffer.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable InfoBuffer {
+ int index;
+ android.hardware.media.c2.Buffer buffer;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl
new file mode 100644
index 0000000..04c869c
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable ParamDescriptor {
+ int index;
+ int attrib;
+ String name;
+ int[] dependencies;
+ const int ATTRIBUTE_REQUIRED = 1;
+ const int ATTRIBUTE_PERSISTENT = 2;
+ const int ATTRIBUTE_STRICT = 4;
+ const int ATTRIBUTE_READ_ONLY = 8;
+ const int ATTRIBUTE_HIDDEN = 16;
+ const int ATTRIBUTE_INTERNAL = 32;
+ const int ATTRIBUTE_CONST = 64;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamField.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamField.aidl
new file mode 100644
index 0000000..13d2522
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamField.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable ParamField {
+ int index;
+ android.hardware.media.c2.FieldId fieldId;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamFieldValues.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamFieldValues.aidl
new file mode 100644
index 0000000..5a2821c
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamFieldValues.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable ParamFieldValues {
+ android.hardware.media.c2.ParamField paramOrField;
+ android.hardware.media.c2.FieldSupportedValues[] values;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Params.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Params.aidl
new file mode 100644
index 0000000..7d363c0
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Params.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable Params {
+ byte[] params;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl
new file mode 100644
index 0000000..f9e6a93
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable SettingResult {
+ android.hardware.media.c2.SettingResult.Failure failure;
+ android.hardware.media.c2.ParamFieldValues field;
+ android.hardware.media.c2.ParamFieldValues[] conflicts;
+ @Backing(type="int") @VintfStability
+ enum Failure {
+ BAD_TYPE = 0,
+ BAD_PORT = 1,
+ BAD_INDEX = 2,
+ READ_ONLY = 3,
+ MISMATCH = 4,
+ BAD_VALUE = 5,
+ CONFLICT = 6,
+ UNSUPPORTED = 7,
+ INFO_BAD_VALUE = 8,
+ INFO_CONFLICT = 9,
+ }
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl
new file mode 100644
index 0000000..ad07677
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable Status {
+ int status;
+ const int OK = 0;
+ const int BAD_VALUE = -22;
+ const int BAD_INDEX = -75;
+ const int CANNOT_DO = -2147483646;
+ const int DUPLICATE = -17;
+ const int NOT_FOUND = -2;
+ const int BAD_STATE = -38;
+ const int BLOCKING = -9930;
+ const int NO_MEMORY = -12;
+ const int REFUSED = -1;
+ const int TIMED_OUT = -110;
+ const int OMITTED = -74;
+ const int CORRUPTED = -2147483648;
+ const int NO_INIT = -19;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/StructDescriptor.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/StructDescriptor.aidl
new file mode 100644
index 0000000..58268e0
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/StructDescriptor.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable StructDescriptor {
+ int type;
+ android.hardware.media.c2.FieldDescriptor[] fields;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
new file mode 100644
index 0000000..1c9bf8d
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable SurfaceSyncObj {
+ android.hardware.common.NativeHandle syncMemory;
+ long bqId;
+ int generationId;
+ long consumerUsage;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ValueRange.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ValueRange.aidl
new file mode 100644
index 0000000..db71ce0
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ValueRange.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable ValueRange {
+ long min;
+ long max;
+ long step;
+ long num;
+ long denom;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Work.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Work.aidl
new file mode 100644
index 0000000..a534348
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Work.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable Work {
+ byte[] chainInfo;
+ android.hardware.media.c2.FrameData input;
+ android.hardware.media.c2.Worklet[] worklets;
+ int workletsProcessed;
+ android.hardware.media.c2.Status result;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/WorkBundle.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/WorkBundle.aidl
new file mode 100644
index 0000000..84708a8
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/WorkBundle.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable WorkBundle {
+ android.hardware.media.c2.Work[] works;
+ android.hardware.media.c2.BaseBlock[] baseBlocks;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/WorkOrdinal.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/WorkOrdinal.aidl
new file mode 100644
index 0000000..2833df3
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/WorkOrdinal.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable WorkOrdinal {
+ long timestampUs;
+ long frameIndex;
+ long customOrdinal;
+}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Worklet.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Worklet.aidl
new file mode 100644
index 0000000..a79abf2
--- /dev/null
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Worklet.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.media.c2;
+@VintfStability
+parcelable Worklet {
+ int componentId;
+ byte[] tunings;
+ android.hardware.media.c2.SettingResult[] failures;
+ android.hardware.media.c2.FrameData output;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/BaseBlock.aidl b/media/c2/aidl/android/hardware/media/c2/BaseBlock.aidl
new file mode 100644
index 0000000..8b8b8e0
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/BaseBlock.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.common.NativeHandle;
+
+/**
+ * Storage type for `BaseBlock`.
+ *
+ * A `BaseBlock` is a representation of a codec memory block. Coded data,
+ * decoded data, codec-specific data, and other codec-related data are all sent
+ * in the form of BaseBlocks.
+ */
+@VintfStability
+union BaseBlock {
+ /**
+ * #nativeBlock is the opaque representation of a buffer.
+ */
+ NativeHandle nativeBlock;
+ /**
+ * #pooledBlock is a reference to a buffer handled by a BufferPool.
+ */
+ android.hardware.media.bufferpool2.BufferStatusMessage pooledBlock;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/Block.aidl b/media/c2/aidl/android/hardware/media/c2/Block.aidl
new file mode 100644
index 0000000..34aa7b1
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/Block.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.common.NativeHandle;
+import android.hardware.media.c2.Params;
+
+/**
+ * Reference to a @ref BaseBlock within a @ref WorkBundle.
+ *
+ * `Block` contains additional attributes that `BaseBlock` does not. These
+ * attributes may differ among `Block` objects that refer to the same
+ * `BaseBlock` in the same `WorkBundle`.
+ */
+@VintfStability
+parcelable Block {
+ /**
+ * Identity of a `BaseBlock` within a `WorkBundle`. This is an index into
+ * #WorkBundle.baseBlocks.
+ */
+ int index;
+ /**
+ * Metadata associated with this `Block`.
+ */
+ Params meta;
+ /**
+ * Fence for synchronizing `Block` access.
+ */
+ NativeHandle fence;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/Buffer.aidl b/media/c2/aidl/android/hardware/media/c2/Buffer.aidl
new file mode 100644
index 0000000..d2dcf2d
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/Buffer.aidl
@@ -0,0 +1,37 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.Block;
+import android.hardware.media.c2.Params;
+
+/**
+ * A codec buffer, which is a collection of @ref Block objects and metadata.
+ *
+ * This is a part of @ref FrameData.
+ */
+@VintfStability
+parcelable Buffer {
+ /**
+ * Metadata associated with the buffer.
+ */
+ Params info;
+ /**
+ * Blocks contained in the buffer.
+ */
+ Block[] blocks;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/FieldDescriptor.aidl b/media/c2/aidl/android/hardware/media/c2/FieldDescriptor.aidl
new file mode 100644
index 0000000..a2774ec
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/FieldDescriptor.aidl
@@ -0,0 +1,103 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldId;
+
+/**
+ * Description of a field inside a C2Param structure.
+ */
+@VintfStability
+parcelable FieldDescriptor {
+ /**
+ * Possible types of the field.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum Type {
+ NO_INIT = 0,
+ INT32,
+ UINT32,
+ CNTR32,
+ INT64,
+ UINT64,
+ CNTR64,
+ FLOAT,
+ /**
+ * Fixed-size string (POD).
+ */
+ STRING = 0x100,
+ /**
+ * A blob has no sub-elements and can be thought of as an array of
+ * bytes. However, bytes cannot be individually addressed by clients.
+ */
+ BLOB,
+ /**
+ * The field is a structure that may contain other fields.
+ */
+ STRUCT = 0x20000,
+ }
+ /**
+ * Named value type. This is used for defining an enum value for a numeric
+ * type.
+ */
+ @VintfStability
+ parcelable NamedValue {
+ /**
+ * Name of the enum value. This must be unique for each enum value in
+ * the same field.
+ */
+ String name;
+ /**
+ * Underlying value of the enum value. Multiple enum names may have the
+ * same underlying value.
+ */
+ long value;
+ }
+ /**
+ * Location of the field in the C2Param structure
+ */
+ FieldId fieldId;
+ /**
+ * Type of the field.
+ */
+ Type type;
+ /**
+ * If #type is #Type.STRUCT, #structIndex is the C2Param structure index;
+ * otherwise, #structIndex is not used.
+ */
+ int structIndex;
+ /**
+ * Extent of the field.
+ * - For a non-array field, #extent is 1.
+ * - For a fixed-length array field, #extent is the length. An array field
+ * of length 1 is indistinguishable from a non-array field.
+ * - For a variable-length array field, #extent is 0. This can only occur as
+ * the last member of a C2Param structure.
+ */
+ int extent;
+ /**
+ * Name of the field. This must be unique for each field in the same
+ * structure.
+ */
+ String name;
+ /**
+ * List of enum values. This is not used when #type is not one of the
+ * numeric types.
+ */
+ NamedValue[] namedValues;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/FieldId.aidl b/media/c2/aidl/android/hardware/media/c2/FieldId.aidl
new file mode 100644
index 0000000..68bf058
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/FieldId.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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 android.hardware.media.c2;
+
+/**
+ * Identifying information of a field relative to a known C2Param structure.
+ *
+ * Within a given C2Param structure, each field is uniquely identified by @ref
+ * FieldId.
+ */
+@VintfStability
+parcelable FieldId {
+ /**
+ * Offset of the field in bytes.
+ */
+ int offset;
+ /**
+ * Size of the field in bytes.
+ */
+ int sizeBytes;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/FieldSupportedValues.aidl b/media/c2/aidl/android/hardware/media/c2/FieldSupportedValues.aidl
new file mode 100644
index 0000000..6c2033b
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/FieldSupportedValues.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.ValueRange;
+
+/*
+ * Description of supported values for a field of C2Param.
+ *
+ * This can be a continuous range or a discrete set of values.
+ *
+ * The intended type of values must be made clear in the context where
+ * `FieldSupportedValues` is used.
+ */
+@VintfStability
+union FieldSupportedValues {
+ /**
+ * No supported values
+ */
+ boolean empty;
+ /**
+ * Numeric range, described in a #ValueRange structure
+ */
+ ValueRange range;
+ /**
+ * List of values
+ */
+ long[] values;
+ /**
+ * List of flags that can be OR-ed.
+ *
+ * The list contains { min-mask, flag1, flag2... }. Basically, the first
+ * value is the required set of flags to be set, and the rest of the values are flags that can
+ * be set independently. FLAGS is only supported for integral types. Supported flags should
+ * not overlap, as it can make validation non-deterministic. The standard validation method
+ * is that starting from the original value, if each flag is removed when fully present (the
+ * min-mask must be fully present), we shall arrive at 0.
+ */
+ long[] flags;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQuery.aidl b/media/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
new file mode 100644
index 0000000..bdaaef6
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.ParamField;
+
+/**
+ * Query information for supported values of a field. This is used as input to
+ * IConfigurable::querySupportedValues().
+ */
+@VintfStability
+parcelable FieldSupportedValuesQuery {
+ @VintfStability
+ @Backing(type="int")
+ enum Type {
+ /**
+ * Query all possible values regardless of other settings.
+ */
+ POSSIBLE = 0,
+ /**
+ * Query currently possible values given dependent settings.
+ */
+ CURRENT,
+ }
+ /**
+ * Identity of the field to query.
+ */
+ ParamField field;
+ /**
+ * Type of the query. See #Type for more information.
+ */
+ Type type;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl b/media/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl
new file mode 100644
index 0000000..b5c28c6
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldSupportedValues;
+import android.hardware.media.c2.Status;
+
+/**
+ * This structure is used to hold the result from
+ * IConfigurable::querySupportedValues().
+ */
+@VintfStability
+parcelable FieldSupportedValuesQueryResult {
+ /**
+ * Result of the query. Possible values are
+ * - `Status::OK`: The query was successful.
+ * - `Status::BAD_STATE`: The query was requested when the `IConfigurable` instance
+ * was in a bad state.
+ * - `Status::BAD_INDEX`: The requested field was not recognized.
+ * - `Status::TIMED_OUT`: The query could not be completed in a timely manner.
+ * - `Status::BLOCKING`: The query must block, but the parameter `mayBlock` in the
+ * call to `querySupportedValues()` was `false`.
+ * - `Status::CORRUPTED`: Some unknown error occurred.
+ */
+ Status status;
+ /**
+ * Supported values. This is meaningful only when #status is `OK`.
+ */
+ FieldSupportedValues values;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/FrameData.aidl b/media/c2/aidl/android/hardware/media/c2/FrameData.aidl
new file mode 100644
index 0000000..15c1b6d
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/FrameData.aidl
@@ -0,0 +1,97 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.Buffer;
+import android.hardware.media.c2.InfoBuffer;
+import android.hardware.media.c2.Params;
+import android.hardware.media.c2.WorkOrdinal;
+
+/**
+ * Data for an input frame or an output frame.
+ *
+ * This structure represents a @e frame with its metadata. A @e frame consists
+ * of an ordered set of buffers, configuration changes, and info buffers along
+ * with some non-configuration metadata.
+ *
+ * @note `FrameData` is the HIDL counterpart of `C2FrameData` in the Codec 2.0
+ * standard.
+ */
+@VintfStability
+parcelable FrameData {
+ /** List of frame flags */
+ /**
+ * For input frames: no output frame shall be generated when processing
+ * this frame, but metadata must still be processed.
+ *
+ * For output frames: this frame must be discarded but metadata is still
+ * valid.
+ */
+ const int DROP_FRAME = (1 << 0);
+ /**
+ * This frame is the last frame of the current stream. Further frames
+ * are part of a new stream.
+ */
+ const int END_OF_STREAM = (1 << 1);
+ /**
+ * This frame must be discarded with its metadata.
+ *
+ * This flag is only set by components, e.g. as a response to the flush
+ * command.
+ */
+ const int DISCARD_FRAME = (1 << 2);
+ /**
+ * This frame is not the last frame produced for the input.
+ *
+ * This flag is normally set by the component - e.g. when an input frame
+ * results in multiple output frames, this flag is set on all but the
+ * last output frame.
+ *
+ * Also, when components are chained, this flag should be propagated
+ * down the work chain. That is, if set on an earlier frame of a
+ * work-chain, it should be propagated to all later frames in that
+ * chain. Additionally, components down the chain could set this flag
+ * even if not set earlier, e.g. if multiple output frames are generated
+ * at that component for the input frame.
+ */
+ const int FLAG_INCOMPLETE = (1 << 3);
+ /**
+ * This frame contains only codec-specific configuration data, and no
+ * actual access unit.
+ */
+ const int CODEC_CONFIG = (1 << 31);
+ /**
+ * Frame flags, as described above.
+ */
+ int flags;
+ /**
+ * @ref WorkOrdinal of the frame.
+ */
+ WorkOrdinal ordinal;
+ /**
+ * List of frame buffers.
+ */
+ Buffer[] buffers;
+ /**
+ * List of configuration updates.
+ */
+ Params configUpdate;
+ /**
+ * List of info buffers.
+ */
+ InfoBuffer[] infoBuffers;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/IComponent.aidl b/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
new file mode 100644
index 0000000..b3390c3
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
@@ -0,0 +1,304 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.common.NativeHandle;
+import android.view.Surface;
+
+import android.hardware.media.c2.IComponentInterface;
+import android.hardware.media.c2.IConfigurable;
+import android.hardware.media.c2.WorkBundle;
+import android.hardware.media.c2.SurfaceSyncObj;
+
+/**
+ * Interface for an AIDL Codec2 component.
+ * Components have two states: stopped and running. The running state has three
+ * sub-states: executing, tripped and error.
+ *
+ * All methods in `IComponent` must not block. If a method call cannot be
+ * completed in a timely manner, it must throw `Status::TIMED_OUT`.
+ */
+@VintfStability
+interface IComponent {
+ /**
+ * The reference object from framwork to HAL C2BlockPool.
+ *
+ * The object will be returned when C2BlockPool is created by a framework
+ * request. The object also can be destroyed using blockPoolId.
+ * Using configurable framework can query/config the object in HAL(IComponent).
+ */
+ parcelable BlockPool {
+ long blockPoolId;
+ IConfigurable configurable;
+ }
+ /**
+ * Configures a component for a tunneled playback mode.
+ *
+ * A successful call to this method puts the component in the *tunneled*
+ * mode. In this mode, the output `Worklet`s returned in
+ * IComponentListener::onWorkDone() may not contain any buffers. The output
+ * buffers are passed directly to the consumer end of a buffer queue whose
+ * producer side is configured with the returned @p sidebandStream passed
+ * to IGraphicBufferProducer::setSidebandStream().
+ *
+ * The component is initially in the non-tunneled mode by default. The
+ * tunneled mode can be toggled on only before the component starts
+ * processing. Once the component is put into the tunneled mode, it shall
+ * stay in the tunneled mode until and only until reset() is called.
+ *
+ * @param avSyncHwId A resource ID for hardware sync. The generator of sync
+ * IDs must ensure that this number is unique among all services at any
+ * given time. For example, if both the audio HAL and the tuner HAL
+ * support this feature, sync IDs from the audio HAL must not clash
+ * with sync IDs from the tuner HAL.
+ * @return Codec-allocated sideband stream NativeHandle. This can
+ * be passed to IGraphicBufferProducer::setSidebandStream() to
+ * establish a direct channel to the consumer.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::OMITTED` - The component does not support video tunneling.
+ * - `Status::BAD_STATE` - The component is already running.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ NativeHandle configureVideoTunnel(in int avSyncHwId);
+
+ /**
+ * Creates a local `C2BlockPool` backed by the given allocator and returns
+ * its id.
+ *
+ * The returned @p blockPoolId is the only way the client can refer to a
+ * `C2BlockPool` object in the component. The id can be passed to
+ * setOutputSurface() or used in some C2Param objects later.
+ *
+ * The created `C2BlockPool` object can be destroyed by calling
+ * destroyBlockPool(), reset() or release(). reset() and release() must
+ * destroy all `C2BlockPool` objects that have been created.
+ *
+ * @param allocatorId Id of a `C2Allocator`.
+ * @param out configurable Configuration interface for the created pool. This
+ * must not be null.
+ * @return Created block pool information. This could be used to config/query and
+ * also be used in setOutputSurface() if the allocator
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NO_MEMORY` - Not enough memory to create the pool.
+ * - `Status::BAD_VALUE` - @p allocatorId is not recognized.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ BlockPool createBlockPool(in int allocatorId);
+
+ /**
+ * Destroys a local block pool previously created by createBlockPool().
+ *
+ * @param blockPoolId Id of a `C2BlockPool` that was previously returned by
+ * createBlockPool().
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NOT_FOUND` - The supplied blockPoolId is not valid.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void destroyBlockPool(in long blockPoolId);
+
+ /**
+ * Drains the component, and optionally downstream components. This is a
+ * signalling method; as such it does not wait for any work completion.
+ *
+ * The last `Work` item is marked as "drain-till-here", so the component is
+ * notified not to wait for further `Work` before it processes what is
+ * already queued. This method can also be used to set the end-of-stream
+ * flag after `Work` has been queued. Client can continue to queue further
+ * `Work` immediately after this method returns.
+ *
+ * This method must be supported in running (including tripped) states.
+ *
+ * `Work` that is completed must be returned via
+ * IComponentListener::onWorkDone().
+ *
+ * @param withEos Whether to drain the component with marking end-of-stream.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void drain(in boolean withEos);
+
+ /**
+ * Discards and abandons any pending `Work` items for the component.
+ *
+ * This method must be supported in running (including tripped) states.
+ *
+ * `Work` that could be immediately abandoned/discarded must be returned in
+ * @p flushedWorkBundle. The order in which queued `Work` items are
+ * discarded can be arbitrary.
+ *
+ * `Work` that could not be abandoned or discarded immediately must be
+ * marked to be discarded at the earliest opportunity, and must be returned
+ * via IComponentListener::onWorkDone(). This must be completed within
+ * 500ms.
+ *
+ * @return `WorkBundle` object containing flushed `Work` items.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ WorkBundle flush();
+
+ /**
+ * Returns the @ref IComponentInterface instance associated to this
+ * component.
+ *
+ * An @ref IConfigurable instance for the component can be obtained by calling
+ * IComponentInterface::getConfigurable() on the returned @p intf.
+ *
+ * @return `IComponentInterface` instance. This must not be null.
+ */
+ IComponentInterface getInterface();
+
+ /**
+ * Queues up work for the component.
+ *
+ * This method must be supported in running (including tripped) states.
+ *
+ * It is acceptable for this method to return `OK` and return an error value
+ * using the IComponentListener::onWorkDone() callback.
+ *
+ * @param workBundle `WorkBundle` object containing a list of `Work` objects
+ * to queue to the component.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::BAD_INDEX` - Some component id in some `Worklet` is not valid.
+ * - `Status::CANNOT_DO` - The components are not tunneled but some `Work` object
+ * contains tunneling information.
+ * - `Status::NO_MEMORY` - Not enough memory to queue @p workBundle.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void queue(in WorkBundle workBundle);
+
+ /**
+ * Releases the component.
+ *
+ * This method must be supported in stopped state.
+ *
+ * This method destroys the component. Upon return, if @p status is `OK` or
+ * `DUPLICATE`, all resources must have been released.
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::BAD_STATE` - The component is running.
+ * - `Status::DUPLICATE` - The component is already released.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void release();
+
+ /**
+ * Resets the component.
+ *
+ * This method must be supported in all (including tripped) states other
+ * than released.
+ *
+ * This method must be supported during any other blocking call.
+ *
+ * This method must return within 500ms.
+ *
+ * When this call returns, if @p status is `OK`, all `Work` items must
+ * have been abandoned, and all resources (including `C2BlockPool` objects
+ * previously created by createBlockPool()) must have been released.
+ *
+ * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is
+ * expected as a response to this call. For all other return values, the
+ * component must be in the stopped state.
+ *
+ * This brings settings back to their default, "guaranteeing" no tripped
+ * state.
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::BAD_STATE` - Component is in released state.
+ * - `Status::DUPLICATE` - When called during another reset call from another
+ * thread.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void reset();
+
+ /**
+ * Starts using a surface for output with a synchronization object
+ *
+ * This method must not block.
+ *
+ * @param blockPoolId Id of the `C2BlockPool` to be associated with the
+ * output surface.
+ * @param surface Output surface.
+ * @param syncObject synchronization object for buffer allocation between
+ * Framework and Component.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::CANNOT_DO` - The component does not support an output surface.
+ * - `Status::REFUSED` - The output surface cannot be accessed.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void setOutputSurface(in long blockPoolId, in Surface surface,
+ in SurfaceSyncObj syncObject);
+
+ /**
+ * Starts the component.
+ *
+ * This method must be supported in stopped state as well as tripped state.
+ *
+ * If the return value is `OK`, the component must be in the running state.
+ * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is
+ * expected as a response to this call. Otherwise, the component must be in
+ * the stopped state.
+ *
+ * If a component is in the tripped state and start() is called while the
+ * component configuration still results in a trip, start() must succeed and
+ * a new onTripped() callback must be used to communicate the configuration
+ * conflict that results in the new trip.
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::BAD_STATE` - Component is not in stopped or tripped state.
+ * - `Status::DUPLICATE` - When called during another start call from another
+ * thread.
+ * - `Status::NO_MEMORY` - Not enough memory to start the component.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void start();
+
+ /**
+ * Stops the component.
+ *
+ * This method must be supported in running (including tripped) state.
+ *
+ * This method must return within 500ms.
+ *
+ * Upon this call, all pending `Work` must be abandoned.
+ *
+ * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is
+ * expected as a response to this call. For all other return values, the
+ * component must be in the stopped state.
+ *
+ * This does not alter any settings and tunings that may have resulted in a
+ * tripped state.
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::BAD_STATE` - Component is not in running state.
+ * - `Status::DUPLICATE` - When called during another stop call from another
+ * thread.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void stop();
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/IComponentInterface.aidl b/media/c2/aidl/android/hardware/media/c2/IComponentInterface.aidl
new file mode 100644
index 0000000..9db81e6
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/IComponentInterface.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.IConfigurable;
+
+/**
+ * Component interface object. This object contains all of the configurations of
+ * a potential or actual component. It can be created and used independently of
+ * an actual Codec2 component to query supported parameters for various
+ * component settings, and configurations for a potential component.
+ *
+ * An actual component exposes this interface via IComponent::getInterface().
+ */
+@VintfStability
+interface IComponentInterface {
+ /**
+ * Returns the @ref IConfigurable instance associated to this component
+ * interface.
+ *
+ * @return `IConfigurable` instance. This must not be null.
+ */
+ IConfigurable getConfigurable();
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/IComponentListener.aidl b/media/c2/aidl/android/hardware/media/c2/IComponentListener.aidl
new file mode 100644
index 0000000..75500b7
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/IComponentListener.aidl
@@ -0,0 +1,131 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.SettingResult;
+import android.hardware.media.c2.Status;
+import android.hardware.media.c2.WorkBundle;
+
+/**
+ * Callback interface for handling notifications from @ref IComponent.
+ */
+@VintfStability
+oneway interface IComponentListener {
+ /**
+ * Identifying information for an input buffer previously queued to the
+ * component via IComponent::queue().
+ */
+ @VintfStability
+ parcelable InputBuffer {
+ /**
+ * This value comes from `Work::input.ordinal.frameIndex` in a `Work`
+ * object that was previously queued.
+ */
+ long frameIndex;
+ /**
+ * This value is an index into `Work::input.buffers` (which is an array)
+ * in a `Work` object that was previously queued.
+ */
+ int arrayIndex;
+ }
+ /**
+ * Information about rendering of a frame to a `Surface`.
+ */
+ @VintfStability
+ parcelable RenderedFrame {
+ /**
+ * Id of the `BufferQueue` containing the rendered buffer.
+ *
+ * This value must have been obtained by an earlier call to
+ * IGraphicBufferProducer::getUniqueId().
+ */
+ long bufferQueueId;
+ /**
+ * Id of the slot of the rendered buffer.
+ *
+ * This value must have been obtained by an earlier call to
+ * IGraphicBufferProducer::dequeueBuffer() or
+ * IGraphicBufferProducer::attachBuffer().
+ */
+ int slotId;
+ /**
+ * Timestamp the rendering happened.
+ *
+ * The reference point for the timestamp is determined by the
+ * `BufferQueue` that performed the rendering.
+ */
+ long timestampNs;
+ }
+ /**
+ * Notify the listener of an error.
+ *
+ * @param status Error type. @p status may be `OK`, which means that an
+ * error has occurred, but the error type does not fit into the type
+ * `Status`. In this case, additional information is provided by
+ * @p errorCode.
+ * @param errorCode Additional error information. The framework may not
+ * recognize the meaning of this value.
+ */
+ void onError(in Status status, in int errorCode);
+
+ /**
+ * Notify the listener that frames have been rendered.
+ *
+ * @param renderedFrames List of @ref RenderedFrame objects.
+ */
+ void onFramesRendered(in RenderedFrame[] renderedFrames);
+
+ /**
+ * Notify the listener that some input buffers are no longer needed by the
+ * component, and hence can be released or reused by the client.
+ *
+ * Input buffers that are contained in a `Work` object returned by an
+ * earlier onWorkDone() call are assumed released, so they must not appear
+ * in any onInputBuffersReleased() calls. That means
+ * onInputBuffersReleased() must only report input buffers that are released
+ * before the output in the same `Work` item is produced. However, it is
+ * possible for an input buffer to be returned by onWorkDone() after it has
+ * been reported by onInputBuffersReleased().
+ *
+ * @note onWorkDone() and onInputBuffersReleased() both notify the client
+ * that input buffers are no longer needed. However, in order to minimize
+ * IPC calls, onInputBuffersReleased() should be called only when
+ * onWorkDone() cannot be called, e.g., the component needs more input
+ * before an output can be produced.
+ *
+ * @param inputBuffers List of `InputBuffer` objects, identifying input
+ * buffers that are no longer needed by the component.
+ */
+ void onInputBuffersReleased(in InputBuffer[] inputBuffers);
+
+ /**
+ * Notify the listener that the component is tripped.
+ *
+ * @param settingResults List of failures.
+ */
+ void onTripped(in SettingResult[] settingResults);
+
+ /**
+ * Notify the listener that some `Work` items have been completed.
+ *
+ * All the input buffers in the returned `Work` objects must not be used by
+ * the component after onWorkDone() is called.
+ *
+ * @param workBundle List of completed `Work` objects.
+ */
+ void onWorkDone(in WorkBundle workBundle);
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/IComponentStore.aidl b/media/c2/aidl/android/hardware/media/c2/IComponentStore.aidl
new file mode 100644
index 0000000..1435a7e
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/IComponentStore.aidl
@@ -0,0 +1,185 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.Buffer;
+import android.hardware.media.c2.IComponent;
+import android.hardware.media.c2.IComponentInterface;
+import android.hardware.media.c2.IComponentListener;
+import android.hardware.media.c2.IConfigurable;
+import android.hardware.media.c2.StructDescriptor;
+
+/**
+ * Entry point for Codec2 HAL.
+ *
+ * All methods in `IComponentStore` must not block. If a method call cannot be
+ * completed in a timely manner, it must throw `Status::TIMED_OUT`. The only
+ * exceptions are getPoolClientManager() and getConfigurable(), which must
+ * always return immediately.
+ *
+ * @note This is an extension of version 1.1 of `IComponentStore`. The purpose
+ * of the extension is to add support for blocking output buffer allocator.
+ */
+@VintfStability
+interface IComponentStore {
+ /**
+ * Component traits.
+ */
+ @VintfStability
+ parcelable ComponentTraits {
+ @VintfStability
+ @Backing(type="int")
+ enum Kind {
+ OTHER = 0,
+ DECODER,
+ ENCODER,
+ }
+ @VintfStability
+ @Backing(type="int")
+ enum Domain {
+ OTHER = 0,
+ VIDEO,
+ AUDIO,
+ IMAGE,
+ }
+ /**
+ * Name of the component. This must be unique for each component.
+ *
+ * This name is use to identify the component to create in
+ * createComponent() and createComponentInterface().
+ */
+ String name;
+ /**
+ * Component domain.
+ */
+ Domain domain;
+ /**
+ * Component kind.
+ */
+ Kind kind;
+ /**
+ * Rank used by `MediaCodecList` to determine component ordering. Lower
+ * value means higher priority.
+ */
+ int rank;
+ /**
+ * MIME type.
+ */
+ String mediaType;
+ /**
+ * Aliases for component name for backward compatibility.
+ *
+ * Multiple components can have the same alias (but not the same
+ * component name) as long as their media types differ.
+ */
+ String[] aliases;
+ }
+
+ /**
+ * Copies the contents of @p src into @p dst without changing the format of
+ * @p dst.
+ *
+ * @param src Source buffer.
+ * @param dst Destination buffer.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::CANNOT_DO` - @p src and @p dst are not compatible.
+ * - `Status::REFUSED` - No permission to copy.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void copyBuffer(in Buffer src, in Buffer dst);
+
+ /**
+ * Creates a component by name.
+ *
+ * @param name Name of the component to create. This must match one of the
+ * names returned by listComponents().
+ * @param listener Callback receiver.
+ * @param pool `IClientManager` object of the BufferPool in the client
+ * process. This may be null if the client does not own a BufferPool.
+ * @return The created component.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NOT_FOUND` - There is no component with the given name.
+ * - `Status::NO_MEMORY` - Not enough memory to create the component.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ *
+ * @sa IComponentListener.
+ */
+ IComponent createComponent(in String name, in IComponentListener listener,
+ in android.hardware.media.bufferpool2.IClientManager pool);
+
+ /**
+ * Creates a component interface by name.
+ *
+ * @param name Name of the component interface to create. This should match
+ * one of the names returned by listComponents().
+ * @return The created component interface.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NOT_FOUND` - There is no component interface with the given name.
+ * - `Status::NO_MEMORY` - Not enough memory to create the component interface.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ IComponentInterface createInterface(in String name);
+
+ /**
+ * Returns the @ref IConfigurable instance associated to this component
+ * store.
+ *
+ * @return `IConfigurable` instance. This must not be null.
+ */
+ IConfigurable getConfigurable();
+
+ /**
+ * Returns the `IClientManager` object for the component's BufferPool.
+ *
+ * @return If the component store supports receiving buffers via
+ * BufferPool API, @p pool must be a valid `IClientManager` instance.
+ * Otherwise, @p pool must be null.
+ */
+ android.hardware.media.bufferpool2.IClientManager getPoolClientManager();
+
+ /**
+ * Returns a list of `StructDescriptor` objects for a set of requested
+ * C2Param structure indices that this store is aware of.
+ *
+ * This operation must be performed at best effort, e.g. the component
+ * store must simply ignore all struct indices that it is not aware of.
+ *
+ * @param indices Indices of C2Param structures to describe.
+ * @return List of `StructDescriptor` objects.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NOT_FOUND` - Some indices were not known.
+ * - `Status::NO_MEMORY` - Not enough memory to complete this method.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ StructDescriptor[] getStructDescriptors(in int[] indices);
+
+ /**
+ * Returns the list of components supported by this component store.
+ *
+ * @return traits List of component traits for all components supported by
+ * this store (in no particular order).
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NO_MEMORY` - Not enough memory to complete this method.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ ComponentTraits[] listComponents();
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl b/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
new file mode 100644
index 0000000..7fdb825
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
@@ -0,0 +1,213 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldSupportedValuesQuery;
+import android.hardware.media.c2.FieldSupportedValuesQueryResult;
+import android.hardware.media.c2.ParamDescriptor;
+import android.hardware.media.c2.Params;
+import android.hardware.media.c2.SettingResult;
+
+/**
+ * Generic configuration interface presented by all configurable Codec2 objects.
+ *
+ * This interface must be supported in all states of the owning object, and must
+ * not change the state of the owning object.
+ */
+@VintfStability
+interface IConfigurable {
+ /**
+ * Return parcelable for config() interface.
+ *
+ * This includes the successful config settings along with the failure reasons of
+ * the specified setting.
+ */
+ @VintfStability
+ parcelable ConfigResult {
+ Params params;
+ SettingResult[] failures;
+ }
+
+ /**
+ * Sets a set of parameters for the object.
+ *
+ * Tuning is performed at best effort: the object must update all supported
+ * configurations at best effort and skip unsupported parameters. Any errors
+ * are communicated in the return value along with the failures.
+ *
+ * A non-strict parameter update with an unsupported value shall cause an
+ * update to the closest supported value. A strict parameter update with an
+ * unsupported value shall be skipped and a failure shall be returned.
+ *
+ * If @p mayBlock is false, this method must not block. An update that
+ * requires blocking shall be skipped and a failure shall be returned.
+ *
+ * If @p mayBlock is true, an update may block, but the whole method call
+ * has to complete in a timely manner, or `Status::TIMED_OUT` is thrown.
+ *
+ * The final values for all parameters set are propagated back to the caller
+ * in @p params.
+ *
+ * \par For IComponent
+ *
+ * When the object type is @ref IComponent, this method must be supported in
+ * any state except released.
+ *
+ * The blocking behavior of this method differs among states:
+ * - In the stopped state, this must be non-blocking. @p mayBlock is
+ * ignored. (The method operates as if @p mayBlock was false.)
+ * - In any of the running states, this method may block momentarily if
+ * @p mayBlock is true. However, if the call cannot be completed in a
+ * timely manner, `Status::TIMED_OUT` is thrown.
+ *
+ * @note Parameter tuning @e does depend on the order of the tuning
+ * parameters, e.g., some parameter update may enable some subsequent
+ * parameter update.
+ *
+ * @param inParams Requested parameter updates.
+ * @param mayBlock Whether this call may block or not.
+ * @return result of config. Params in the result should be in same order
+ * with @p inParams.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NO_MEMORY` - Some supported parameters could not be updated
+ * successfully because they contained unsupported values.
+ * These are returned in @p failures.
+ * - `Status::BLOCKING` - Setting some parameters requires blocking, but
+ * @p mayBlock is false.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ ConfigResult config(in Params inParams, in boolean mayBlock);
+
+ /**
+ * Returns the id of the object. This must be unique among all objects of
+ * the same type hosted by the same store.
+ *
+ * @return Id of the object.
+ */
+ int getId();
+
+ /**
+ * Returns the name of the object.
+ *
+ * This must match the name that was supplied during the creation of the
+ * object.
+ *
+ * @return Name of the object.
+ */
+ String getName();
+
+ /**
+ * Queries a set of parameters from the object.
+ *
+ * Querying is performed at best effort: the object must query all supported
+ * parameters and skip unsupported ones (which may include parameters that
+ * could not be allocated).
+ *
+ * If @p mayBlock is true, a query may block, but the whole method call
+ * has to complete in a timely manner, or `Status::TIMED_OUT` is thrown.
+ *
+ * If @p mayBlock is false, this method must not block(All parameter queries
+ * that require blocking must be skipped). Otherwise, this
+ * method is allowed to block for a certain period of time before completing
+ * the operation. If the operation is not completed in a timely manner,
+ * `Status::TIMED_OUT` is thrown.
+ *
+ * @note Since unsupported parameters will be skipped, the returned results
+ * does not have every settings from @p indices, but the result will preserve
+ * the original order from @p indices though unsupported settings are skipped.
+ *
+ * \par For IComponent
+ *
+ * When the object type is @ref IComponent, this method must be supported in
+ * any state except released. This call must not change the state nor the
+ * internal configuration of the component.
+ *
+ * The blocking behavior of this method differs among states:
+ * - In the stopped state, this must be non-blocking. @p mayBlock is
+ * ignored. (The method operates as if @p mayBlock was false.)
+ * - In any of the running states, this method may block momentarily if
+ * @p mayBlock is true. However, if the call cannot be completed in a
+ * timely manner, `Status::status` is thrown.
+ *
+ * @param indices List of C2Param structure indices to query.
+ * @param mayBlock Whether this call may block or not.
+ * @return Flattened representation of std::vector<C2Param> object.
+ * Unsupported settings are skipped in the results. The order in @p indices
+ * still be preserved except skipped settings.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NO_MEMORY` - Could not allocate memory for a supported parameter.
+ * - `Status::BLOCKING` - Querying some parameters requires blocking, but
+ * @p mayBlock is false.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ Params query(in int[] indices, in boolean mayBlock);
+
+ /**
+ * Returns a list of supported parameters within a selected range of C2Param
+ * structure indices.
+ *
+ * @param start The first index of the selected range.
+ * @param count The length of the selected range.
+ * @return List of supported parameters in the selected range. This
+ * list may have fewer than @p count elements if some indices in the
+ * range are not supported.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NO_MEMORY` - Not enough memory to complete this method.
+ *
+ */
+ ParamDescriptor[] querySupportedParams(in int start, in int count);
+
+ /**
+ * Retrieves the supported values for the queried fields.
+ *
+ * The object must process all fields queried even if some queries fail.
+ *
+ * If @p mayBlock is false, this method must not block. Otherwise, this
+ * method is allowed to block for a certain period of time before completing
+ * the operation. If the operation cannot be completed in a timely manner,
+ * `Status::TIMED_OUT` is thrown.
+ *
+ * \par For IComponent
+ *
+ * When the object type is @ref IComponent, this method must be supported in
+ * any state except released.
+ *
+ * The blocking behavior of this method differs among states:
+ * - In the stopped state, this must be non-blocking. @p mayBlock is
+ * ignored. (The method operates as if @p mayBlock was false.)
+ * - In any of the running states, this method may block momentarily if
+ * @p mayBlock is true. However, if the call cannot be completed in a
+ * timely manner, `Status::TIMED_OUT` is thrown.
+ *
+ * @param inFields List of field queries.
+ * @param mayBlock Whether this call may block or not.
+ * @return List of supported values and results for the
+ * supplied queries.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::BLOCKING` - Querying some parameters requires blocking, but
+ * @p mayBlock is false.
+ * - `Status::NO_MEMORY` - Not enough memory to complete this method.
+ * - `Status::BLOCKING` - Querying some fields requires blocking, but @p mayblock
+ * is false.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ FieldSupportedValuesQueryResult[] querySupportedValues(
+ in FieldSupportedValuesQuery[] inFields, in boolean mayBlock);
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/InfoBuffer.aidl b/media/c2/aidl/android/hardware/media/c2/InfoBuffer.aidl
new file mode 100644
index 0000000..207c4d0
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/InfoBuffer.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.Buffer;
+
+/**
+ * An extension of @ref Buffer that also contains a C2Param structure index.
+ *
+ * This is a part of @ref FrameData.
+ */
+@VintfStability
+parcelable InfoBuffer {
+ /**
+ * A C2Param structure index.
+ */
+ int index;
+ /**
+ * Associated @ref Buffer object.
+ */
+ Buffer buffer;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/ParamDescriptor.aidl b/media/c2/aidl/android/hardware/media/c2/ParamDescriptor.aidl
new file mode 100644
index 0000000..84c6acc
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/ParamDescriptor.aidl
@@ -0,0 +1,73 @@
+/*
+ * 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 android.hardware.media.c2;
+
+/**
+ * Usage description of a C2Param structure.
+ *
+ * @ref ParamDescriptor is returned by IConfigurable::querySupportedParams().
+ */
+@VintfStability
+parcelable ParamDescriptor {
+ /** The list of bit flags for attrib */
+ /**
+ * The parameter is required to be specified.
+ */
+ const int ATTRIBUTE_REQUIRED = 1 << 0;
+ /**
+ * The parameter retains its value.
+ */
+ const int ATTRIBUTE_PERSISTENT = 1 << 1;
+ /**
+ * The parameter is strict.
+ */
+ const int ATTRIBUTE_STRICT = 1 << 2;
+ /**
+ * The parameter is publicly read-only.
+ */
+ const int ATTRIBUTE_READ_ONLY = 1 << 3;
+ /**
+ * The parameter must not be visible to clients.
+ */
+ const int ATTRIBUTE_HIDDEN = 1 << 4;
+ /**
+ * The parameter must not be used by framework (other than testing).
+ */
+ const int ATTRIBUTE_INTERNAL = 1 << 5;
+ /**
+ * The parameter is publicly constant (hence read-only).
+ */
+ const int ATTRIBUTE_CONST = 1 << 6;
+
+ /**
+ * Index of the C2Param structure being described.
+ */
+ int index;
+ /**
+ * bit flag for attribute defined in the above.
+ */
+ int attrib;
+ /**
+ * Name of the structure. This must be unique for each structure.
+ */
+ String name;
+ /**
+ * Indices of other C2Param structures that this C2Param structure depends
+ * on.
+ */
+ int[] dependencies;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/ParamField.aidl b/media/c2/aidl/android/hardware/media/c2/ParamField.aidl
new file mode 100644
index 0000000..64a46bb
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/ParamField.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldId;
+
+/**
+ * Reference to a field in a C2Param structure.
+ */
+@VintfStability
+parcelable ParamField {
+ /**
+ * Index of the C2Param structure.
+ */
+ int index;
+ /**
+ * Identifier of the field inside the C2Param structure.
+ */
+ FieldId fieldId;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/ParamFieldValues.aidl b/media/c2/aidl/android/hardware/media/c2/ParamFieldValues.aidl
new file mode 100644
index 0000000..7b74c0e
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/ParamFieldValues.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldSupportedValues;
+import android.hardware.media.c2.ParamField;
+
+/**
+ * Supported values for a field.
+ *
+ * This is a pair of the field specifier together with an optional supported
+ * values object. This structure is used when reporting parameter configuration
+ * failures and conflicts.
+ */
+@VintfStability
+parcelable ParamFieldValues {
+ /**
+ * Reference to a field or a C2Param structure.
+ */
+ ParamField paramOrField;
+ /**
+ * Optional supported values for the field if #paramOrField specifies an
+ * actual field that is numeric (non struct, blob or string). Supported
+ * values for arrays (including string and blobs) describe the supported
+ * values for each element (character for string, and bytes for blobs). It
+ * is optional for read-only strings and blobs.
+ */
+ FieldSupportedValues[] values;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/Params.aidl b/media/c2/aidl/android/hardware/media/c2/Params.aidl
new file mode 100644
index 0000000..53b512c
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/Params.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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 android.hardware.media.c2;
+
+/**
+ * Flattened representation of std::vector<C2Param> object.
+ *
+ * The `Params` type is an array of bytes made up by concatenating a list of
+ * C2Param objects. The start index (offset into @ref Params) of each C2Param
+ * object in the list is divisible by 8. Up to 7 padding bytes may be added
+ * after each C2Param object to achieve this 64-bit alignment.
+ *
+ * Each C2Param object has the following layout:
+ * - 4 bytes: C2Param structure index (of type @ref ParamIndex) identifying the
+ * type of the C2Param object.
+ * - 4 bytes: size of the C2Param object (unsigned 4-byte integer).
+ * - (size - 8) bytes: data of the C2Param object.
+ */
+@VintfStability
+parcelable Params {
+ byte[] params;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/SettingResult.aidl b/media/c2/aidl/android/hardware/media/c2/SettingResult.aidl
new file mode 100644
index 0000000..c2b9574
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/SettingResult.aidl
@@ -0,0 +1,99 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.ParamFieldValues;
+
+/**
+ * Information describing the reason the parameter settings may fail, or may be
+ * overridden.
+ */
+@VintfStability
+parcelable SettingResult {
+ /**
+ * Failure code
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum Failure {
+ /**
+ * Parameter is not supported.
+ */
+ BAD_TYPE,
+ /**
+ * Parameter is not supported on the specific port.
+ */
+ BAD_PORT,
+ /**
+ * Parameter is not supported on the specific stream.
+ */
+ BAD_INDEX,
+ /**
+ * Parameter is read-only and cannot be set.
+ */
+ READ_ONLY,
+ /**
+ * Parameter mismatches input data.
+ */
+ MISMATCH,
+ /**
+ * Strict parameter does not accept value for the field at all.
+ */
+ BAD_VALUE,
+ /**
+ * Strict parameter field value is in conflict with an/other
+ * setting(s).
+ */
+ CONFLICT,
+ /**
+ * Parameter field is out of range due to other settings. (This failure
+ * mode can only be used for strict calculated parameters.)
+ */
+ UNSUPPORTED,
+ /**
+ * Field does not access the requested parameter value at all. It has
+ * been corrected to the closest supported value. This failure mode is
+ * provided to give guidance as to what are the currently supported
+ * values for this field (which may be a subset of the at-all-potential
+ * values).
+ */
+ INFO_BAD_VALUE,
+ /**
+ * Requested parameter value is in conflict with an/other setting(s)
+ * and has been corrected to the closest supported value. This failure
+ * mode is given to provide guidance as to what are the currently
+ * supported values as well as to optionally provide suggestion to the
+ * client as to how to enable the requested parameter value.
+ */
+ INFO_CONFLICT,
+ }
+ Failure failure;
+ /**
+ * Failing (or corrected) field or parameter and optionally, currently
+ * supported values for the field. Values must only be set for field
+ * failures other than `BAD_VALUE`, and only if they are different from the
+ * globally supported values (e.g. due to restrictions by another parameter
+ * or input data).
+ */
+ ParamFieldValues field;
+ /**
+ * Conflicting parameters or fields with (optional) suggested values for any
+ * conflicting fields to avoid the conflict. Values must only be set for
+ * `CONFLICT`, `UNSUPPORTED` or `INFO_CONFLICT` failure code.
+ */
+ ParamFieldValues[] conflicts;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/Status.aidl b/media/c2/aidl/android/hardware/media/c2/Status.aidl
new file mode 100644
index 0000000..58a2404
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/Status.aidl
@@ -0,0 +1,82 @@
+/*
+ * 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 android.hardware.media.c2;
+
+/**
+ * Common return values for Codec2 operations.
+ */
+@VintfStability
+parcelable Status {
+ /**
+ * Operation completed successfully.
+ */
+ const int OK = 0;
+ /**
+ * Argument has invalid value (user error).
+ */
+ const int BAD_VALUE = -22;
+ /**
+ * Argument uses invalid index (user error).
+ */
+ const int BAD_INDEX = -75;
+ /**
+ * Argument/Index is valid but not possible.
+ */
+ const int CANNOT_DO = -2147483646;
+ /**
+ * Object already exists.
+ */
+ const int DUPLICATE = -17;
+ /**
+ * Object not found.
+ */
+ const int NOT_FOUND = -2;
+ /**
+ * Operation is not permitted in the current state.
+ */
+ const int BAD_STATE = -38;
+ /**
+ * Operation would block but blocking is not permitted.
+ */
+ const int BLOCKING = -9930;
+ /**
+ * Not enough memory to complete operation.
+ */
+ const int NO_MEMORY = -12;
+ /**
+ * Missing permission to complete operation.
+ */
+ const int REFUSED = -1;
+ /**
+ * Operation did not complete within timeout.
+ */
+ const int TIMED_OUT = -110;
+ /**
+ * Operation is not implemented/supported (optional only).
+ */
+ const int OMITTED = -74;
+ /**
+ * Some unexpected error prevented the operation.
+ */
+ const int CORRUPTED = -2147483648;
+ /**
+ * Status has not been initialized.
+ */
+ const int NO_INIT = -19;
+
+ int status;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/StructDescriptor.aidl b/media/c2/aidl/android/hardware/media/c2/StructDescriptor.aidl
new file mode 100644
index 0000000..00359041
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/StructDescriptor.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldDescriptor;
+
+/**
+ * Description of a C2Param structure. It consists of an index and a list of
+ * `FieldDescriptor`s.
+ */
+@VintfStability
+parcelable StructDescriptor {
+ /**
+ * Index of the structure.
+ *
+ * Actually C2Param::CoreIndex
+ * Core index is the underlying parameter type for a parameter. It is used to describe the
+ * layout of the parameter structure regardless of the component or parameter kind/scope.
+ *
+ * It is used to identify and distinguish global parameters, and also parameters on a given
+ * port or stream. They must be unique for the set of global parameters, as well as for the
+ * set of parameters on each port or each stream, but the same core index can be used for
+ * parameters on different streams or ports, as well as for global parameters and port/stream
+ * parameters.
+ */
+ int type;
+ /**
+ * List of fields in the structure.
+ *
+ * Fields are ordered by their offsets. A field that is a structure is
+ * ordered before its members.
+ */
+ FieldDescriptor[] fields;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl b/media/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl
new file mode 100644
index 0000000..d20e102
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl
@@ -0,0 +1,55 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.common.NativeHandle;
+/**
+ * Surface(BufferQueue/IGBP) synchronization object regarding # of dequeued
+ * output buffers. This keeps # of dequeued buffers from Surface less than
+ * configured max # of dequeued buffers all the time.
+ */
+@VintfStability
+parcelable SurfaceSyncObj {
+ /**
+ * ASharedMemory for synchronization data. Layout is below
+ *
+ * |lock(futex) 4bytes|
+ * |conditional_variable(futex) 4bytes|
+ * |# of max dequeable buffer 4bytes|
+ * |# of dequeued buffer 4bytes|
+ * |Status of the surface 4bytes|
+ * INIT = 0, Configuring surface is not finished.
+ * ACTIVE = 1, Surface is ready to allocate(dequeue).
+ * SWITCHING = 2, Switching to the new surface. It is blocked
+ * to allocate(dequeue) a buffer until switching
+ * completes.
+ */
+ NativeHandle syncMemory;
+ /**
+ * BufferQueue id.
+ */
+ long bqId;
+ /**
+ * Generation id.
+ */
+ int generationId;
+ /**
+ * Consumer usage flags. See +ndk
+ * libnativewindow#AHardwareBuffer_UsageFlags for possible values.
+ */
+ long consumerUsage;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/ValueRange.aidl b/media/c2/aidl/android/hardware/media/c2/ValueRange.aidl
new file mode 100644
index 0000000..9abcb7d
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/ValueRange.aidl
@@ -0,0 +1,63 @@
+/*
+ * 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 android.hardware.media.c2;
+
+/**
+ * Description of a set of values.
+ *
+ * If the `step` member is 0, and `num` and `denom` are both 1, the `Range`
+ * structure represents a closed interval bounded by `min` and `max`.
+ *
+ * Otherwise, the #ValueRange structure represents a finite sequence of numbers
+ * produced from the following recurrence relation:
+ *
+ * @code
+ * v[0] = min
+ * v[i] = v[i - 1] * num / denom + step ; i >= 1
+ * @endcode
+ *
+ * Both the ratio `num / denom` and the value `step` must be positive. The
+ * last number in the sequence described by this #Range structure is the
+ * largest number in the sequence that is smaller than or equal to `max`.
+ *
+ * @note
+ * The division in the formula may truncate the result if the data type of
+ * these values is an integral type.
+ */
+@VintfStability
+parcelable ValueRange {
+ /**
+ * Lower end of the range (inclusive).
+ */
+ long min;
+ /**
+ * Upper end of the range (inclusive).
+ */
+ long max;
+ /**
+ * The non-homogeneous term in the recurrence relation.
+ */
+ long step;
+ /**
+ * The numerator of the scale coefficient in the recurrence relation.
+ */
+ long num;
+ /**
+ * The denominator of the scale coefficient in the recurrence relation.
+ */
+ long denom;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/Work.aidl b/media/c2/aidl/android/hardware/media/c2/Work.aidl
new file mode 100644
index 0000000..4b8d696
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/Work.aidl
@@ -0,0 +1,83 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.FrameData;
+import android.hardware.media.c2.Status;
+import android.hardware.media.c2.Worklet;
+
+/**
+ * A collection of input data to and output data from the component.
+ *
+ * A `Work` object holds information about a single work item. It is created by
+ * the client and passed to the component via IComponent::queue(). The component
+ * has two ways of returning a `Work` object to the client:
+ * 1. If the queued `Work` object has been successfully processed,
+ * IComponentListener::onWorkDone() shall be called to notify the listener,
+ * and the output shall be included in the returned `Work` object.
+ * 2. If the client calls IComponent::flush(), a `Work` object that has not
+ * been processed shall be returned.
+ *
+ * `Work` is a part of @ref WorkBundle.
+ */
+@VintfStability
+parcelable Work {
+ /**
+ * Additional work chain info not part of this work.
+ */
+ byte[] chainInfo;
+ /**
+ * @ref FrameData for the input.
+ */
+ FrameData input;
+ /**
+ * The chain of `Worklet`s.
+ *
+ * The length of #worklets is 1 when tunneling is not enabled.
+ *
+ * If #worklets has more than a single element, the tunnels between
+ * successive components of the work chain must have been successfully
+ * pre-registered at the time that the `Work` is submitted. Allocating the
+ * output buffers in the `Worklet`s is the responsibility of each component
+ * in the chain.
+ *
+ * Upon `Work` submission, #worklets must be an appropriately sized vector
+ * containing `Worklet`s with @ref Worklet.hasOutput set to `false`. After a
+ * successful processing, all but the final `Worklet` in the returned
+ * #worklets must have @ref Worklet.hasOutput set to `false`.
+ */
+ Worklet[] worklets;
+ /**
+ * The number of `Worklet`s successfully processed in this chain.
+ *
+ * This must be initialized to 0 by the client when the `Work` is submitted,
+ * and it must contain the number of `Worklet`s that were successfully
+ * processed when the `Work` is returned to the client.
+ *
+ * #workletsProcessed cannot exceed the length of #worklets. If
+ * #workletsProcessed is smaller than the length of #worklets, #result
+ * cannot be `OK`.
+ */
+ int workletsProcessed;
+ /**
+ * The final outcome of the `Work` (corresponding to #workletsProcessed).
+ *
+ * The value of @ref Status.OK implies that all `Worklet`s have been
+ * successfully processed.
+ */
+ Status result;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/WorkBundle.aidl b/media/c2/aidl/android/hardware/media/c2/WorkBundle.aidl
new file mode 100644
index 0000000..2125fda
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/WorkBundle.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.BaseBlock;
+import android.hardware.media.c2.Work;
+
+/**
+ * List of `Work` objects.
+ *
+ * `WorkBundle` is used in IComponent::queue(), IComponent::flush() and
+ * IComponentListener::onWorkDone(). A `WorkBundle` object consists of a list of
+ * `Work` objects and a list of `BaseBlock` objects. Bundling multiple `Work`
+ * objects together provides two benefits:
+ * 1. Batching of `Work` objects can reduce the number of IPC calls.
+ * 2. If multiple `Work` objects contain `Block`s that refer to the same
+ * `BaseBlock`, the number of `BaseBlock`s that is sent between processes
+ * is also reduced.
+ *
+ * @note `WorkBundle` is the AIDL counterpart of the vector of `C2Work` in the
+ * Codec 2.0 standard. The presence of #baseBlocks helps with minimizing the
+ * data transferred over an IPC.
+ */
+@VintfStability
+parcelable WorkBundle {
+ /**
+ * A list of Work items.
+ */
+ Work[] works;
+ /**
+ * A list of blocks indexed by elements of #works.
+ */
+ BaseBlock[] baseBlocks;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/WorkOrdinal.aidl b/media/c2/aidl/android/hardware/media/c2/WorkOrdinal.aidl
new file mode 100644
index 0000000..5708a90
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/WorkOrdinal.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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 android.hardware.media.c2;
+
+/**
+ * Ordering information of @ref FrameData objects. Each member is used for
+ * comparing urgency: a smaller difference from a reference value indicates that
+ * the associated Work object is more urgent. The reference value for each
+ * member is initialized the first time it is communicated between the client
+ * and the codec, and it may be updated to later values that are communicated.
+ *
+ * Each member of `WorkOrdinal` is stored as an unsigned integer, but the actual
+ * order it represents is derived by subtracting the reference value, then
+ * interpreting the result as a signed number with the same storage size (using
+ * two's complement).
+ *
+ * @note `WorkOrdinal` is the HIDL counterpart of `C2WorkOrdinalStruct` in the
+ * Codec 2.0 standard.
+ */
+@VintfStability
+parcelable WorkOrdinal {
+ /**
+ * Timestamp in microseconds.
+ */
+ long timestampUs;
+ /**
+ * Frame index.
+ */
+ long frameIndex;
+ /**
+ * Component specific frame ordinal.
+ */
+ long customOrdinal;
+}
diff --git a/media/c2/aidl/android/hardware/media/c2/Worklet.aidl b/media/c2/aidl/android/hardware/media/c2/Worklet.aidl
new file mode 100644
index 0000000..6b3ceac
--- /dev/null
+++ b/media/c2/aidl/android/hardware/media/c2/Worklet.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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 android.hardware.media.c2;
+
+import android.hardware.media.c2.FrameData;
+import android.hardware.media.c2.SettingResult;
+
+/**
+ * In/out structure containing some instructions for and results from output
+ * processing.
+ *
+ * This is a part of @ref Work. One `Worklet` corresponds to one output
+ * @ref FrameData. The client must construct an original `Worklet` object inside
+ * a @ref Work object for each expected output before calling
+ * IComponent::queue().
+ */
+@VintfStability
+parcelable Worklet {
+ /**
+ * Component id. (Input)
+ *
+ * This is used only when tunneling is enabled.
+ *
+ * When used, this must match the return value from IConfigurable::getId().
+ */
+ int componentId;
+ /**
+ * List of C2Param objects describing tunings to be applied before
+ * processing this `Worklet`. (Input)
+ */
+ byte[] tunings;
+ /**
+ * List of failures. (Output)
+ */
+ SettingResult[] failures;
+ /**
+ * Output frame data. (Output)
+ */
+ FrameData output;
+}
diff --git a/memtrack/aidl/Android.bp b/memtrack/aidl/Android.bp
index 79effcb..0d1c241 100644
--- a/memtrack/aidl/Android.bp
+++ b/memtrack/aidl/Android.bp
@@ -39,5 +39,6 @@
},
},
},
+ frozen: true,
versions: ["1"],
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
new file mode 100644
index 0000000..fad767c
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.radio.config;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum MultipleEnabledProfilesMode {
+ NONE = 0,
+ MEP_A1 = 1,
+ MEP_A2 = 2,
+ MEP_B = 3,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
index be4c080..da894cd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
@@ -38,4 +38,5 @@
String atr;
String eid;
android.hardware.radio.config.SimPortInfo[] portInfo;
+ android.hardware.radio.config.MultipleEnabledProfilesMode supportedMepMode;
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
index 62f6204..a0792c3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
@@ -37,8 +37,12 @@
int fiveQi;
android.hardware.radio.data.QosBandwidth downlink;
android.hardware.radio.data.QosBandwidth uplink;
+ /**
+ * @deprecated use qosFlowIdentifier.
+ */
byte qfi;
char averagingWindowMs;
+ int qosFlowIdentifier;
const byte FLOW_ID_RANGE_MIN = 1;
const byte FLOW_ID_RANGE_MAX = 63;
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
index 2201345..2f2e07b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
@@ -41,4 +41,5 @@
int p2;
int p3;
String data;
+ boolean isEs10;
}
diff --git a/radio/aidl/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl b/radio/aidl/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
new file mode 100644
index 0000000..b18ea0e
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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 android.hardware.radio.config;
+
+/**
+ * Multiple Enabled Profiles(MEP) mode is the jointly supported MEP mode. As per section 3.4.1.1 of
+ * GSMA spec SGP.22 v3.0,there are 3 supported MEP modes: MEP-A1, MEP-A2 and MEP-B.
+ * If there is no jointly supported MEP mode, supported MEP mode is set to NONE.
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(toString=true)
+enum MultipleEnabledProfilesMode {
+ /**
+ * If there is no jointly supported MEP mode, set supported MEP mode to NONE.
+ */
+ NONE,
+ /**
+ * In case of MEP-A1, the ISD-R is selected on eSIM port 0 only and profiles are selected on
+ * eSIM ports 1 and higher, with the eSIM port being assigned by the LPA or platform.
+ */
+ MEP_A1,
+ /**
+ * In case of MEP-A2, the ISD-R is selected on eSIM port 0 only and profiles are selected on
+ * eSIM ports 1 and higher, with the eSIM port being assigned by the eUICC.
+ */
+ MEP_A2,
+ /**
+ * In case of MEP-B, profiles are selected on eSIM ports 0 and higher, with the ISD-R being
+ * selectable on any of these eSIM ports.
+ */
+ MEP_B,
+}
diff --git a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
index 748660f..73f2954 100644
--- a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
@@ -16,6 +16,7 @@
package android.hardware.radio.config;
+import android.hardware.radio.config.MultipleEnabledProfilesMode;
import android.hardware.radio.config.SimPortInfo;
@VintfStability
@@ -52,4 +53,8 @@
* active port in the slot mapping.
*/
SimPortInfo[] portInfo;
+ /**
+ * Jointly supported Multiple Enabled Profiles(MEP) mode as per SGP.22 V3.0
+ */
+ MultipleEnabledProfilesMode supportedMepMode;
}
diff --git a/radio/aidl/android/hardware/radio/data/NrQos.aidl b/radio/aidl/android/hardware/radio/data/NrQos.aidl
index af8ab83..28b4a7f 100644
--- a/radio/aidl/android/hardware/radio/data/NrQos.aidl
+++ b/radio/aidl/android/hardware/radio/data/NrQos.aidl
@@ -36,9 +36,13 @@
QosBandwidth downlink;
QosBandwidth uplink;
/**
- * QOS flow identifier of the QOS flow description in the range
- * (FLOW_ID_RANGE_MIN, FLOW_ID_RANGE_MAX)
+ * @deprecated use qosFlowIdentifier.
*/
byte qfi;
char averagingWindowMs;
+ /**
+ * QOS flow identifier of the QOS flow description in the range
+ * (FLOW_ID_RANGE_MIN, FLOW_ID_RANGE_MAX).
+ **/
+ int qosFlowIdentifier;
}
diff --git a/radio/aidl/android/hardware/radio/sim/SimApdu.aidl b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
index 43adbbc..4759e2e 100644
--- a/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
@@ -49,4 +49,9 @@
* In hex string format ([a-fA-F0-9]*)
*/
String data;
+ /**
+ * isEs10 indicates that the current streaming APDU contains an ES10 command or it is a regular
+ * APDU. (As per spec SGP.22 V3.0, ES10 commands needs to be sent over command port of MEP-A1)
+ */
+ boolean isEs10;
}
diff --git a/radio/aidl/compat/libradiocompat/data/structs.cpp b/radio/aidl/compat/libradiocompat/data/structs.cpp
index cc6dcbc..22cde6b 100644
--- a/radio/aidl/compat/libradiocompat/data/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/data/structs.cpp
@@ -136,7 +136,7 @@
.fiveQi = qos.fiveQi,
.downlink = toAidl(qos.downlink),
.uplink = toAidl(qos.uplink),
- .qfi = static_cast<int8_t>(qos.qfi),
+ .qosFlowIdentifier = static_cast<int8_t>(qos.qfi),
.averagingWindowMs = qos.averagingWindowMs,
};
}
diff --git a/secure_element/aidl/Android.bp b/secure_element/aidl/Android.bp
new file mode 100644
index 0000000..5a529a4
--- /dev/null
+++ b/secure_element/aidl/Android.bp
@@ -0,0 +1,35 @@
+aidl_interface {
+ name: "android.hardware.secure_element",
+ vendor_available: true,
+ host_supported: true,
+ srcs: ["android/hardware/secure_element/*.aidl"],
+ stability: "vintf",
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ sdk_version: "system_current",
+ },
+ },
+}
+
+cc_test {
+ name: "VtsHalSecureElementTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["vts/VtsHalSecureElementTargetTest.cpp"],
+ shared_libs: [
+ "libbinder_ndk",
+ ],
+ static_libs: [
+ "android.hardware.secure_element-V1-ndk",
+ "libgmock",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/ISecureElement.aidl b/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/ISecureElement.aidl
new file mode 100644
index 0000000..fba29ab
--- /dev/null
+++ b/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/ISecureElement.aidl
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.secure_element;
+@VintfStability
+interface ISecureElement {
+ void closeChannel(in byte channelNumber);
+ byte[] getAtr();
+ void init(in android.hardware.secure_element.ISecureElementCallback clientCallback);
+ boolean isCardPresent();
+ byte[] openBasicChannel(in byte[] aid, in byte p2);
+ android.hardware.secure_element.LogicalChannelResponse openLogicalChannel(in byte[] aid, in byte p2);
+ void reset();
+ byte[] transmit(in byte[] data);
+ const int FAILED = 1;
+ const int CHANNEL_NOT_AVAILABLE = 2;
+ const int NO_SUCH_ELEMENT_ERROR = 3;
+ const int UNSUPPORTED_OPERATION = 4;
+ const int IOERROR = 5;
+}
diff --git a/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/ISecureElementCallback.aidl b/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/ISecureElementCallback.aidl
new file mode 100644
index 0000000..6c2be2a
--- /dev/null
+++ b/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/ISecureElementCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.secure_element;
+@VintfStability
+interface ISecureElementCallback {
+ void onStateChange(in boolean connected, in String debugReason);
+}
diff --git a/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/LogicalChannelResponse.aidl b/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/LogicalChannelResponse.aidl
new file mode 100644
index 0000000..f2e7f04
--- /dev/null
+++ b/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/LogicalChannelResponse.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.secure_element;
+@VintfStability
+parcelable LogicalChannelResponse {
+ byte channelNumber;
+ byte[] selectResponse;
+}
diff --git a/secure_element/aidl/android/hardware/secure_element/ISecureElement.aidl b/secure_element/aidl/android/hardware/secure_element/ISecureElement.aidl
new file mode 100644
index 0000000..7c5a704
--- /dev/null
+++ b/secure_element/aidl/android/hardware/secure_element/ISecureElement.aidl
@@ -0,0 +1,129 @@
+/*
+ * 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 android.hardware.secure_element;
+
+import android.hardware.secure_element.ISecureElementCallback;
+import android.hardware.secure_element.LogicalChannelResponse;
+
+@VintfStability
+interface ISecureElement {
+ const int FAILED = 1;
+ const int CHANNEL_NOT_AVAILABLE = 2;
+ const int NO_SUCH_ELEMENT_ERROR = 3;
+ const int UNSUPPORTED_OPERATION = 4;
+ const int IOERROR = 5;
+
+ /**
+ * Closes the channel indicated by the channelNumber.
+ *
+ * @throws ServiceSpecificException Closing a channel must return
+ * FAILED on an error or if a basic channel (i.e. channel 0)
+ * is used.
+ *
+ * @param channelNumber to be closed
+ */
+ void closeChannel(in byte channelNumber);
+
+ /**
+ * Returns Answer to Reset as per ISO/IEC 7816
+ *
+ * @return containing the response. Empty vector if Secure Element
+ * doesn't support ATR.
+ */
+ byte[] getAtr();
+
+ /**
+ * Initializes the Secure Element. This may include updating the applet
+ * and/or vendor-specific initialization.
+ *
+ * HAL service must send onStateChange() with connected equal to true
+ * after all the initialization has been successfully completed.
+ * Clients must wait for a onStateChange(true) before opening channels.
+ *
+ * @param clientCallback callback used to sent status of the SE back to the
+ * client
+ */
+ void init(in ISecureElementCallback clientCallback);
+
+ /**
+ * Returns the current state of the card.
+ *
+ * This is useful for removable Secure Elements like UICC,
+ * Secure Elements on SD cards etc.
+ *
+ * @return true if present, false otherwise
+ */
+ boolean isCardPresent();
+
+ /**
+ * Opens a basic channel with the Secure Element, selecting the applet
+ * represented by the Application ID (AID). A basic channel has channel
+ * number 0.
+ *
+ * @throws ServiceSpecificException with codes
+ * - CHANNEL_NOT_AVAILABLE if secure element has reached the maximum
+ * limit on the number of channels it can support.
+ * - NO_SUCH_ELEMENT_ERROR if AID provided doesn't match any applet
+ * on the secure element.
+ * - UNSUPPORTED_OPERATION if operation provided by the P2 parameter
+ * is not permitted by the applet.
+ * - IOERROR if there was an error communicating with the Secure Element.
+ *
+ * @param aid AID to uniquely identify the applet on the Secure Element
+ * @param p2 P2 parameter of SELECT APDU as per ISO 7816-4
+ *
+ * @return On success, response to SELECT command.
+ */
+ byte[] openBasicChannel(in byte[] aid, in byte p2);
+
+ /**
+ * Opens a logical channel with the Secure Element, selecting the applet
+ * represented by the Application ID (AID).
+ *
+ * @param aid AID to uniquely identify the applet on the Secure Element
+ * @param p2 P2 parameter of SELECT APDU as per ISO 7816-4
+ * @throws ServiceSpecificException on error with the following code:
+ * - CHANNEL_NOT_AVAILABLE if secure element has reached the maximum
+ * limit on the number of channels it can support.
+ * - NO_SUCH_ELEMENT_ERROR if AID provided doesn't match any applet
+ * on the secure element.
+ * - UNSUPPORTED_OPERATION if operation provided by the P2 parameter
+ * is not permitted by the applet.
+ * - IOERROR if there was an error communicating with the Secure Element.
+ *
+ * @return On success, response to SELECT command
+ */
+ LogicalChannelResponse openLogicalChannel(in byte[] aid, in byte p2);
+
+ /**
+ * Reset the Secure Element.
+ *
+ * HAL should trigger reset to the secure element. It could hardware power cycle or
+ * a soft reset depends on the hardware design.
+ * HAL service must send onStateChange() with connected equal to true
+ * after resetting and all the re-initialization has been successfully completed.
+ */
+ void reset();
+
+ /**
+ * Transmits an APDU command (as per ISO/IEC 7816) to the SE.
+ *
+ * @param data APDU command to be sent
+ * @return response to the command
+ */
+ byte[] transmit(in byte[] data);
+}
diff --git a/secure_element/aidl/android/hardware/secure_element/ISecureElementCallback.aidl b/secure_element/aidl/android/hardware/secure_element/ISecureElementCallback.aidl
new file mode 100644
index 0000000..d15a7fb
--- /dev/null
+++ b/secure_element/aidl/android/hardware/secure_element/ISecureElementCallback.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.secure_element;
+
+@VintfStability
+interface ISecureElementCallback {
+ /**
+ * Used to inform the client about changes in the state of the Secure
+ * Element.
+ *
+ * @param connected indicates the current state of the SE
+ * @param reason provides additional data why there was a change in state
+ * ex. initialization error, SE removed etc
+ * This is used only for debugging purpose to understand
+ * in-field issues.
+ */
+ void onStateChange(in boolean connected, in String debugReason);
+}
diff --git a/secure_element/aidl/android/hardware/secure_element/LogicalChannelResponse.aidl b/secure_element/aidl/android/hardware/secure_element/LogicalChannelResponse.aidl
new file mode 100644
index 0000000..65ea71e
--- /dev/null
+++ b/secure_element/aidl/android/hardware/secure_element/LogicalChannelResponse.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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 android.hardware.secure_element;
+
+@VintfStability
+parcelable LogicalChannelResponse {
+ /**
+ * Channel number to uniquely identify the channel
+ */
+ byte channelNumber;
+ /**
+ * Response to SELECT command as per ISO/IEC 7816
+ */
+ byte[] selectResponse;
+}
diff --git a/secure_element/aidl/default/Android.bp b/secure_element/aidl/default/Android.bp
new file mode 100644
index 0000000..c604b68
--- /dev/null
+++ b/secure_element/aidl/default/Android.bp
@@ -0,0 +1,15 @@
+cc_binary {
+ name: "android.hardware.secure_element-service.example",
+ relative_install_path: "hw",
+ vendor: true,
+ init_rc: ["secure_element.rc"],
+ vintf_fragments: ["secure_element.xml"],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "android.hardware.secure_element-V1-ndk",
+ ],
+ srcs: [
+ "main.cpp",
+ ],
+}
diff --git a/secure_element/aidl/default/main.cpp b/secure_element/aidl/default/main.cpp
new file mode 100644
index 0000000..16b8236
--- /dev/null
+++ b/secure_element/aidl/default/main.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/secure_element/BnSecureElement.h>
+
+#include <android-base/hex.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::secure_element::BnSecureElement;
+using aidl::android::hardware::secure_element::ISecureElementCallback;
+using aidl::android::hardware::secure_element::LogicalChannelResponse;
+using android::base::HexString;
+using ndk::ScopedAStatus;
+
+static const std::vector<uint8_t> kAndroidTestAid = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41,
+ 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64,
+ 0x43, 0x54, 0x53, 0x31};
+static const std::vector<uint8_t> kLongAndroidTestAid = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41,
+ 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64,
+ 0x43, 0x54, 0x53, 0x32};
+
+class MySecureElement : public BnSecureElement {
+ public:
+ ScopedAStatus closeChannel(int8_t channelNumber) override {
+ LOG(INFO) << __func__ << " channel number: " << channelNumber;
+ return ScopedAStatus::ok();
+ }
+ ScopedAStatus getAtr(std::vector<uint8_t>* _aidl_return) override {
+ LOG(INFO) << __func__;
+ _aidl_return->clear();
+ return ScopedAStatus::ok();
+ }
+ ScopedAStatus init(const std::shared_ptr<ISecureElementCallback>& clientCallback) override {
+ LOG(INFO) << __func__ << " callback: " << clientCallback.get();
+ if (!clientCallback) {
+ return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+ }
+ mCb = clientCallback;
+ mCb->onStateChange(true, "");
+ return ScopedAStatus::ok();
+ }
+ ScopedAStatus isCardPresent(bool* _aidl_return) override {
+ LOG(INFO) << __func__;
+ *_aidl_return = true;
+ return ScopedAStatus::ok();
+ }
+ ScopedAStatus openBasicChannel(const std::vector<uint8_t>& aid, int8_t p2,
+ std::vector<uint8_t>* _aidl_return) override {
+ LOG(INFO) << __func__ << " aid: " << HexString(aid.data(), aid.size()) << " (" << aid.size()
+ << ") p2 " << p2;
+
+ // TODO(b/123254068) - this is not an implementation of the OMAPI protocol or APDU.
+ // The functionality here is enough to exercise the framework, but actual
+ // calls to the secure element will fail. This implementation does not model
+ // channel isolation or any other aspects important to implementing secure element.
+ *_aidl_return = {0x90, 0x00, 0x00}; // DO NOT COPY
+ return ScopedAStatus::ok();
+ }
+ ScopedAStatus openLogicalChannel(
+ const std::vector<uint8_t>& aid, int8_t p2,
+ ::aidl::android::hardware::secure_element::LogicalChannelResponse* _aidl_return)
+ override {
+ LOG(INFO) << __func__ << " aid: " << HexString(aid.data(), aid.size()) << " (" << aid.size()
+ << ") p2 " << p2;
+
+ if (aid != kAndroidTestAid && aid != kLongAndroidTestAid) {
+ return ScopedAStatus::fromServiceSpecificError(NO_SUCH_ELEMENT_ERROR);
+ }
+
+ *_aidl_return = LogicalChannelResponse{.channelNumber = 1, .selectResponse = {}};
+
+ // TODO(b/123254068) - this is not an implementation of the OMAPI protocol or APDU.
+ // The functionality here is enough to exercise the framework, but actual
+ // calls to the secure element will fail. This implementation does not model
+ // channel isolation or any other aspects important to implementing secure element.
+ if (aid == kAndroidTestAid) { // DO NOT COPY
+ size_t size = 2050; // DO NOT COPY
+ _aidl_return->selectResponse.resize(size); // DO NOT COPY
+ _aidl_return->selectResponse[size - 1] = 0x00; // DO NOT COPY
+ _aidl_return->selectResponse[size - 2] = 0x90; // DO NOT COPY
+ } else { // DO NOT COPY
+ _aidl_return->selectResponse = {0x00, 0x00, 0x90, 0x00}; // DO NOT COPY
+ } // DO NOT COPY
+
+ LOG(INFO) << __func__ << " sending response: "
+ << HexString(_aidl_return->selectResponse.data(),
+ _aidl_return->selectResponse.size());
+
+ return ScopedAStatus::ok();
+ }
+ ScopedAStatus reset() override {
+ LOG(INFO) << __func__;
+ mCb->onStateChange(false, "reset");
+ mCb->onStateChange(true, "reset");
+ return ScopedAStatus::ok();
+ }
+ ScopedAStatus transmit(const std::vector<uint8_t>& data,
+ std::vector<uint8_t>* _aidl_return) override {
+ LOG(INFO) << __func__ << " data: " << HexString(data.data(), data.size()) << " ("
+ << data.size() << ")";
+
+ // TODO(b/123254068) - this is not an implementation of the OMAPI protocol or APDU.
+ // The functionality here is enough to exercise the framework, but actual
+ // calls to the secure element will fail. This implementation does not model
+ // channel isolation or any other aspects important to implementing secure element.
+
+ std::string hex = HexString(data.data(), data.size()); // DO NOT COPY
+ if (hex == "01a4040210a000000476416e64726f696443545331") { // DO NOT COPY
+ *_aidl_return = {0x00, 0x6A, 0x00}; // DO NOT COPY
+ } else if (data == std::vector<uint8_t>{0x00, 0xF4, 0x00, 0x00, 0x00}) { // DO NOT COPY
+ // CHECK_SELECT_P2_APDU w/ channel 1 // DO NOT COPY
+ *_aidl_return = {0x00, 0x90, 0x00}; // DO NOT COPY
+ } else if (data == std::vector<uint8_t>{0x01, 0xF4, 0x00, 0x00, 0x00}) { // DO NOT COPY
+ // CHECK_SELECT_P2_APDU w/ channel 1 // DO NOT COPY
+ *_aidl_return = {0x00, 0x90, 0x00}; // DO NOT COPY
+ } else if (data.size() == 5 || data.size() == 8) { // DO NOT COPY
+ // SEGMENTED_RESP_APDU - happens to use length 5 and 8 // DO NOT COPY
+ size_t size = (data[2] << 8 | data[3]) + 2; // DO NOT COPY
+ _aidl_return->resize(size); // DO NOT COPY
+ (*_aidl_return)[size - 1] = 0x00; // DO NOT COPY
+ (*_aidl_return)[size - 2] = 0x90; // DO NOT COPY
+ if (size >= 3) (*_aidl_return)[size - 3] = 0xFF; // DO NOT COPY
+ } else { // DO NOT COPY
+ *_aidl_return = {0x90, 0x00, 0x00}; // DO NOT COPY
+ } // DO NOT COPY
+
+ return ScopedAStatus::ok();
+ }
+
+ private:
+ std::shared_ptr<ISecureElementCallback> mCb;
+};
+
+int main() {
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+ auto se = ndk::SharedRefBase::make<MySecureElement>();
+ const std::string name = std::string() + BnSecureElement::descriptor + "/eSE1";
+ binder_status_t status = AServiceManager_addService(se->asBinder().get(), name.c_str());
+ CHECK_EQ(status, STATUS_OK);
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reach
+}
diff --git a/secure_element/aidl/default/secure_element.rc b/secure_element/aidl/default/secure_element.rc
new file mode 100644
index 0000000..7d21666
--- /dev/null
+++ b/secure_element/aidl/default/secure_element.rc
@@ -0,0 +1,4 @@
+service vendor.secure_element /vendor/bin/hw/android.hardware.secure_element-service.example
+ class hal
+ user nobody
+ group nobody
diff --git a/secure_element/aidl/default/secure_element.xml b/secure_element/aidl/default/secure_element.xml
new file mode 100644
index 0000000..96ab2e7
--- /dev/null
+++ b/secure_element/aidl/default/secure_element.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.secure_element</name>
+ <version>1</version>
+ <fqname>ISecureElement/eSE1</fqname>
+ </hal>
+</manifest>
diff --git a/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp b/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp
new file mode 100644
index 0000000..a85a8bc
--- /dev/null
+++ b/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/secure_element/BnSecureElementCallback.h>
+#include <aidl/android/hardware/secure_element/ISecureElement.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+
+using namespace std::chrono_literals;
+
+using aidl::android::hardware::secure_element::BnSecureElementCallback;
+using aidl::android::hardware::secure_element::ISecureElement;
+using aidl::android::hardware::secure_element::LogicalChannelResponse;
+using ndk::ScopedAStatus;
+using ndk::SharedRefBase;
+using ndk::SpAIBinder;
+using testing::ElementsAre;
+using testing::ElementsAreArray;
+
+#define EXPECT_OK(status) \
+ do { \
+ auto status_impl = (status); \
+ EXPECT_TRUE(status_impl.isOk()) << status_impl.getDescription(); \
+ } while (false)
+
+static const std::vector<uint8_t> kDataApdu = {0x00, 0x08, 0x00, 0x00, 0x00};
+static const std::vector<uint8_t> kAndroidTestAid = {0xA0, 0x00, 0x00, 0x04, 0x76, 0x41,
+ 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64,
+ 0x43, 0x54, 0x53, 0x31};
+
+class MySecureElementCallback : public BnSecureElementCallback {
+ public:
+ ScopedAStatus onStateChange(bool state, const std::string& debugReason) override {
+ {
+ std::unique_lock<std::mutex> l(m);
+ (void)debugReason;
+ history.push_back(state);
+ }
+ cv.notify_one();
+ return ScopedAStatus::ok();
+ };
+
+ void expectCallbackHistory(std::vector<bool>&& want) {
+ std::unique_lock<std::mutex> l(m);
+ cv.wait_for(l, 2s, [&]() { return history.size() >= want.size(); });
+ EXPECT_THAT(history, ElementsAreArray(want));
+ }
+
+ private:
+ std::mutex m; // guards history
+ std::condition_variable cv;
+ std::vector<bool> history;
+};
+
+class SecureElementAidl : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ SpAIBinder binder = SpAIBinder(AServiceManager_waitForService(GetParam().c_str()));
+ se = ISecureElement::fromBinder(binder);
+ ASSERT_NE(se, nullptr);
+
+ cb = SharedRefBase::make<MySecureElementCallback>();
+ EXPECT_OK(se->init(cb));
+
+ cb->expectCallbackHistory({true});
+ }
+
+ std::shared_ptr<ISecureElement> se;
+ std::shared_ptr<MySecureElementCallback> cb;
+};
+
+TEST_P(SecureElementAidl, isCardPresent) {
+ bool res = false;
+ EXPECT_OK(se->isCardPresent(&res));
+ EXPECT_TRUE(res);
+}
+
+TEST_P(SecureElementAidl, transmit) {
+ LogicalChannelResponse response;
+ EXPECT_OK(se->openLogicalChannel(kAndroidTestAid, 0x00, &response));
+
+ EXPECT_GE(response.selectResponse.size(), 2u);
+ EXPECT_GE(response.channelNumber, 1);
+
+ std::vector<uint8_t> command = kDataApdu;
+ command[0] |= response.channelNumber;
+
+ std::vector<uint8_t> transmitResponse;
+ EXPECT_OK(se->transmit(command, &transmitResponse));
+
+ EXPECT_LE(transmitResponse.size(), 3);
+ EXPECT_GE(transmitResponse.size(), 2);
+ EXPECT_EQ(transmitResponse[transmitResponse.size() - 1], 0x00);
+ EXPECT_EQ(transmitResponse[transmitResponse.size() - 2], 0x90);
+
+ EXPECT_OK(se->closeChannel(response.channelNumber));
+}
+
+TEST_P(SecureElementAidl, openBasicChannel) {
+ std::vector<uint8_t> response;
+ auto status = se->openBasicChannel(kAndroidTestAid, 0x00, &response);
+
+ if (!status.isOk()) {
+ EXPECT_EQ(status.getServiceSpecificError(), ISecureElement::CHANNEL_NOT_AVAILABLE)
+ << status.getDescription();
+ return;
+ }
+
+ EXPECT_GE(response.size(), 2u);
+ EXPECT_OK(se->closeChannel(0));
+}
+
+TEST_P(SecureElementAidl, getAtr) {
+ std::vector<uint8_t> atr;
+ EXPECT_OK(se->getAtr(&atr));
+ if (atr.size() == 0) {
+ return;
+ }
+ EXPECT_LE(atr.size(), 32u);
+ EXPECT_GE(atr.size(), 1u);
+}
+
+TEST_P(SecureElementAidl, openCloseLogicalChannel) {
+ LogicalChannelResponse response;
+ EXPECT_OK(se->openLogicalChannel(kAndroidTestAid, 0x00, &response));
+ EXPECT_GE(response.selectResponse.size(), 2u);
+ EXPECT_GE(response.channelNumber, 1);
+ EXPECT_OK(se->closeChannel(response.channelNumber));
+}
+
+TEST_P(SecureElementAidl, openInvalidAid) {
+ LogicalChannelResponse response;
+ auto status = se->openLogicalChannel({0x42}, 0x00, &response);
+ EXPECT_EQ(status.getServiceSpecificError(), ISecureElement::NO_SUCH_ELEMENT_ERROR)
+ << status.getDescription();
+}
+
+TEST_P(SecureElementAidl, Reset) {
+ cb->expectCallbackHistory({true});
+ EXPECT_OK(se->reset());
+ cb->expectCallbackHistory({true, false, true});
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SecureElementAidl);
+INSTANTIATE_TEST_SUITE_P(
+ SecureElement, SecureElementAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(ISecureElement::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
index 4c2be89..294c205 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
@@ -125,9 +125,9 @@
* straightforward translation of the KeyMint tag/value parameter lists to ASN.1.
*
* KeyDescription ::= SEQUENCE {
- * attestationVersion INTEGER, # Value 200
+ * attestationVersion INTEGER, # Value 300
* attestationSecurityLevel SecurityLevel, # See below
- * keyMintVersion INTEGER, # Value 200
+ * keyMintVersion INTEGER, # Value 300
* keymintSecurityLevel SecurityLevel, # See below
* attestationChallenge OCTET_STRING, # Tag::ATTESTATION_CHALLENGE from attestParams
* uniqueId OCTET_STRING, # Empty unless key has Tag::INCLUDE_UNIQUE_ID
@@ -209,6 +209,7 @@
* vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL,
* bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL,
* deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL,
+ * attestationIdSecondImei [723] EXPLICIT OCTET_STRING OPTIONAL,
* }
*/
Certificate[] certificateChain;
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index f4c0095..ea4ba18 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -892,6 +892,7 @@
ASSERT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG)
<< "result = " << result;
+ device_id_attestation_vsr_check(result);
}
CheckedDeleteKey(&attest_key.keyBlob);
}
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index cd140c8..26dc3f5 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -348,8 +348,8 @@
// Add the tag that doesn't match the local device's real ID.
builder.push_back(invalid_tag);
auto result = GenerateKey(builder, &key_blob, &key_characteristics);
-
ASSERT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG);
+ device_id_attestation_vsr_check(result);
}
}
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 80abd92..43ad30a 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -2031,6 +2031,16 @@
*signingKey = std::move(pubKey);
}
+void device_id_attestation_vsr_check(const ErrorCode& result) {
+ if (get_vsr_api_level() >= 34) {
+ ASSERT_FALSE(result == ErrorCode::INVALID_TAG)
+ << "It is a specification violation for INVALID_TAG to be returned due to ID "
+ << "mismatch in a Device ID Attestation call. INVALID_TAG is only intended to "
+ << "be used for a case where updateAad() is called after update(). As of "
+ << "VSR-14, this is now enforced as an error.";
+ }
+}
+
} // namespace test
} // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 67e8b21..5b09ca5 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -395,6 +395,7 @@
void check_maced_pubkey(const MacedPublicKey& macedPubKey, bool testMode,
vector<uint8_t>* payload_value);
void p256_pub_key(const vector<uint8_t>& coseKeyData, EVP_PKEY_Ptr* signingKey);
+void device_id_attestation_vsr_check(const ErrorCode& result);
AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
diff --git a/security/rkp/CHANGELOG.md b/security/rkp/CHANGELOG.md
index 29b1a1c..c3e3609 100644
--- a/security/rkp/CHANGELOG.md
+++ b/security/rkp/CHANGELOG.md
@@ -27,7 +27,7 @@
`"android.hardward.security.keymint"`).
* ProtectedData has been removed.
* DeviceInfo
- * `version` has moved to a top-level field within the CSR generated by the HAL
+ * `version` has moved to a top-level field within the CSR generated by the HAL.
* IRemotelyProvisionedComponent
* The need for an EEK has been removed. There is no longer an encrypted portion of the CSR.
* Test mode has been removed.
@@ -36,5 +36,10 @@
* the chain of signing, MACing, and encryption operations has been replaced with a single
COSE_Sign1 object.
* CertificateType has been added to identify the type of certificate being requested.
+ * The structure has been composed to enable a clear split between what is required to validate a
+ payload and the implementation-defined payload itself. This is done by creating a typed
+ `AuthenticatedRequest<T>` object representing the top level data required to authenticate
+ the data provided in the payload, `T`.
* RpcHardwareInfo
* `supportedNumKeysInCsr` added to report the maximum number of keys supported in a CSR.
+ * `supportedEekCurve` is no longer used, due to the removal of the EEK from the scheme.
diff --git a/security/rkp/aidl/Android.bp b/security/rkp/aidl/Android.bp
index 4c479f4..5285477 100644
--- a/security/rkp/aidl/Android.bp
+++ b/security/rkp/aidl/Android.bp
@@ -21,6 +21,10 @@
backend: {
java: {
min_sdk_version: "33",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.rkpd",
+ ],
},
rust: {
enabled: true,
diff --git a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 78969d1..2fc780c 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -345,20 +345,20 @@
* ]
*
* ; COSE_Sign1 (untagged)
- * SignedData<T> = [
+ * SignedData<Data> = [
* protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
* unprotected: {},
- * payload: bstr .cbor T / nil,
- * signature: bstr ; PureEd25519(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct<T>) /
- * ; ECDSA(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct<T>)
+ * payload: bstr .cbor Data / nil,
+ * signature: bstr ; PureEd25519(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct<Data>) /
+ * ; ECDSA(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct<Data>)
* ]
*
* ; Sig_structure for SignedData
- * SignedDataSigStruct<T> = [
+ * SignedDataSigStruct<Data> = [
* context: "Signature1",
* protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
* external_aad: bstr .size 0,
- * payload: bstr .cbor T
+ * payload: bstr .cbor Data / nil,
* ]
*
* ; UdsCerts allows the platform to provide additional certifications for the UDS_Pub. For
diff --git a/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
index 5fe5b00..d0b059d 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
@@ -29,9 +29,9 @@
const int CURVE_25519 = 2;
/**
- * Implementation version of the remotely provisioned component hardware. The version number is
- * implementation defined, and not necessarily globally meaningful. The version is used to
- * distinguish between different versions of a given implementation.
+ * Implementation version of the remotely provisioned component hardware. The version provided
+ * here must match the version reported in the CsrPayload produced by the HAL interface. This
+ * field primarily acts as a convenience for the system components interacting with the HALs.
*/
int versionNumber;
@@ -43,6 +43,9 @@
@utf8InCpp String rpcAuthorName;
/**
+ * NOTE: This field is no longer used as of version 3 of the HAL interface. This is because the
+ * Endpoint Encryption Key is no longer used in the provisioning scheme.
+ *
* supportedEekCurve returns an int representing which curve is supported for validating
* signatures over the Endpoint Encryption Key certificate chain and for using the corresponding
* signed encryption key in ECDH. Only one curve should be supported, with preference for 25519
diff --git a/sensors/1.0/default/Android.bp b/sensors/1.0/default/Android.bp
index 2e4e1b0..bb31050 100644
--- a/sensors/1.0/default/Android.bp
+++ b/sensors/1.0/default/Android.bp
@@ -44,6 +44,12 @@
"libhidlbase",
"android.hardware.sensors@1.0",
],
+ whole_static_libs: [
+ "sensors_common_convert",
+ ],
+ export_static_lib_headers: [
+ "sensors_common_convert",
+ ],
local_include_dirs: ["include/sensors"],
export_shared_lib_headers: [
"libhardware",
diff --git a/sensors/1.0/default/convert.cpp b/sensors/1.0/default/convert.cpp
index 43ee327..ae71a97 100644
--- a/sensors/1.0/default/convert.cpp
+++ b/sensors/1.0/default/convert.cpp
@@ -196,6 +196,11 @@
}
}
+void convertFromASensorEvent(const ASensorEvent& src, Event* dst) {
+ convertFromSensorEvent(
+ android::hardware::sensors::implementation::common::convertASensorEvent(src), dst);
+}
+
void convertToSensorEvent(const Event &src, sensors_event_t *dst) {
*dst = {.version = sizeof(sensors_event_t),
.sensor = src.sensorHandle,
diff --git a/sensors/1.0/default/include/sensors/convert.h b/sensors/1.0/default/include/sensors/convert.h
index c3a0125..ae773df 100644
--- a/sensors/1.0/default/include/sensors/convert.h
+++ b/sensors/1.0/default/include/sensors/convert.h
@@ -20,6 +20,7 @@
#include <android/hardware/sensors/1.0/ISensors.h>
#include <hardware/sensors.h>
+#include <sensors/common_convert.h>
namespace android {
namespace hardware {
@@ -31,6 +32,7 @@
void convertToSensor(const SensorInfo &src, sensor_t *dst);
void convertFromSensorEvent(const sensors_event_t &src, Event *dst);
+void convertFromASensorEvent(const ASensorEvent& src, Event* dst);
void convertToSensorEvent(const Event &src, sensors_event_t *dst);
bool convertFromSharedMemInfo(const SharedMemInfo& memIn, sensors_direct_mem_t *memOut);
diff --git a/sensors/aidl/Android.bp b/sensors/aidl/Android.bp
index d04017c..9673190 100644
--- a/sensors/aidl/Android.bp
+++ b/sensors/aidl/Android.bp
@@ -11,6 +11,7 @@
name: "android.hardware.sensors",
vendor_available: true,
srcs: ["android/hardware/sensors/*.aidl"],
+ host_supported: true,
imports: [
"android.hardware.common-V2",
"android.hardware.common.fmq-V1",
diff --git a/audio/aidl/default/reverb/Android.bp b/sensors/aidl/convert/Android.bp
similarity index 62%
copy from audio/aidl/default/reverb/Android.bp
copy to sensors/aidl/convert/Android.bp
index 955038c..0b31597 100644
--- a/audio/aidl/default/reverb/Android.bp
+++ b/sensors/aidl/convert/Android.bp
@@ -23,18 +23,28 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
-cc_library_shared {
- name: "libreverbsw",
- defaults: [
- "aidlaudioeffectservice_defaults",
- "latest_android_media_audio_common_types_ndk_shared",
- "latest_android_hardware_audio_effect_ndk_shared",
+cc_library_static {
+ name: "android.hardware.sensors-V1-convert",
+ vendor_available: true,
+ host_supported: true,
+ srcs: ["convert.cpp"],
+ export_include_dirs: ["include"],
+ shared_libs: [
+ "liblog",
+ "libcutils",
+ "libhardware",
+ "libbase",
+ "libutils",
+ "android.hardware.sensors-V1-ndk",
],
- srcs: [
- "ReverbSw.cpp",
- ":effectCommonFile",
+ whole_static_libs: [
+ "sensors_common_convert",
],
- visibility: [
- "//hardware/interfaces/audio/aidl/default",
+ export_static_lib_headers: [
+ "sensors_common_convert",
+ ],
+ local_include_dirs: ["include/aidl/sensors"],
+ export_shared_lib_headers: [
+ "libhardware",
],
}
diff --git a/sensors/aidl/convert/convert.cpp b/sensors/aidl/convert/convert.cpp
new file mode 100644
index 0000000..abd4d55
--- /dev/null
+++ b/sensors/aidl/convert/convert.cpp
@@ -0,0 +1,500 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "aidl/sensors/convert.h"
+#include "android-base/logging.h"
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+
+using aidl::android::hardware::sensors::AdditionalInfo;
+using aidl::android::hardware::sensors::DynamicSensorInfo;
+using aidl::android::hardware::sensors::Event;
+using aidl::android::hardware::sensors::ISensors;
+using aidl::android::hardware::sensors::SensorInfo;
+using aidl::android::hardware::sensors::SensorStatus;
+using aidl::android::hardware::sensors::SensorType;
+
+status_t convertToStatus(ndk::ScopedAStatus status) {
+ if (status.isOk()) {
+ return OK;
+ } else {
+ switch (status.getExceptionCode()) {
+ case EX_ILLEGAL_ARGUMENT: {
+ return BAD_VALUE;
+ }
+ case EX_SECURITY: {
+ return PERMISSION_DENIED;
+ }
+ case EX_UNSUPPORTED_OPERATION: {
+ return INVALID_OPERATION;
+ }
+ case EX_SERVICE_SPECIFIC: {
+ switch (status.getServiceSpecificError()) {
+ case ISensors::ERROR_BAD_VALUE: {
+ return BAD_VALUE;
+ }
+ case ISensors::ERROR_NO_MEMORY: {
+ return NO_MEMORY;
+ }
+ default: {
+ return UNKNOWN_ERROR;
+ }
+ }
+ }
+ default: {
+ return UNKNOWN_ERROR;
+ }
+ }
+ }
+}
+
+void convertToSensor(const SensorInfo& src, sensor_t* dst) {
+ dst->name = strdup(src.name.c_str());
+ dst->vendor = strdup(src.vendor.c_str());
+ dst->version = src.version;
+ dst->handle = src.sensorHandle;
+ dst->type = (int)src.type;
+ dst->maxRange = src.maxRange;
+ dst->resolution = src.resolution;
+ dst->power = src.power;
+ dst->minDelay = src.minDelayUs;
+ dst->fifoReservedEventCount = src.fifoReservedEventCount;
+ dst->fifoMaxEventCount = src.fifoMaxEventCount;
+ dst->stringType = strdup(src.typeAsString.c_str());
+ dst->requiredPermission = strdup(src.requiredPermission.c_str());
+ dst->maxDelay = src.maxDelayUs;
+ dst->flags = src.flags;
+ dst->reserved[0] = dst->reserved[1] = 0;
+}
+
+void convertToSensorEvent(const Event& src, sensors_event_t* dst) {
+ *dst = {.version = sizeof(sensors_event_t),
+ .sensor = src.sensorHandle,
+ .type = (int32_t)src.sensorType,
+ .reserved0 = 0,
+ .timestamp = src.timestamp};
+
+ switch (src.sensorType) {
+ case SensorType::META_DATA: {
+ // Legacy HALs expect the handle reference in the meta data field.
+ // Copy it over from the handle of the event.
+ dst->meta_data.what = (int32_t)src.payload.get<Event::EventPayload::meta>().what;
+ dst->meta_data.sensor = src.sensorHandle;
+ // Set the sensor handle to 0 to maintain compatibility.
+ dst->sensor = 0;
+ break;
+ }
+
+ case SensorType::ACCELEROMETER:
+ case SensorType::MAGNETIC_FIELD:
+ case SensorType::ORIENTATION:
+ case SensorType::GYROSCOPE:
+ case SensorType::GRAVITY:
+ case SensorType::LINEAR_ACCELERATION: {
+ dst->acceleration.x = src.payload.get<Event::EventPayload::vec3>().x;
+ dst->acceleration.y = src.payload.get<Event::EventPayload::vec3>().y;
+ dst->acceleration.z = src.payload.get<Event::EventPayload::vec3>().z;
+ dst->acceleration.status = (int32_t)src.payload.get<Event::EventPayload::vec3>().status;
+ break;
+ }
+
+ case SensorType::GAME_ROTATION_VECTOR: {
+ dst->data[0] = src.payload.get<Event::EventPayload::vec4>().x;
+ dst->data[1] = src.payload.get<Event::EventPayload::vec4>().y;
+ dst->data[2] = src.payload.get<Event::EventPayload::vec4>().z;
+ dst->data[3] = src.payload.get<Event::EventPayload::vec4>().w;
+ break;
+ }
+
+ case SensorType::ROTATION_VECTOR:
+ case SensorType::GEOMAGNETIC_ROTATION_VECTOR: {
+ dst->data[0] = src.payload.get<Event::EventPayload::data>().values[0];
+ dst->data[1] = src.payload.get<Event::EventPayload::data>().values[1];
+ dst->data[2] = src.payload.get<Event::EventPayload::data>().values[2];
+ dst->data[3] = src.payload.get<Event::EventPayload::data>().values[3];
+ dst->data[4] = src.payload.get<Event::EventPayload::data>().values[4];
+ break;
+ }
+
+ case SensorType::MAGNETIC_FIELD_UNCALIBRATED:
+ case SensorType::GYROSCOPE_UNCALIBRATED:
+ case SensorType::ACCELEROMETER_UNCALIBRATED: {
+ dst->uncalibrated_gyro.x_uncalib = src.payload.get<Event::EventPayload::uncal>().x;
+ dst->uncalibrated_gyro.y_uncalib = src.payload.get<Event::EventPayload::uncal>().y;
+ dst->uncalibrated_gyro.z_uncalib = src.payload.get<Event::EventPayload::uncal>().z;
+ dst->uncalibrated_gyro.x_bias = src.payload.get<Event::EventPayload::uncal>().xBias;
+ dst->uncalibrated_gyro.y_bias = src.payload.get<Event::EventPayload::uncal>().yBias;
+ dst->uncalibrated_gyro.z_bias = src.payload.get<Event::EventPayload::uncal>().zBias;
+ break;
+ }
+
+ case SensorType::HINGE_ANGLE:
+ case SensorType::DEVICE_ORIENTATION:
+ case SensorType::LIGHT:
+ case SensorType::PRESSURE:
+ case SensorType::PROXIMITY:
+ case SensorType::RELATIVE_HUMIDITY:
+ case SensorType::AMBIENT_TEMPERATURE:
+ case SensorType::SIGNIFICANT_MOTION:
+ case SensorType::STEP_DETECTOR:
+ case SensorType::TILT_DETECTOR:
+ case SensorType::WAKE_GESTURE:
+ case SensorType::GLANCE_GESTURE:
+ case SensorType::PICK_UP_GESTURE:
+ case SensorType::WRIST_TILT_GESTURE:
+ case SensorType::STATIONARY_DETECT:
+ case SensorType::MOTION_DETECT:
+ case SensorType::HEART_BEAT:
+ case SensorType::LOW_LATENCY_OFFBODY_DETECT: {
+ dst->data[0] = src.payload.get<Event::EventPayload::scalar>();
+ break;
+ }
+
+ case SensorType::STEP_COUNTER: {
+ dst->u64.step_counter = src.payload.get<Event::EventPayload::stepCount>();
+ break;
+ }
+
+ case SensorType::HEART_RATE: {
+ dst->heart_rate.bpm = src.payload.get<Event::EventPayload::heartRate>().bpm;
+ dst->heart_rate.status =
+ (int8_t)src.payload.get<Event::EventPayload::heartRate>().status;
+ break;
+ }
+
+ case SensorType::POSE_6DOF: { // 15 floats
+ for (size_t i = 0; i < 15; ++i) {
+ dst->data[i] = src.payload.get<Event::EventPayload::pose6DOF>().values[i];
+ }
+ break;
+ }
+
+ case SensorType::DYNAMIC_SENSOR_META: {
+ dst->dynamic_sensor_meta.connected =
+ src.payload.get<Event::EventPayload::dynamic>().connected;
+ dst->dynamic_sensor_meta.handle =
+ src.payload.get<Event::EventPayload::dynamic>().sensorHandle;
+ dst->dynamic_sensor_meta.sensor = NULL; // to be filled in later
+
+ memcpy(dst->dynamic_sensor_meta.uuid,
+ src.payload.get<Event::EventPayload::dynamic>().uuid.values.data(), 16);
+
+ break;
+ }
+
+ case SensorType::ADDITIONAL_INFO: {
+ const AdditionalInfo& srcInfo = src.payload.get<Event::EventPayload::additional>();
+
+ additional_info_event_t* dstInfo = &dst->additional_info;
+ dstInfo->type = (int32_t)srcInfo.type;
+ dstInfo->serial = srcInfo.serial;
+
+ switch (srcInfo.payload.getTag()) {
+ case AdditionalInfo::AdditionalInfoPayload::Tag::dataInt32: {
+ const auto& values =
+ srcInfo.payload.get<AdditionalInfo::AdditionalInfoPayload::dataInt32>()
+ .values;
+ CHECK_EQ(values.size() * sizeof(int32_t), sizeof(dstInfo->data_int32));
+ memcpy(dstInfo->data_int32, values.data(), sizeof(dstInfo->data_int32));
+ break;
+ }
+ case AdditionalInfo::AdditionalInfoPayload::Tag::dataFloat: {
+ const auto& values =
+ srcInfo.payload.get<AdditionalInfo::AdditionalInfoPayload::dataFloat>()
+ .values;
+ CHECK_EQ(values.size() * sizeof(float), sizeof(dstInfo->data_float));
+ memcpy(dstInfo->data_float, values.data(), sizeof(dstInfo->data_float));
+ break;
+ }
+ default: {
+ LOG(ERROR) << "Invalid sensor additional info tag: ",
+ (int)srcInfo.payload.getTag();
+ }
+ }
+ break;
+ }
+
+ case SensorType::HEAD_TRACKER: {
+ const auto& ht = src.payload.get<Event::EventPayload::headTracker>();
+ dst->head_tracker.rx = ht.rx;
+ dst->head_tracker.ry = ht.ry;
+ dst->head_tracker.rz = ht.rz;
+ dst->head_tracker.vx = ht.vx;
+ dst->head_tracker.vy = ht.vy;
+ dst->head_tracker.vz = ht.vz;
+ dst->head_tracker.discontinuity_count = ht.discontinuityCount;
+ break;
+ }
+
+ case SensorType::ACCELEROMETER_LIMITED_AXES:
+ case SensorType::GYROSCOPE_LIMITED_AXES:
+ dst->limited_axes_imu.x = src.payload.get<Event::EventPayload::limitedAxesImu>().x;
+ dst->limited_axes_imu.y = src.payload.get<Event::EventPayload::limitedAxesImu>().y;
+ dst->limited_axes_imu.z = src.payload.get<Event::EventPayload::limitedAxesImu>().z;
+ dst->limited_axes_imu.x_supported =
+ src.payload.get<Event::EventPayload::limitedAxesImu>().xSupported;
+ dst->limited_axes_imu.y_supported =
+ src.payload.get<Event::EventPayload::limitedAxesImu>().ySupported;
+ dst->limited_axes_imu.z_supported =
+ src.payload.get<Event::EventPayload::limitedAxesImu>().zSupported;
+ break;
+
+ case SensorType::ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
+ case SensorType::GYROSCOPE_LIMITED_AXES_UNCALIBRATED:
+ dst->limited_axes_imu_uncalibrated.x_uncalib =
+ src.payload.get<Event::EventPayload::limitedAxesImuUncal>().x;
+ dst->limited_axes_imu_uncalibrated.y_uncalib =
+ src.payload.get<Event::EventPayload::limitedAxesImuUncal>().y;
+ dst->limited_axes_imu_uncalibrated.z_uncalib =
+ src.payload.get<Event::EventPayload::limitedAxesImuUncal>().z;
+ dst->limited_axes_imu_uncalibrated.x_bias =
+ src.payload.get<Event::EventPayload::limitedAxesImuUncal>().xBias;
+ dst->limited_axes_imu_uncalibrated.y_bias =
+ src.payload.get<Event::EventPayload::limitedAxesImuUncal>().yBias;
+ dst->limited_axes_imu_uncalibrated.z_bias =
+ src.payload.get<Event::EventPayload::limitedAxesImuUncal>().zBias;
+ dst->limited_axes_imu_uncalibrated.x_supported =
+ src.payload.get<Event::EventPayload::limitedAxesImuUncal>().xSupported;
+ dst->limited_axes_imu_uncalibrated.y_supported =
+ src.payload.get<Event::EventPayload::limitedAxesImuUncal>().ySupported;
+ dst->limited_axes_imu_uncalibrated.z_supported =
+ src.payload.get<Event::EventPayload::limitedAxesImuUncal>().zSupported;
+ break;
+
+ case SensorType::HEADING:
+ dst->heading.heading = src.payload.get<Event::EventPayload::heading>().heading;
+ dst->heading.accuracy = src.payload.get<Event::EventPayload::heading>().accuracy;
+ break;
+
+ default: {
+ CHECK_GE((int32_t)src.sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE);
+
+ memcpy(dst->data, src.payload.get<Event::EventPayload::data>().values.data(),
+ 16 * sizeof(float));
+ break;
+ }
+ }
+}
+
+void convertFromSensorEvent(const sensors_event_t& src, Event* dst) {
+ *dst = {
+ .timestamp = src.timestamp,
+ .sensorHandle = src.sensor,
+ .sensorType = (SensorType)src.type,
+ };
+
+ switch (dst->sensorType) {
+ case SensorType::META_DATA: {
+ Event::EventPayload::MetaData meta;
+ meta.what = (Event::EventPayload::MetaData::MetaDataEventType)src.meta_data.what;
+ // Legacy HALs contain the handle reference in the meta data field.
+ // Copy that over to the handle of the event. In legacy HALs this
+ // field was expected to be 0.
+ dst->sensorHandle = src.meta_data.sensor;
+ dst->payload.set<Event::EventPayload::Tag::meta>(meta);
+ break;
+ }
+
+ case SensorType::ACCELEROMETER:
+ case SensorType::MAGNETIC_FIELD:
+ case SensorType::ORIENTATION:
+ case SensorType::GYROSCOPE:
+ case SensorType::GRAVITY:
+ case SensorType::LINEAR_ACCELERATION: {
+ Event::EventPayload::Vec3 vec3;
+ vec3.x = src.acceleration.x;
+ vec3.y = src.acceleration.y;
+ vec3.z = src.acceleration.z;
+ vec3.status = (SensorStatus)src.acceleration.status;
+ dst->payload.set<Event::EventPayload::Tag::vec3>(vec3);
+ break;
+ }
+
+ case SensorType::GAME_ROTATION_VECTOR: {
+ Event::EventPayload::Vec4 vec4;
+ vec4.x = src.data[0];
+ vec4.y = src.data[1];
+ vec4.z = src.data[2];
+ vec4.w = src.data[3];
+ dst->payload.set<Event::EventPayload::Tag::vec4>(vec4);
+ break;
+ }
+
+ case SensorType::ROTATION_VECTOR:
+ case SensorType::GEOMAGNETIC_ROTATION_VECTOR: {
+ Event::EventPayload::Data data;
+ memcpy(data.values.data(), src.data, 5 * sizeof(float));
+ dst->payload.set<Event::EventPayload::Tag::data>(data);
+ break;
+ }
+
+ case SensorType::MAGNETIC_FIELD_UNCALIBRATED:
+ case SensorType::GYROSCOPE_UNCALIBRATED:
+ case SensorType::ACCELEROMETER_UNCALIBRATED: {
+ Event::EventPayload::Uncal uncal;
+ uncal.x = src.uncalibrated_gyro.x_uncalib;
+ uncal.y = src.uncalibrated_gyro.y_uncalib;
+ uncal.z = src.uncalibrated_gyro.z_uncalib;
+ uncal.xBias = src.uncalibrated_gyro.x_bias;
+ uncal.yBias = src.uncalibrated_gyro.y_bias;
+ uncal.zBias = src.uncalibrated_gyro.z_bias;
+ dst->payload.set<Event::EventPayload::Tag::uncal>(uncal);
+ break;
+ }
+
+ case SensorType::DEVICE_ORIENTATION:
+ case SensorType::LIGHT:
+ case SensorType::PRESSURE:
+ case SensorType::PROXIMITY:
+ case SensorType::RELATIVE_HUMIDITY:
+ case SensorType::AMBIENT_TEMPERATURE:
+ case SensorType::SIGNIFICANT_MOTION:
+ case SensorType::STEP_DETECTOR:
+ case SensorType::TILT_DETECTOR:
+ case SensorType::WAKE_GESTURE:
+ case SensorType::GLANCE_GESTURE:
+ case SensorType::PICK_UP_GESTURE:
+ case SensorType::WRIST_TILT_GESTURE:
+ case SensorType::STATIONARY_DETECT:
+ case SensorType::MOTION_DETECT:
+ case SensorType::HEART_BEAT:
+ case SensorType::LOW_LATENCY_OFFBODY_DETECT:
+ case SensorType::HINGE_ANGLE: {
+ dst->payload.set<Event::EventPayload::Tag::scalar>((float)src.data[0]);
+ break;
+ }
+
+ case SensorType::STEP_COUNTER: {
+ dst->payload.set<Event::EventPayload::Tag::stepCount>(src.u64.step_counter);
+ break;
+ }
+
+ case SensorType::HEART_RATE: {
+ Event::EventPayload::HeartRate heartRate;
+ heartRate.bpm = src.heart_rate.bpm;
+ heartRate.status = (SensorStatus)src.heart_rate.status;
+ dst->payload.set<Event::EventPayload::Tag::heartRate>(heartRate);
+ break;
+ }
+
+ case SensorType::POSE_6DOF: { // 15 floats
+ Event::EventPayload::Pose6Dof pose6DOF;
+ for (size_t i = 0; i < 15; ++i) {
+ pose6DOF.values[i] = src.data[i];
+ }
+ dst->payload.set<Event::EventPayload::Tag::pose6DOF>(pose6DOF);
+ break;
+ }
+
+ case SensorType::DYNAMIC_SENSOR_META: {
+ DynamicSensorInfo dynamic;
+ dynamic.connected = src.dynamic_sensor_meta.connected;
+ dynamic.sensorHandle = src.dynamic_sensor_meta.handle;
+
+ memcpy(dynamic.uuid.values.data(), src.dynamic_sensor_meta.uuid, 16);
+ dst->payload.set<Event::EventPayload::Tag::dynamic>(dynamic);
+ break;
+ }
+
+ case SensorType::ADDITIONAL_INFO: {
+ AdditionalInfo info;
+ const additional_info_event_t& srcInfo = src.additional_info;
+ info.type = (AdditionalInfo::AdditionalInfoType)srcInfo.type;
+ info.serial = srcInfo.serial;
+
+ AdditionalInfo::AdditionalInfoPayload::Int32Values data;
+ CHECK_EQ(data.values.size() * sizeof(int32_t), sizeof(srcInfo.data_int32));
+ memcpy(data.values.data(), srcInfo.data_int32, sizeof(srcInfo.data_int32));
+ info.payload.set<AdditionalInfo::AdditionalInfoPayload::Tag::dataInt32>(data);
+
+ dst->payload.set<Event::EventPayload::Tag::additional>(info);
+ break;
+ }
+
+ case SensorType::HEAD_TRACKER: {
+ Event::EventPayload::HeadTracker headTracker;
+ headTracker.rx = src.head_tracker.rx;
+ headTracker.ry = src.head_tracker.ry;
+ headTracker.rz = src.head_tracker.rz;
+ headTracker.vx = src.head_tracker.vx;
+ headTracker.vy = src.head_tracker.vy;
+ headTracker.vz = src.head_tracker.vz;
+ headTracker.discontinuityCount = src.head_tracker.discontinuity_count;
+
+ dst->payload.set<Event::EventPayload::Tag::headTracker>(headTracker);
+ break;
+ }
+
+ case SensorType::ACCELEROMETER_LIMITED_AXES:
+ case SensorType::GYROSCOPE_LIMITED_AXES: {
+ Event::EventPayload::LimitedAxesImu limitedAxesImu;
+ limitedAxesImu.x = src.limited_axes_imu.x;
+ limitedAxesImu.y = src.limited_axes_imu.y;
+ limitedAxesImu.z = src.limited_axes_imu.z;
+ limitedAxesImu.xSupported = src.limited_axes_imu.x_supported;
+ limitedAxesImu.ySupported = src.limited_axes_imu.y_supported;
+ limitedAxesImu.zSupported = src.limited_axes_imu.z_supported;
+ dst->payload.set<Event::EventPayload::Tag::limitedAxesImu>(limitedAxesImu);
+ break;
+ }
+
+ case SensorType::ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
+ case SensorType::GYROSCOPE_LIMITED_AXES_UNCALIBRATED: {
+ Event::EventPayload::LimitedAxesImuUncal limitedAxesImuUncal;
+ limitedAxesImuUncal.x = src.limited_axes_imu_uncalibrated.x_uncalib;
+ limitedAxesImuUncal.y = src.limited_axes_imu_uncalibrated.y_uncalib;
+ limitedAxesImuUncal.z = src.limited_axes_imu_uncalibrated.z_uncalib;
+ limitedAxesImuUncal.xBias = src.limited_axes_imu_uncalibrated.x_bias;
+ limitedAxesImuUncal.yBias = src.limited_axes_imu_uncalibrated.y_bias;
+ limitedAxesImuUncal.yBias = src.limited_axes_imu_uncalibrated.y_bias;
+ limitedAxesImuUncal.zBias = src.limited_axes_imu_uncalibrated.z_bias;
+ limitedAxesImuUncal.xSupported = src.limited_axes_imu_uncalibrated.x_supported;
+ limitedAxesImuUncal.ySupported = src.limited_axes_imu_uncalibrated.y_supported;
+ limitedAxesImuUncal.zSupported = src.limited_axes_imu_uncalibrated.z_supported;
+ dst->payload.set<Event::EventPayload::Tag::limitedAxesImuUncal>(limitedAxesImuUncal);
+ break;
+ }
+
+ case SensorType::HEADING: {
+ Event::EventPayload::Heading heading;
+ heading.heading = src.heading.heading;
+ heading.accuracy = src.heading.accuracy;
+ dst->payload.set<Event::EventPayload::heading>(heading);
+ break;
+ }
+
+ default: {
+ CHECK_GE((int32_t)dst->sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE);
+
+ Event::EventPayload::Data data;
+ memcpy(data.values.data(), src.data, 16 * sizeof(float));
+ dst->payload.set<Event::EventPayload::Tag::data>(data);
+ break;
+ }
+ }
+}
+
+void convertFromASensorEvent(const ASensorEvent& src, Event* dst) {
+ convertFromSensorEvent(common::convertASensorEvent(src), dst);
+}
+
+} // namespace implementation
+} // namespace sensors
+} // namespace hardware
+} // namespace android
diff --git a/sensors/aidl/convert/include/aidl/sensors/convert.h b/sensors/aidl/convert/include/aidl/sensors/convert.h
new file mode 100644
index 0000000..44504fe
--- /dev/null
+++ b/sensors/aidl/convert/include/aidl/sensors/convert.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/sensors/ISensors.h>
+#include <hardware/sensors.h>
+#include <sensors/common_convert.h>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+
+status_t convertToStatus(ndk::ScopedAStatus status);
+void convertToSensor(const aidl::android::hardware::sensors::SensorInfo& src, sensor_t* dst);
+void convertToSensorEvent(const aidl::android::hardware::sensors::Event& src, sensors_event_t* dst);
+void convertFromSensorEvent(const sensors_event_t& src,
+ aidl::android::hardware::sensors::Event* dst);
+void convertFromASensorEvent(const ASensorEvent& src, aidl::android::hardware::sensors::Event* dst);
+
+} // namespace implementation
+} // namespace sensors
+} // namespace hardware
+} // namespace android
diff --git a/sensors/aidl/default/Sensor.cpp b/sensors/aidl/default/Sensor.cpp
index 62193d6..3bdd8b6 100644
--- a/sensors/aidl/default/Sensor.cpp
+++ b/sensors/aidl/default/Sensor.cpp
@@ -223,7 +223,7 @@
EventPayload::Vec3 vec3 = {
.x = 0,
.y = 0,
- .z = -9.8,
+ .z = 9.8,
.status = SensorStatus::ACCURACY_HIGH,
};
payload.set<EventPayload::Tag::vec3>(vec3);
diff --git a/sensors/common/convert/Android.bp b/sensors/common/convert/Android.bp
new file mode 100644
index 0000000..230665e
--- /dev/null
+++ b/sensors/common/convert/Android.bp
@@ -0,0 +1,42 @@
+// 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: ["Android-Apache-2.0"],
+}
+
+cc_library {
+ name: "sensors_common_convert",
+ srcs: [
+ "convert.cpp",
+ ],
+ vendor_available: true,
+ host_supported: true,
+ local_include_dirs: ["include"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ shared_libs: [
+ "libhardware",
+ ],
+ header_libs: [
+ "libandroid_sensor_headers",
+ ],
+
+ export_include_dirs: ["include"],
+ export_header_lib_headers: [
+ "libandroid_sensor_headers",
+ ],
+}
diff --git a/sensors/common/convert/convert.cpp b/sensors/common/convert/convert.cpp
new file mode 100644
index 0000000..27de32c
--- /dev/null
+++ b/sensors/common/convert/convert.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sensors/common_convert.h>
+#include <cstring>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+namespace common {
+
+sensors_event_t convertASensorEvent(const ASensorEvent& src) {
+ // Attempt to ensure these types are compatible.
+ static_assert(sizeof(sensors_event_t) == sizeof(ASensorEvent));
+ static_assert(offsetof(sensors_event_t, timestamp) == offsetof(ASensorEvent, timestamp));
+ static_assert(offsetof(sensors_event_t, flags) == offsetof(ASensorEvent, flags));
+
+ // TODO(b/259711109) Follow up work to handle this in a safer way.
+ return *reinterpret_cast<const sensors_event_t*>(&src);
+}
+
+} // namespace common
+} // namespace implementation
+} // namespace sensors
+} // namespace hardware
+} // namespace android
diff --git a/sensors/common/convert/include/sensors/common_convert.h b/sensors/common/convert/include/sensors/common_convert.h
new file mode 100644
index 0000000..a281369
--- /dev/null
+++ b/sensors/common/convert/include/sensors/common_convert.h
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android/sensor.h>
+#include <hardware/sensors.h>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+namespace common {
+
+sensors_event_t convertASensorEvent(const ASensorEvent& aEvent);
+
+} // namespace common
+} // namespace implementation
+} // namespace sensors
+} // namespace hardware
+} // namespace android
diff --git a/sensors/common/default/2.X/Sensor.cpp b/sensors/common/default/2.X/Sensor.cpp
index fd701fd..2c1cdfb 100644
--- a/sensors/common/default/2.X/Sensor.cpp
+++ b/sensors/common/default/2.X/Sensor.cpp
@@ -218,7 +218,7 @@
void AccelSensor::readEventPayload(EventPayload& payload) {
payload.vec3.x = 0;
payload.vec3.y = 0;
- payload.vec3.z = -9.8;
+ payload.vec3.z = 9.8;
payload.vec3.status = SensorStatus::ACCURACY_HIGH;
}
diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
index f5745c5..a0bb67a 100644
--- a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
+++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
@@ -237,7 +237,7 @@
event.timestamp = ::android::elapsedRealtimeNano();
event.u.vec3.x = 0;
event.u.vec3.y = 0;
- event.u.vec3.z = -9.815;
+ event.u.vec3.z = 9.815;
event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
events.push_back(event);
return events;
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortInfo.aidl b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortInfo.aidl
index a5e3a2a..25c3be1 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortInfo.aidl
+++ b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HdmiPortInfo.aidl
@@ -38,5 +38,6 @@
int portId;
boolean cecSupported;
boolean arcSupported;
+ boolean eArcSupported;
int physicalAddress;
}
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortInfo.aidl b/tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortInfo.aidl
index 1d6f27d..2e2c858 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortInfo.aidl
+++ b/tv/hdmi/aidl/android/hardware/tv/hdmi/HdmiPortInfo.aidl
@@ -27,6 +27,7 @@
int portId; // Should start from 1 which corresponds to HDMI "port 1".
boolean cecSupported;
boolean arcSupported;
+ boolean eArcSupported;
// The physical address of the device connected to this port, valid range is 0x0000 to 0xFFFF
// (ref Sec 8.7.2 of HDMI 1.4b).
int physicalAddress;
diff --git a/tv/hdmi/aidl/default/HdmiMock.cpp b/tv/hdmi/aidl/default/HdmiMock.cpp
index 0cf5118..bbc4705 100644
--- a/tv/hdmi/aidl/default/HdmiMock.cpp
+++ b/tv/hdmi/aidl/default/HdmiMock.cpp
@@ -166,6 +166,7 @@
.portId = static_cast<uint32_t>(1),
.cecSupported = true,
.arcSupported = false,
+ .eArcSupported = false,
.physicalAddress = mPhysicalAddress};
mPortConnectionStatus[0] = false;
mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
diff --git a/tv/tuner/OWNERS b/tv/tuner/OWNERS
new file mode 100644
index 0000000..83e090d
--- /dev/null
+++ b/tv/tuner/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 136752
+
+quxiangfang@google.com
+shubang@google.com
+hgchen@google.com
+raychin@google.com
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
index 0ff2da9..5d1d215 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
@@ -47,4 +47,5 @@
void setLna(in boolean bEnable);
void setMaxNumberOfFrontends(in android.hardware.tv.tuner.FrontendType frontendType, in int maxNumber);
int getMaxNumberOfFrontends(in android.hardware.tv.tuner.FrontendType frontendType);
+ boolean isLnaSupported();
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
index 03def33..4a0b7a2 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
@@ -125,6 +125,9 @@
/**
* Enable or Disable Low Noise Amplifier (LNA).
*
+ * If the device doesn't support LNA, the HAL implement should set {@link Result#UNAVAILABLE}
+ * to EX_SERVICE_SPECIFIC as the service specific error.
+ *
* @param bEnable true if activate LNA module; false if deactivate LNA
*/
void setLna(in boolean bEnable);
@@ -148,4 +151,11 @@
* @return the maximum usable number of the queried frontend type.
*/
int getMaxNumberOfFrontends(in FrontendType frontendType);
+
+ /**
+ * Is Low Noise Amplifier (LNA) supported.
+ *
+ * @return true if supported, otherwise false
+ */
+ boolean isLnaSupported();
}
diff --git a/tv/tuner/aidl/default/Tuner.cpp b/tv/tuner/aidl/default/Tuner.cpp
index 591f936..8c715a0 100644
--- a/tv/tuner/aidl/default/Tuner.cpp
+++ b/tv/tuner/aidl/default/Tuner.cpp
@@ -204,6 +204,13 @@
return ::ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus Tuner::isLnaSupported(bool* _aidl_return) {
+ ALOGV("%s", __FUNCTION__);
+
+ *_aidl_return = true;
+ return ::ndk::ScopedAStatus::ok();
+}
+
binder_status_t Tuner::dump(int fd, const char** args, uint32_t numArgs) {
ALOGV("%s", __FUNCTION__);
{
diff --git a/tv/tuner/aidl/default/Tuner.h b/tv/tuner/aidl/default/Tuner.h
index ad73003..a77c930 100644
--- a/tv/tuner/aidl/default/Tuner.h
+++ b/tv/tuner/aidl/default/Tuner.h
@@ -61,6 +61,7 @@
int32_t in_maxNumber) override;
::ndk::ScopedAStatus getMaxNumberOfFrontends(FrontendType in_frontendType,
int32_t* _aidl_return) override;
+ ::ndk::ScopedAStatus isLnaSupported(bool* _aidl_return) override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ComplianceWarning.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ComplianceWarning.aidl
new file mode 100644
index 0000000..8b67070
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ComplianceWarning.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.usb;
+@Backing(type="int") @VintfStability
+enum ComplianceWarning {
+ OTHER = 1,
+ DEBUG_ACCESSORY = 2,
+ BC_1_2 = 3,
+ MISSING_RP = 4,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
index f866c1e..859f526 100644
--- a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
@@ -41,5 +41,5 @@
oneway void setCallback(in android.hardware.usb.IUsbCallback callback);
oneway void switchRole(in String portName, in android.hardware.usb.PortRole role, long transactionId);
oneway void limitPowerTransfer(in String portName, boolean limit, long transactionId);
- oneway void resetUsbPort(in String portName,long transactionId);
+ oneway void resetUsbPort(in String portName, long transactionId);
}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
index dfd99fb..b0b7552 100644
--- a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
@@ -50,4 +50,6 @@
android.hardware.usb.UsbDataStatus[] usbDataStatus;
boolean powerTransferLimited;
android.hardware.usb.PowerBrickStatus powerBrickStatus;
+ boolean supportsComplianceWarnings = false;
+ android.hardware.usb.ComplianceWarning[] complianceWarnings = {};
}
diff --git a/usb/aidl/android/hardware/usb/ComplianceWarning.aidl b/usb/aidl/android/hardware/usb/ComplianceWarning.aidl
new file mode 100644
index 0000000..4c18a31
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/ComplianceWarning.aidl
@@ -0,0 +1,59 @@
+/*
+ * 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 android.hardware.usb;
+
+@VintfStability
+@Backing(type="int")
+/**
+ * Indicates the potential non-compliance reasons for the
+ * connected USB Type-C port partner which could be a power
+ * source, accessory or cable. Applicable for USB-C receptacles
+ * in Android devices.
+ */
+enum ComplianceWarning {
+ /**
+ * Used to indicate Type-C sources/cables/accessories/ports
+ * whose issue is not listed below but do not meet
+ * specification requirements from including but not limited to
+ * USB Type-C Cable and Connector Specification, Universal Serial Bus
+ * Power Delivery Specification, and Universal Serial Bus
+ * 1.x/2.0/3.x/4.0.
+ */
+ OTHER = 1,
+ /**
+ * Used to indicate Type-C port partner
+ * (cable/accessory/source) that identifies itself as debug
+ * accessory source as defined in USB Type-C Cable and
+ * Connector Specification. However, the specification
+ * states that this is meant for debug only and shall not
+ * be used for with commercial products.
+ */
+ DEBUG_ACCESSORY = 2,
+ /**
+ * Used to indicate Type-C port partner that does not
+ * identify itself as one of the charging port types
+ * (SDP/CDP/DCP etc) as defined by Battery Charging v1.2
+ * Specification.
+ */
+ BC_1_2 = 3,
+ /**
+ * Used to indicate Type-C sources/cables that are missing
+ * pull up resistors on the CC pins as required by USB
+ * Type-C Cable and Connector Specification.
+ */
+ MISSING_RP = 4,
+}
diff --git a/usb/aidl/android/hardware/usb/PortStatus.aidl b/usb/aidl/android/hardware/usb/PortStatus.aidl
index 51bee71..d7e61ec 100644
--- a/usb/aidl/android/hardware/usb/PortStatus.aidl
+++ b/usb/aidl/android/hardware/usb/PortStatus.aidl
@@ -19,6 +19,7 @@
import android.hardware.usb.ContaminantDetectionStatus;
import android.hardware.usb.ContaminantProtectionMode;
import android.hardware.usb.ContaminantProtectionStatus;
+import android.hardware.usb.ComplianceWarning;
import android.hardware.usb.PortDataRole;
import android.hardware.usb.PortMode;
import android.hardware.usb.PortPowerRole;
@@ -115,4 +116,15 @@
* Denotes whether Power brick is connected.
*/
PowerBrickStatus powerBrickStatus;
+ /**
+ * True if the hal implementation can support identifying
+ * non compliant USB power source/cable/accessory. False other
+ * otherwise.
+ */
+ boolean supportsComplianceWarnings = false;
+ /**
+ * List of reasons as to why the attached USB
+ * power source/cable/accessory is non compliant.
+ */
+ ComplianceWarning[] complianceWarnings = {};
}
diff --git a/usb/aidl/default/Android.bp b/usb/aidl/default/Android.bp
index ad331f9..472e732 100644
--- a/usb/aidl/default/Android.bp
+++ b/usb/aidl/default/Android.bp
@@ -34,7 +34,7 @@
"Usb.cpp",
],
shared_libs: [
- "android.hardware.usb-V1-ndk",
+ "android.hardware.usb-V2-ndk",
"libbase",
"libbinder_ndk",
"libcutils",
diff --git a/usb/aidl/default/Usb.cpp b/usb/aidl/default/Usb.cpp
index 7e738c4..dd12da0 100644
--- a/usb/aidl/default/Usb.cpp
+++ b/usb/aidl/default/Usb.cpp
@@ -123,6 +123,15 @@
return Status::SUCCESS;
}
+Status queryNonCompliantChargerStatus(std::vector<PortStatus> *currentPortStatus) {
+ string reasons, path;
+
+ for (int i = 0; i < currentPortStatus->size(); i++) {
+ (*currentPortStatus)[i].supportsComplianceWarnings = false;
+ }
+ return Status::SUCCESS;
+}
+
string appendRoleNodeHelper(const string &portName, PortRole::Tag tag) {
string node(kTypecPath + portName);
@@ -527,6 +536,7 @@
pthread_mutex_lock(&usb->mLock);
status = getPortStatusHelper(currentPortStatus);
queryMoistureDetectionStatus(currentPortStatus);
+ queryNonCompliantChargerStatus(currentPortStatus);
if (usb->mCallback != NULL) {
ScopedAStatus ret = usb->mCallback->notifyPortStatusChange(*currentPortStatus,
status);
diff --git a/usb/aidl/default/android.hardware.usb-service.example.xml b/usb/aidl/default/android.hardware.usb-service.example.xml
index 6088194..c3f07f5 100644
--- a/usb/aidl/default/android.hardware.usb-service.example.xml
+++ b/usb/aidl/default/android.hardware.usb-service.example.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.usb</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IUsb</name>
<instance>default</instance>
diff --git a/usb/aidl/vts/Android.bp b/usb/aidl/vts/Android.bp
index 00a7c93..d0e0eec 100644
--- a/usb/aidl/vts/Android.bp
+++ b/usb/aidl/vts/Android.bp
@@ -34,7 +34,7 @@
"libbinder_ndk",
],
static_libs: [
- "android.hardware.usb-V1-ndk",
+ "android.hardware.usb-V2-ndk",
],
test_suites: [
"general-tests",
diff --git a/usb/aidl/vts/VtsAidlUsbTargetTest.cpp b/usb/aidl/vts/VtsAidlUsbTargetTest.cpp
index ea2f985..c4ec8a4 100644
--- a/usb/aidl/vts/VtsAidlUsbTargetTest.cpp
+++ b/usb/aidl/vts/VtsAidlUsbTargetTest.cpp
@@ -43,6 +43,7 @@
#define TIMEOUT_PERIOD 10
using ::aidl::android::hardware::usb::BnUsbCallback;
+using ::aidl::android::hardware::usb::ComplianceWarning;
using ::aidl::android::hardware::usb::IUsb;
using ::aidl::android::hardware::usb::IUsbCallback;
using ::aidl::android::hardware::usb::PortDataRole;
@@ -560,6 +561,53 @@
ALOGI("UsbAidlTest resetUsbPort end");
}
+/*
+ * Test charger compliance warning
+ * The test asserts that complianceWarnings is
+ * empty when the feature is not supported. i.e.
+ * supportsComplianceWarning is false.
+ */
+TEST_P(UsbAidlTest, nonCompliantChargerStatus) {
+ ALOGI("UsbAidlTest nonCompliantChargerStatus start");
+ int64_t transactionId = rand() % 10000;
+ const auto& ret = usb->queryPortStatus(transactionId);
+ ASSERT_TRUE(ret.isOk());
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(2, usb_last_cookie);
+ EXPECT_EQ(transactionId, last_transactionId);
+
+ if (!usb_last_port_status.supportsComplianceWarnings) {
+ EXPECT_TRUE(usb_last_port_status.complianceWarnings.empty());
+ }
+
+ ALOGI("UsbAidlTest nonCompliantChargerStatus end");
+}
+
+/*
+ * Test charger compliance warning values
+ * The test asserts that complianceWarning values
+ * are valid.
+ */
+TEST_P(UsbAidlTest, nonCompliantChargerValues) {
+ ALOGI("UsbAidlTest nonCompliantChargerValues start");
+ int64_t transactionId = rand() % 10000;
+ const auto& ret = usb->queryPortStatus(transactionId);
+ ASSERT_TRUE(ret.isOk());
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(2, usb_last_cookie);
+ EXPECT_EQ(transactionId, last_transactionId);
+
+ // Current compliance values range from [1, 4]
+ if (usb_last_port_status.supportsComplianceWarnings) {
+ for (auto warning : usb_last_port_status.complianceWarnings) {
+ EXPECT_TRUE((int)warning >= (int)ComplianceWarning::OTHER);
+ EXPECT_TRUE((int)warning <= (int)ComplianceWarning::MISSING_RP);
+ }
+ }
+
+ ALOGI("UsbAidlTest nonCompliantChargerValues end");
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UsbAidlTest);
INSTANTIATE_TEST_SUITE_P(
PerInstance, UsbAidlTest,
diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp
index 86ef027..c5936e3 100644
--- a/vibrator/aidl/Android.bp
+++ b/vibrator/aidl/Android.bp
@@ -17,7 +17,7 @@
stability: "vintf",
backend: {
java: {
- sdk_version: "module_current",
+ sdk_version: "system_current",
},
},
versions: [
diff --git a/vibrator/aidl/default/example_vendor_java_client/Android.bp b/vibrator/aidl/default/example_vendor_java_client/Android.bp
new file mode 100644
index 0000000..f615cb1
--- /dev/null
+++ b/vibrator/aidl/default/example_vendor_java_client/Android.bp
@@ -0,0 +1,34 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library {
+ name: "libexample_vib_getter",
+ srcs: ["getter.cpp"],
+ vendor: true,
+ shared_libs: [
+ "liblog",
+ "libbinder_ndk",
+ ],
+ header_libs: ["jni_headers"],
+ stl: "c++_shared",
+ visibility: [":__subpackages__"],
+}
+
+android_app {
+ name: "ExampleVibratorJavaVendorClient",
+ privileged: true,
+ vendor: true,
+ static_libs: ["android.hardware.vibrator-V1-java"],
+ jni_libs: ["libexample_vib_getter"],
+ jarjar_rules: "jarjar.txt",
+ stl: "c++_shared",
+ srcs: ["example/vib/MyActivity.java"],
+ sdk_version: "system_current",
+ visibility: [":__subpackages__"],
+}
diff --git a/vibrator/aidl/default/example_vendor_java_client/AndroidManifest.xml b/vibrator/aidl/default/example_vendor_java_client/AndroidManifest.xml
new file mode 100644
index 0000000..0561066
--- /dev/null
+++ b/vibrator/aidl/default/example_vendor_java_client/AndroidManifest.xml
@@ -0,0 +1,7 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="example.vib">
+ <application>
+ <activity android:name=".MyActivity"/>
+ </application>
+</manifest>
diff --git a/vibrator/aidl/default/example_vendor_java_client/example/vib/MyActivity.java b/vibrator/aidl/default/example_vendor_java_client/example/vib/MyActivity.java
new file mode 100644
index 0000000..aadce8e
--- /dev/null
+++ b/vibrator/aidl/default/example_vendor_java_client/example/vib/MyActivity.java
@@ -0,0 +1,54 @@
+/*
+ * 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 example.vib;
+
+import android.app.Activity;
+import android.hardware.vibrator.IVibrator;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+public class MyActivity extends Activity {
+ private static native IBinder gimme(String name);
+
+ @Override
+ public void onCreate(Bundle b) {
+ super.onCreate(b);
+ System.loadLibrary("example_vib_getter");
+
+ // There is no API to get ahold of a Stable AIDL service from a vendor app
+ // in Java. This is because this is not the recommended way to get ahold
+ // of functionality in Android. The Android API Council recommendation is to
+ // implement uses-library APIs in the system/system_ext partition which add
+ // new APIs. AIDL as an API in Java is not recommended or supported way to
+ // communicate by apps - the recommendation is to use Java APIs. However,
+ // there also exists a large number of vendor apps which are coupled with
+ // hardware-specific code, and are therefore on the vendor partition. A
+ // large number of these use HIDL, and this is how they can continue to
+ // use that structure with AIDL.
+ IVibrator v =
+ IVibrator.Stub.asInterface(gimme("android.hardware.vibrator.IVibrator/default"));
+
+ try {
+ v.on(100 /*ms*/, null /*cb*/);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+
+ finish();
+ }
+}
diff --git a/vibrator/aidl/default/example_vendor_java_client/getter.cpp b/vibrator/aidl/default/example_vendor_java_client/getter.cpp
new file mode 100644
index 0000000..6115445
--- /dev/null
+++ b/vibrator/aidl/default/example_vendor_java_client/getter.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_ibinder_jni.h>
+#include <android/binder_manager.h>
+#include <jni.h>
+#include <log/log.h>
+
+extern "C" JNIEXPORT jobject JNICALL
+Java_example_vib_MyActivity_gimme__Ljava_lang_String_2(JNIEnv* env, jclass /**/, jstring str) {
+ ALOGI("%s", __func__);
+
+ // Best practice is probably libnativehelper ScopedUtfChars or
+ // libbase ScopeGuard (for platform code), but this is with minimal
+ // dependencies.
+ const char* name = env->GetStringUTFChars(str, nullptr);
+
+ ALOGI("example vib gimme %s", name);
+
+ jobject jbinder = nullptr;
+
+ // Java does not have vendor variants. It's only safe to pass a service when
+ // 'vendor: true' if it is @VintfStability.
+ if (AServiceManager_isDeclared(name)) {
+ ndk::SpAIBinder binder = ndk::SpAIBinder(AServiceManager_waitForService(name));
+ jbinder = AIBinder_toJavaBinder(env, binder.get());
+ } else {
+ ALOGI("not declared");
+ }
+
+ env->ReleaseStringUTFChars(str, name);
+
+ return jbinder;
+}
diff --git a/vibrator/aidl/default/example_vendor_java_client/jarjar.txt b/vibrator/aidl/default/example_vendor_java_client/jarjar.txt
new file mode 100644
index 0000000..e7613a0
--- /dev/null
+++ b/vibrator/aidl/default/example_vendor_java_client/jarjar.txt
@@ -0,0 +1,2 @@
+rule android.hardware.** example.vib.ah.@1
+
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 25a09b4..c7dd584 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -63,4 +63,5 @@
oneway void onWpsEventSuccess();
oneway void onQosPolicyReset();
oneway void onQosPolicyRequest(in int qosPolicyRequestId, in android.hardware.wifi.supplicant.QosPolicyData[] qosPolicyData);
+ oneway void onStateChangedWithAkm(in android.hardware.wifi.supplicant.StaIfaceCallbackState newState, in byte[] bssid, in int id, in byte[] ssid, in boolean filsHlpSent, in android.hardware.wifi.supplicant.KeyMgmtMask keyMgmtMask);
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
index 0b3cb81..0bdec34 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
@@ -127,6 +127,7 @@
void setWepKey(in int keyIdx, in byte[] wepKey);
void setWepTxKeyIdx(in int keyIdx);
void setRoamingConsortiumSelection(in byte[] selectedRcoi);
+ void setMinimumTlsVersionEapPhase1Param(android.hardware.wifi.supplicant.TlsVersion tlsVersion);
const int SSID_MAX_LEN_IN_BYTES = 32;
const int PSK_PASSPHRASE_MIN_LEN_IN_BYTES = 8;
const int PSK_PASSPHRASE_MAX_LEN_IN_BYTES = 63;
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/TlsVersion.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/TlsVersion.aidl
new file mode 100644
index 0000000..22a374f
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/TlsVersion.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum TlsVersion {
+ TLS_V1_0 = 0,
+ TLS_V1_1 = 1,
+ TLS_V1_2 = 2,
+ TLS_V1_3 = 3,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
index 9a0a924..32e1510 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
@@ -39,4 +39,6 @@
SAE_PK = 4,
WFD_R2 = 8,
TRUST_ON_FIRST_USE = 16,
+ SET_TLS_MINIMUM_VERSION = 32,
+ TLS_V1_3 = 64,
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 0730a8c..c7961fa 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -27,6 +27,7 @@
import android.hardware.wifi.supplicant.DppFailureCode;
import android.hardware.wifi.supplicant.DppProgressCode;
import android.hardware.wifi.supplicant.Hs20AnqpData;
+import android.hardware.wifi.supplicant.KeyMgmtMask;
import android.hardware.wifi.supplicant.OsuMethod;
import android.hardware.wifi.supplicant.QosPolicyData;
import android.hardware.wifi.supplicant.StaIfaceCallbackState;
@@ -252,6 +253,8 @@
* event is triggered by a particular network, the |SupplicantNetworkId|,
* |ssid|, |bssid| parameters must indicate the parameters of the network/AP
* which caused this state transition.
+ * <p>
+ * This callback is deprecated from AIDL v2, newer HAL should call onStateChangedWithAkm().
*
* @param newState New State of the interface. This must be one of the |State|
* values above.
@@ -303,4 +306,27 @@
* @param qosPolicyData QoS policies info requested by the AP.
*/
void onQosPolicyRequest(in int qosPolicyRequestId, in QosPolicyData[] qosPolicyData);
+
+ /**
+ * Used to indicate a state change event on this particular iface. If this
+ * event is triggered by a particular network, the |id|,
+ * |ssid|, |bssid| parameters must indicate the parameters of the network/AP
+ * which caused this state transition.
+ *
+ * @param newState New State of the interface. This must be one of the
+ * |StaIfaceCallbackState| values above.
+ * @param bssid BSSID of the corresponding AP which caused this state
+ * change event. This must be zero'ed if this event is not
+ * specific to a particular network.
+ * @param id ID of the corresponding network which caused this
+ * state change event. This must be invalid (-1) if this
+ * event is not specific to a particular network.
+ * @param ssid SSID of the corresponding network which caused this state
+ * change event. This must be empty if this event is not specific
+ * to a particular network.
+ * @param filsHlpSent Whether FILS HLP IEs were included in this association.
+ * @param keyMgmtMask current used key mgmt mask.
+ */
+ void onStateChangedWithAkm(in StaIfaceCallbackState newState, in byte[] bssid, in int id,
+ in byte[] ssid, in boolean filsHlpSent, in KeyMgmtMask keyMgmtMask);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
index 267f1e8..44512a9 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
@@ -31,6 +31,7 @@
import android.hardware.wifi.supplicant.PairwiseCipherMask;
import android.hardware.wifi.supplicant.ProtoMask;
import android.hardware.wifi.supplicant.SaeH2eMode;
+import android.hardware.wifi.supplicant.TlsVersion;
/**
* Interface exposed by the supplicant for each station mode network
@@ -1118,4 +1119,16 @@
* |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
*/
void setRoamingConsortiumSelection(in byte[] selectedRcoi);
+
+ /**
+ * Set the minimum TLS version for EAP phase1 param.
+ *
+ * @param tlsVersion the TLS version
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ void setMinimumTlsVersionEapPhase1Param(TlsVersion tlsVersion);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/TlsVersion.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/TlsVersion.aidl
new file mode 100644
index 0000000..316e881
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/TlsVersion.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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 android.hardware.wifi.supplicant;
+
+/**
+ * TlsVersion: TLS version.
+ */
+@VintfStability
+@Backing(type="int")
+enum TlsVersion {
+ TLS_V1_0,
+ TLS_V1_1,
+ TLS_V1_2,
+ TLS_V1_3,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
index 08006cf..a9434c4 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
@@ -42,4 +42,12 @@
* Trust On First Use
*/
TRUST_ON_FIRST_USE = 1 << 4,
+ /**
+ * TLS minimum version
+ */
+ SET_TLS_MINIMUM_VERSION = 1 << 5,
+ /**
+ * TLS V1.3
+ */
+ TLS_V1_3 = 1 << 6,
}
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
index 272a427..d57f539 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
@@ -206,6 +206,13 @@
QosPolicyData /* qosPolicyData */>&) override {
return ndk::ScopedAStatus::ok();
}
+ ::ndk::ScopedAStatus onStateChangedWithAkm(
+ ::aidl::android::hardware::wifi::supplicant::StaIfaceCallbackState /* newState */,
+ const std::vector<uint8_t>& /* bssid */, int32_t /* id */,
+ const std::vector<uint8_t>& /* ssid */, bool /* filsHlpSent */,
+ ::aidl::android::hardware::wifi::supplicant::KeyMgmtMask /* keyMgmtMask*/) override {
+ return ndk::ScopedAStatus::ok();
+ }
};
class SupplicantStaIfaceAidlTest : public testing::TestWithParam<std::string> {
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
index b3f70da..e5d976c 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
@@ -19,6 +19,7 @@
#include <aidl/Vintf.h>
#include <aidl/android/hardware/wifi/supplicant/BnSupplicant.h>
#include <aidl/android/hardware/wifi/supplicant/BnSupplicantStaNetworkCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/TlsVersion.h>
#include <android/binder_manager.h>
#include <android/binder_status.h>
#include <binder/IServiceManager.h>
@@ -51,6 +52,7 @@
using aidl::android::hardware::wifi::supplicant::PairwiseCipherMask;
using aidl::android::hardware::wifi::supplicant::ProtoMask;
using aidl::android::hardware::wifi::supplicant::SaeH2eMode;
+using aidl::android::hardware::wifi::supplicant::TlsVersion;
using aidl::android::hardware::wifi::supplicant::TransitionDisableIndication;
using aidl::android::hardware::wifi::supplicant::WpaDriverCapabilitiesMask;
using android::ProcessState;
@@ -791,6 +793,13 @@
EXPECT_TRUE(sta_network_->setRoamingConsortiumSelection(testSelection).isOk());
}
+/*
+ * SetMinimumTlsVersionEapPhase1Param
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetMinimumTlsVersionEapPhase1Param) {
+ EXPECT_TRUE(sta_network_->setMinimumTlsVersionEapPhase1Param(TlsVersion::TLS_V1_3).isOk());
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkAidlTest);
INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaNetworkAidlTest,
testing::ValuesIn(android::getAidlHalInstanceNames(