Add host_supported to sensors AIDL interface am: 9ef0c60a25
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2292599
Change-Id: I59fb1d0dd78f95b79c7276fac80ec0fa6dd61bb1
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/audio/README.md b/audio/README.md
index 3f40d72..1938ad4 100644
--- a/audio/README.md
+++ b/audio/README.md
@@ -2,29 +2,10 @@
Directory structure of the audio HAL related code.
-## Directory Structure for AIDL audio HAL
+Run `common/all-versions/copyHAL.sh` to create a new version of the audio HAL
+based on an existing one.
-The AIDL version is located inside `aidl` directory. The tree below explains
-the role of each subdirectory:
-
-* `aidl_api` — snapshots of the API created each Android release. Every
- release, the current version of the API becomes "frozen" and gets assigned
- the next version number. If the API needs further modifications, they are
- made on the "current" version. After making modifications, run
- `m <package name>-update-api` to update the snapshot of the "current"
- version.
-* `android/hardware/audio/common` — data structures and interfaces shared
- between various HALs: BT HAL, core and effects audio HALs.
-* `android/hardware/audio/core` — data structures and interfaces of the
- core audio HAL.
-* `default` — the default, reference implementation of the audio HAL service.
-* `vts` — VTS tests for the AIDL HAL.
-
-## Directory Structure for HIDL audio HAL
-
-Run `common/all-versions/copyHAL.sh` to create a new version of the HIDL audio
-HAL based on an existing one. Note that this isn't possible since Android T
-release. Android U and above uses AIDL audio HAL.
+## Directory Structure
* `2.0` — version 2.0 of the core HIDL API. Note that `.hal` files
can not be moved into the `core` directory because that would change
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index e16b338..0a92e99 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -109,6 +109,7 @@
defaults: ["aidlaudioeffectservice_defaults"],
shared_libs: [
"libbassboostsw",
+ "libbundleaidl",
"libdynamicsprocessingsw",
"libequalizersw",
"libhapticgeneratorsw",
diff --git a/audio/aidl/default/include/effect-impl/EffectWorker.h b/audio/aidl/default/include/effect-impl/EffectWorker.h
index a297937..6a78eab 100644
--- a/audio/aidl/default/include/effect-impl/EffectWorker.h
+++ b/audio/aidl/default/include/effect-impl/EffectWorker.h
@@ -62,6 +62,7 @@
}
// must implement by each effect implementation
+ // TODO: consider if this interface need adjustment to handle in-place processing
virtual IEffect::Status effectProcessImpl(float* in, float* out, int processSamples) = 0;
private:
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
index 51645c7..27b9169 100644
--- a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
@@ -76,16 +76,60 @@
std::lock_guard lg(mMutex);
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
- mSpecificParam = specific.get<Parameter::Specific::loudnessEnhancer>();
- LOG(DEBUG) << __func__ << " success with: " << specific.toString();
- return ndk::ScopedAStatus::ok();
+ auto& leParam = specific.get<Parameter::Specific::loudnessEnhancer>();
+ auto tag = leParam.getTag();
+
+ switch (tag) {
+ case LoudnessEnhancer::gainMb: {
+ RETURN_IF(mContext->setLeGainMb(leParam.get<LoudnessEnhancer::gainMb>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setGainMbFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "LoudnessEnhancerTagNotSupported");
+ }
+ }
}
ndk::ScopedAStatus LoudnessEnhancerSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
RETURN_IF(Parameter::Id::loudnessEnhancerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
- specific->set<Parameter::Specific::loudnessEnhancer>(mSpecificParam);
+ auto leId = id.get<Parameter::Id::loudnessEnhancerTag>();
+ auto leIdTag = leId.getTag();
+ switch (leIdTag) {
+ case LoudnessEnhancer::Id::commonTag:
+ return getParameterLoudnessEnhancer(leId.get<LoudnessEnhancer::Id::commonTag>(),
+ specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(leIdTag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "LoudnessEnhancerTagNotSupported");
+ }
+}
+
+ndk::ScopedAStatus LoudnessEnhancerSw::getParameterLoudnessEnhancer(
+ const LoudnessEnhancer::Tag& tag, Parameter::Specific* specific) {
+ std::lock_guard lg(mMutex);
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ LoudnessEnhancer leParam;
+ switch (tag) {
+ case LoudnessEnhancer::gainMb: {
+ leParam.set<LoudnessEnhancer::gainMb>(mContext->getLeGainMb());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "LoudnessEnhancerTagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::loudnessEnhancer>(leParam);
return ndk::ScopedAStatus::ok();
}
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
index c0de9c1..478aebc 100644
--- a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
@@ -32,7 +32,16 @@
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
- // TODO: add specific context here
+
+ RetCode setLeGainMb(int gainMb) {
+ // TODO : Add implementation to apply new gain
+ mGainMb = gainMb;
+ return RetCode::SUCCESS;
+ }
+ int getLeGainMb() const { return mGainMb; }
+
+ private:
+ int mGainMb = 0; // Default Gain
};
class LoudnessEnhancerSw final : public EffectImpl {
@@ -66,7 +75,7 @@
.name = "LoudnessEnhancerSw"},
.capability = Capability::make<Capability::loudnessEnhancer>(kCapability)};
- /* parameters */
- LoudnessEnhancer mSpecificParam;
+ ndk::ScopedAStatus getParameterLoudnessEnhancer(const LoudnessEnhancer::Tag& tag,
+ Parameter::Specific* specific);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index 8de1d79..03e9fca 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -7,136 +7,72 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
-cc_test {
- name: "VtsHalAudioCoreTargetTest",
+cc_defaults {
+ name: "VtsHalAudioTargetTestDefaults",
defaults: [
- "VtsHalTargetTestDefaults",
- "use_libaidlvintf_gtest_helper_static",
"latest_android_hardware_audio_common_ndk_static",
- "latest_android_hardware_audio_core_ndk_static",
"latest_android_media_audio_common_types_ndk_static",
+ "use_libaidlvintf_gtest_helper_static",
+ "VtsHalTargetTestDefaults",
],
shared_libs: [
"libbinder_ndk",
- "libcutils",
"libfmq",
],
static_libs: [
+ "android.hardware.audio.effect-V1-ndk",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
"libaudioaidlcommon",
],
+ header_libs: ["libaudioaidl_headers"],
cflags: [
"-Wall",
"-Wextra",
"-Werror",
"-Wthread-safety",
],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
+
+cc_test {
+ name: "VtsHalAudioCoreTargetTest",
+ defaults: [
+ "VtsHalAudioTargetTestDefaults",
+ "latest_android_hardware_audio_core_ndk_static",
+ ],
+ shared_libs: [
+ "libcutils",
+ ],
srcs: [
"ModuleConfig.cpp",
"VtsHalAudioCoreTargetTest.cpp",
],
- test_suites: [
- "general-tests",
- "vts",
- ],
}
cc_test {
name: "VtsHalAudioEffectFactoryTargetTest",
- defaults: [
- "latest_android_media_audio_common_types_ndk_static",
- "VtsHalTargetTestDefaults",
- "use_libaidlvintf_gtest_helper_static",
- ],
- srcs: [
- "VtsHalAudioEffectFactoryTargetTest.cpp",
- ],
- shared_libs: [
- "libbinder_ndk",
- ],
- static_libs: [
- "android.hardware.audio.effect-V1-ndk",
- "android.hardware.common-V2-ndk",
- "android.hardware.common.fmq-V1-ndk",
- ],
- header_libs: ["libaudioaidl_headers"],
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-Wthread-safety",
- ],
- test_suites: [
- "general-tests",
- "vts",
- ],
+ defaults: ["VtsHalAudioTargetTestDefaults"],
+ srcs: ["VtsHalAudioEffectFactoryTargetTest.cpp"],
}
cc_test {
name: "VtsHalAudioEffectTargetTest",
- defaults: [
- "latest_android_hardware_audio_common_ndk_static",
- "latest_android_media_audio_common_types_ndk_static",
- "VtsHalTargetTestDefaults",
- "use_libaidlvintf_gtest_helper_static",
- ],
- srcs: [
- "VtsHalAudioEffectTargetTest.cpp",
- ],
- shared_libs: [
- "libbinder_ndk",
- "libfmq",
- ],
- static_libs: [
- "android.hardware.audio.effect-V1-ndk",
- "android.hardware.common-V2-ndk",
- "android.hardware.common.fmq-V1-ndk",
- "libaudioaidlcommon",
- ],
- header_libs: ["libaudioaidl_headers"],
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-Wthread-safety",
- ],
- test_suites: [
- "general-tests",
- "vts",
- ],
+ defaults: ["VtsHalAudioTargetTestDefaults"],
+ srcs: ["VtsHalAudioEffectTargetTest.cpp"],
}
cc_test {
name: "VtsHalEqualizerTargetTest",
- defaults: [
- "latest_android_hardware_audio_common_ndk_static",
- "latest_android_media_audio_common_types_ndk_static",
- "VtsHalTargetTestDefaults",
- "use_libaidlvintf_gtest_helper_static",
- ],
- srcs: [
- "VtsHalEqualizerTargetTest.cpp",
- ],
- shared_libs: [
- "libbinder_ndk",
- "libfmq",
- ],
- static_libs: [
- "android.hardware.audio.effect-V1-ndk",
- "android.hardware.common-V2-ndk",
- "android.hardware.common.fmq-V1-ndk",
- "libaudioaidlcommon",
- ],
- header_libs: ["libaudioaidl_headers"],
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-Wthread-safety",
- ],
- test_suites: [
- "general-tests",
- "vts",
- ],
+ defaults: ["VtsHalAudioTargetTestDefaults"],
+ srcs: ["VtsHalEqualizerTargetTest.cpp"],
+}
+
+cc_test {
+ name: "VtsHalLoudnessEnhancerTargetTest",
+ defaults: ["VtsHalAudioTargetTestDefaults"],
+ srcs: ["VtsHalLoudnessEnhancerTargetTest.cpp"],
}
diff --git a/audio/aidl/vts/VtsHalAudioCoreTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreTargetTest.cpp
index 2f72bb0..5e9aa7f 100644
--- a/audio/aidl/vts/VtsHalAudioCoreTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreTargetTest.cpp
@@ -1961,10 +1961,11 @@
INSTANTIATE_TEST_SUITE_P(AudioCoreModuleTest, AudioCoreModule,
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreModule);
INSTANTIATE_TEST_SUITE_P(AudioCoreTelephonyTest, AudioCoreTelephony,
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
android::PrintInstanceNameToString);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreModule);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreTelephony);
INSTANTIATE_TEST_SUITE_P(AudioStreamInTest, AudioStreamIn,
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
android::PrintInstanceNameToString);
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
new file mode 100644
index 0000000..2ad016d
--- /dev/null
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -0,0 +1,145 @@
+/*
+ * 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/Vintf.h>
+
+#define LOG_TAG "VtsHalLoudnessEnhancerTest"
+
+#include <Utils.h>
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Capability;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::LoudnessEnhancer;
+using aidl::android::hardware::audio::effect::LoudnessEnhancerTypeUUID;
+using aidl::android::hardware::audio::effect::Parameter;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_GAIN_MB };
+using LoudnessEnhancerParamTestParam = std::tuple<std::string, 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.
+const std::vector<int> kGainMbValues = {std::numeric_limits<int>::min(), 100,
+ std::numeric_limits<int>::max()};
+
+class LoudnessEnhancerParamTest : public ::testing::TestWithParam<LoudnessEnhancerParamTestParam>,
+ public EffectHelper {
+ public:
+ LoudnessEnhancerParamTest()
+ : EffectHelper(std::get<PARAM_INSTANCE_NAME>(GetParam())),
+ mParamGainMb(std::get<PARAM_GAIN_MB>(GetParam())) {}
+
+ void SetUp() override {
+ CreateEffectsWithUUID(LoudnessEnhancerTypeUUID);
+ initParamCommonFormat();
+ initParamCommon();
+ initParamSpecific();
+ OpenEffects(LoudnessEnhancerTypeUUID);
+ SCOPED_TRACE(testing::Message() << "gainMb: " << mParamGainMb);
+ }
+
+ void TearDown() override {
+ CloseEffects();
+ DestroyEffects();
+ CleanUp();
+ }
+
+ 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;
+
+ // 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();
+
+ // 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));
+
+ EXPECT_EQ(expectParam, getParam);
+ }
+ };
+ EXPECT_NO_FATAL_FAILURE(ForEachEffect(functor));
+ }
+
+ void addGainMbParam(int gainMb) {
+ LoudnessEnhancer le;
+ le.set<LoudnessEnhancer::gainMb>(gainMb);
+ mTags.push_back({LoudnessEnhancer::gainMb, le});
+ }
+
+ 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();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ LoudnessEnhancerTest, LoudnessEnhancerParamTest,
+ ::testing::Combine(
+ testing::ValuesIn(android::getAidlHalInstanceNames(IFactory::descriptor)),
+ testing::ValuesIn(kGainMbValues)),
+ [](const testing::TestParamInfo<LoudnessEnhancerParamTest::ParamType>& info) {
+ std::string 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::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(LoudnessEnhancerParamTest);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index 3baafc9..b57dc63 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -238,12 +238,27 @@
}
// static
-std::vector<uint8_t> Effect::parameterToHal(uint32_t paramSize, const void* paramData,
- uint32_t valueSize, const void** valueData) {
+bool Effect::parameterToHal(uint32_t paramSize, const void* paramData, uint32_t valueSize,
+ const void** valueData, std::vector<uint8_t>* halParamBuffer) {
+ constexpr size_t kMaxSize = EFFECT_PARAM_SIZE_MAX - sizeof(effect_param_t);
+ if (paramSize > kMaxSize) {
+ ALOGE("%s: Parameter size is too big: %" PRIu32, __func__, paramSize);
+ return false;
+ }
size_t valueOffsetFromData = alignedSizeIn<uint32_t>(paramSize) * sizeof(uint32_t);
+ if (valueOffsetFromData > kMaxSize) {
+ ALOGE("%s: Aligned parameter size is too big: %zu", __func__, valueOffsetFromData);
+ return false;
+ }
+ if (valueSize > kMaxSize - valueOffsetFromData) {
+ ALOGE("%s: Value size is too big: %" PRIu32 ", max size is %zu", __func__, valueSize,
+ kMaxSize - valueOffsetFromData);
+ android_errorWriteLog(0x534e4554, "237291425");
+ return false;
+ }
size_t halParamBufferSize = sizeof(effect_param_t) + valueOffsetFromData + valueSize;
- std::vector<uint8_t> halParamBuffer(halParamBufferSize, 0);
- effect_param_t* halParam = reinterpret_cast<effect_param_t*>(&halParamBuffer[0]);
+ halParamBuffer->resize(halParamBufferSize, 0);
+ effect_param_t* halParam = reinterpret_cast<effect_param_t*>(halParamBuffer->data());
halParam->psize = paramSize;
halParam->vsize = valueSize;
memcpy(halParam->data, paramData, paramSize);
@@ -256,7 +271,7 @@
*valueData = halParam->data + valueOffsetFromData;
}
}
- return halParamBuffer;
+ return true;
}
Result Effect::analyzeCommandStatus(const char* commandName, const char* context, status_t status) {
@@ -301,6 +316,11 @@
Result Effect::getCurrentConfigImpl(uint32_t featureId, uint32_t configSize,
GetCurrentConfigSuccessCallback onSuccess) {
+ if (configSize > kMaxDataSize - sizeof(uint32_t)) {
+ ALOGE("%s: Config size is too big: %" PRIu32, __func__, configSize);
+ android_errorWriteLog(0x534e4554, "240266798");
+ return Result::INVALID_ARGUMENTS;
+ }
uint32_t halCmd = featureId;
std::vector<uint32_t> halResult(alignedSizeIn<uint32_t>(sizeof(uint32_t) + configSize), 0);
uint32_t halResultSize = 0;
@@ -314,11 +334,15 @@
GetParameterSuccessCallback onSuccess) {
// As it is unknown what method HAL uses for copying the provided parameter data,
// it is safer to make sure that input and output buffers do not overlap.
- std::vector<uint8_t> halCmdBuffer =
- parameterToHal(paramSize, paramData, requestValueSize, nullptr);
+ std::vector<uint8_t> halCmdBuffer;
+ if (!parameterToHal(paramSize, paramData, requestValueSize, nullptr, &halCmdBuffer)) {
+ return Result::INVALID_ARGUMENTS;
+ }
const void* valueData = nullptr;
- std::vector<uint8_t> halParamBuffer =
- parameterToHal(paramSize, paramData, replyValueSize, &valueData);
+ std::vector<uint8_t> halParamBuffer;
+ if (!parameterToHal(paramSize, paramData, replyValueSize, &valueData, &halParamBuffer)) {
+ return Result::INVALID_ARGUMENTS;
+ }
uint32_t halParamBufferSize = halParamBuffer.size();
return sendCommandReturningStatusAndData(
@@ -331,8 +355,12 @@
Result Effect::getSupportedConfigsImpl(uint32_t featureId, uint32_t maxConfigs, uint32_t configSize,
GetSupportedConfigsSuccessCallback onSuccess) {
+ if (maxConfigs != 0 && configSize > (kMaxDataSize - 2 * sizeof(uint32_t)) / maxConfigs) {
+ ALOGE("%s: Config size is too big: %" PRIu32, __func__, configSize);
+ return Result::INVALID_ARGUMENTS;
+ }
uint32_t halCmd[2] = {featureId, maxConfigs};
- uint32_t halResultSize = 2 * sizeof(uint32_t) + maxConfigs * sizeof(configSize);
+ uint32_t halResultSize = 2 * sizeof(uint32_t) + maxConfigs * configSize;
std::vector<uint8_t> halResult(static_cast<size_t>(halResultSize), 0);
return sendCommandReturningStatusAndData(
EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS, "GET_FEATURE_SUPPORTED_CONFIGS", sizeof(halCmd),
@@ -472,8 +500,10 @@
Result Effect::setParameterImpl(uint32_t paramSize, const void* paramData, uint32_t valueSize,
const void* valueData) {
- std::vector<uint8_t> halParamBuffer =
- parameterToHal(paramSize, paramData, valueSize, &valueData);
+ std::vector<uint8_t> halParamBuffer;
+ if (!parameterToHal(paramSize, paramData, valueSize, &valueData, &halParamBuffer)) {
+ return Result::INVALID_ARGUMENTS;
+ }
return sendCommandReturningStatus(EFFECT_CMD_SET_PARAM, "SET_PARAM", halParamBuffer.size(),
&halParamBuffer[0]);
}
diff --git a/audio/effect/all-versions/default/Effect.h b/audio/effect/all-versions/default/Effect.h
index 011544d..5d8dccc 100644
--- a/audio/effect/all-versions/default/Effect.h
+++ b/audio/effect/all-versions/default/Effect.h
@@ -184,6 +184,9 @@
using GetSupportedConfigsSuccessCallback =
std::function<void(uint32_t supportedConfigs, void* configsData)>;
+ // Sets the limit on the maximum size of vendor-provided data structures.
+ static constexpr size_t kMaxDataSize = 1 << 20;
+
static const char* sContextResultOfCommand;
static const char* sContextCallToCommand;
static const char* sContextCallFunction;
@@ -211,8 +214,8 @@
channel_config_t* halConfig);
static void effectOffloadParamToHal(const EffectOffloadParameter& offload,
effect_offload_param_t* halOffload);
- static std::vector<uint8_t> parameterToHal(uint32_t paramSize, const void* paramData,
- uint32_t valueSize, const void** valueData);
+ static bool parameterToHal(uint32_t paramSize, const void* paramData, uint32_t valueSize,
+ const void** valueData, std::vector<uint8_t>* halParamBuffer);
Result analyzeCommandStatus(const char* commandName, const char* context, status_t status);
void getConfigImpl(int commandCode, const char* commandName, GetConfigCallback cb);
diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
index e59423f..d95bb06 100644
--- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -35,6 +35,7 @@
#include <common/all-versions/VersionUtils.h>
+#include <cutils/properties.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
@@ -623,6 +624,27 @@
EXPECT_TRUE(ret.isOk());
}
+TEST_P(AudioEffectHidlTest, GetParameterInvalidMaxReplySize) {
+ description("Verify that GetParameter caps the maximum reply size");
+ const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
+ if (!isNewDeviceLaunchingOnTPlus) {
+ GTEST_SKIP() << "The test only applies to devices launching on T or later";
+ }
+ // Use a non-empty parameter to avoid being rejected by any earlier checks.
+ hidl_vec<uint8_t> parameter;
+ parameter.resize(16);
+ // Use very large size to ensure that the service does not crash. Since parameters
+ // are specific to each effect, and some effects may not have parameters at all,
+ // simply checking the return value would not reveal an issue of using an uncapped value.
+ const uint32_t veryLargeReplySize = std::numeric_limits<uint32_t>::max() - 100;
+ Result retval = Result::OK;
+ Return<void> ret =
+ effect->getParameter(parameter, veryLargeReplySize,
+ [&](Result r, const hidl_vec<uint8_t>&) { retval = r; });
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::INVALID_ARGUMENTS, retval);
+}
+
TEST_P(AudioEffectHidlTest, GetSupportedConfigsForFeature) {
description("Verify that GetSupportedConfigsForFeature does not crash");
Return<void> ret = effect->getSupportedConfigsForFeature(
@@ -643,6 +665,37 @@
EXPECT_TRUE(ret.isOk());
}
+TEST_P(AudioEffectHidlTest, GetSupportedConfigsForFeatureInvalidConfigSize) {
+ description("Verify that GetSupportedConfigsForFeature caps the maximum config size");
+ const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
+ if (!isNewDeviceLaunchingOnTPlus) {
+ GTEST_SKIP() << "The test only applies to devices launching on T or later";
+ }
+ // Use very large size to ensure that the service does not crash.
+ const uint32_t veryLargeConfigSize = std::numeric_limits<uint32_t>::max() - 100;
+ Result retval = Result::OK;
+ Return<void> ret = effect->getSupportedConfigsForFeature(
+ 0, 1, veryLargeConfigSize,
+ [&](Result r, uint32_t, const hidl_vec<uint8_t>&) { retval = r; });
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::INVALID_ARGUMENTS, retval);
+}
+
+TEST_P(AudioEffectHidlTest, GetCurrentConfigForFeatureInvalidConfigSize) {
+ description("Verify that GetCurrentConfigForFeature caps the maximum config size");
+ const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
+ if (!isNewDeviceLaunchingOnTPlus) {
+ GTEST_SKIP() << "The test only applies to devices launching on T or later";
+ }
+ // Use very large size to ensure that the service does not crash.
+ const uint32_t veryLargeConfigSize = std::numeric_limits<uint32_t>::max() - 100;
+ Result retval = Result::OK;
+ Return<void> ret = effect->getCurrentConfigForFeature(
+ 0, veryLargeConfigSize, [&](Result r, const hidl_vec<uint8_t>&) { retval = r; });
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::INVALID_ARGUMENTS, retval);
+}
+
// The main test class for Equalizer Audio Effect HIDL HAL.
class EqualizerAudioEffectHidlTest : public AudioEffectHidlTest {
public:
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl
index ebff98f..3abdb54 100644
--- a/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl
@@ -33,7 +33,9 @@
@utf8InCpp
String deviceId;
/**
- * Possible additional vendor information that is opaque to the EvsManager
+ * Possible additional vendor information that is opaque to the EvsManager.
+ * The size of the payload must not exceed 16-byte if the HIDL recipients are
+ * expected to exist.
*/
int[] payload;
}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/IEvsCameraStream.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/IEvsCameraStream.aidl
index 2c2b44c..c599d58 100644
--- a/automotive/evs/aidl/android/hardware/automotive/evs/IEvsCameraStream.aidl
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/IEvsCameraStream.aidl
@@ -47,7 +47,10 @@
/**
* Receives calls from the HAL each time an event happens.
*
- * @param in event EVS event with possible event information.
+ * @param in event EVS event with possible event information. If ths HIDL
+ * recipients are expected to exist, the size of the event
+ * payload must not exceed 16 bytes; otherwise, a notification
+ * will not reach them.
*/
void notify(in EvsEventDesc event);
}
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 0d3253b..33e211c 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -84,7 +84,10 @@
name: "android.hardware.automotive.vehicle@2.0-default-impl-lib",
vendor: true,
defaults: ["vhal_v2_0_target_defaults"],
- cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
+ cflags: [
+ "-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING",
+ "-DENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS",
+ ],
srcs: [
"impl/vhal_v2_0/DefaultVehicleHal.cpp",
"impl/vhal_v2_0/VehicleHalClient.cpp",
@@ -225,6 +228,25 @@
test_suites: ["general-tests"],
}
+cc_test {
+ name: "android.hardware.automotive.vehicle@2.0-default-config-test",
+ vendor: true,
+ defaults: ["vhal_v2_0_target_defaults"],
+ srcs: [
+ "impl/vhal_v2_0/tests/DefaultConfigSupportedPropertyIds_test.cpp",
+ ],
+ cflags: [
+ "-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING",
+ "-DENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS",
+ ],
+ static_libs: [
+ "android.hardware.automotive.vehicle@2.0-default-impl-lib",
+ "libgtest",
+ "libgmock",
+ ],
+ test_suites: ["general-tests"],
+}
+
cc_binary {
name: "android.hardware.automotive.vehicle@2.0-default-service",
defaults: ["vhal_v2_0_target_defaults"],
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index cfbbbd3..55a7720 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -1109,6 +1109,19 @@
},
.initialValue = {.stringValue = {"Test"}},
},
+ // This property is later defined in the AIDL VHAL interface. However, HIDL VHAL might
+ // require support for this property to meet EU regulation.
+ {
+ .config =
+ {
+ // GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT
+ .prop = 0x11400F47,
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::STATIC,
+ },
+ // GsrComplianceRequirementType::GSR_COMPLIANCE_REQUIRED_V1
+ .initialValue = {.int32Values = {1}},
+ },
#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
// Vendor propetry for E2E ClusterHomeService testing.
{
@@ -1157,6 +1170,46 @@
},
},
#endif // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
+#ifdef ENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS
+ {
+ .config =
+ {
+ // VHAL_SUPPORTED_PROPERTY_IDS
+ .prop = 289476424,
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::STATIC,
+ // Fetch 100 configs in one request. This number is just arbitrarily
+ // chosen here. But some HAL impl with bigger config data may need a
+ // smaller number.
+ .configArray = {100},
+ },
+ // All supported property IDs. This list is checked by
+ // DefaultConfigSupportedPropertyIds_test.
+ .initialValue =
+ {.int32Values =
+ {291504388, 289472773, 291504390, 289472775, 289407240, 289407241,
+ 289472780, 286261505, 286261506, 289407235, 289472779, 291504647,
+ 289408517, 356518832, 356516106, 291504644, 291504649, 291504656,
+ 291504901, 291504903, 287310600, 291504905, 287310602, 287310603,
+ 291504908, 291504904, 392168201, 392168202, 289408514, 289408001,
+ 287310850, 287310851, 287310853, 289475088, 289475104, 289475120,
+ 354419984, 320865540, 320865556, 354419975, 354419976, 354419986,
+ 354419973, 354419974, 354419978, 354419977, 356517120, 356517121,
+ 356582673, 356517139, 289408269, 356517131, 358614275, 291570965,
+ 291505923, 289408270, 289408512, 287310855, 289408000, 289408008,
+ 289408009, 289407747, 291504900, 568332561, 371198722, 373295872,
+ 320867268, 322964416, 290521862, 287310858, 287310859, 289475072,
+ 289475073, 289409539, 299896064, 299896065, 299896066, 299896067,
+ 289410560, 289410561, 289410562, 289410563, 289410576, 289410577,
+ 289410578, 289410579, 289476368, 299895808, 639631617, 627048706,
+ 591397123, 554696964, 289410873, 289410874, 287313669, 299896583,
+ 299896584, 299896585, 299896586, 299896587, 286265121, 286265122,
+ 286265123, 290457094, 290459441, 299896626, 290459443, 289410868,
+ 289476405, 299896630, 289410871, 292556600, 557853201, 559950353,
+ 555756049, 554707473, 289410887, 557846324, 557911861, 568332086,
+ 557846327, 560992056, 289476424}},
+ },
+#endif // ENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS
};
} // impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultConfigSupportedPropertyIds_test.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultConfigSupportedPropertyIds_test.cpp
new file mode 100644
index 0000000..aa05daa
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultConfigSupportedPropertyIds_test.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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 <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <vector>
+
+#include "vhal_v2_0/DefaultConfig.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+namespace impl {
+
+using ::testing::ElementsAreArray;
+
+// Test that VHAL_SUPPORTED_PROPERTY_IDS contains all supported property IDs.
+TEST(DefaultConfigSupportedPropertyIdsTest, testIncludeAllSupportedIds) {
+ const int32_t vhalSupportedPropertyIdsPropId = 289476424;
+
+ std::vector<int32_t> allSupportedIds;
+ std::vector<int32_t> configuredSupportedIds;
+
+ for (const auto& property : impl::kVehicleProperties) {
+ int propId = property.config.prop;
+ allSupportedIds.push_back(propId);
+
+ if (propId == vhalSupportedPropertyIdsPropId) {
+ configuredSupportedIds = property.initialValue.int32Values;
+ }
+ }
+
+ ASSERT_THAT(allSupportedIds, ElementsAreArray(configuredSupportedIds));
+}
+
+} // namespace impl
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
index e3c8dd6..25a1940 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
@@ -141,7 +141,7 @@
TEST_F(DefaultVhalImplTest, testListProperties) {
std::vector<VehiclePropConfig> configs = mHal->listProperties();
- EXPECT_EQ((size_t)121, configs.size());
+ EXPECT_EQ((size_t)123, configs.size());
}
TEST_F(DefaultVhalImplTest, testGetDefaultPropertyFloat) {
diff --git a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h b/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
index 65cd795..9a93e1a 100644
--- a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
+++ b/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
@@ -40,6 +40,7 @@
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaMirror;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
using ::aidl::android::hardware::automotive::vehicle::VehicleGear;
using ::aidl::android::hardware::automotive::vehicle::VehicleHvacFanDirection;
@@ -180,6 +181,523 @@
{.config =
{
+ .prop = toInt(VehicleProperty::EV_BATTERY_DISPLAY_UNITS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .configArray = {toInt(VehicleUnit::WATT_HOUR),
+ toInt(VehicleUnit::AMPERE_HOURS),
+ toInt(VehicleUnit::KILOWATT_HOUR)},
+ },
+ .initialValue = {.int32Values = {toInt(VehicleUnit::KILOWATT_HOUR)}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_BELT_BUCKLED),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER}}},
+ .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+ {SEAT_1_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_LEFT, {.int32Values = {0}}},
+ {SEAT_2_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_BELT_HEIGHT_POS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = 0,
+ .maxInt32Value = 10}}},
+ .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {10}}},
+ {SEAT_1_RIGHT, {.int32Values = {10}}},
+ {SEAT_2_LEFT, {.int32Values = {10}}},
+ {SEAT_2_RIGHT, {.int32Values = {10}}},
+ {SEAT_2_CENTER, {.int32Values = {10}}}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_BELT_HEIGHT_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+ {SEAT_1_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_LEFT, {.int32Values = {0}}},
+ {SEAT_2_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_FORE_AFT_POS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -10,
+ .maxInt32Value = 10}}},
+ .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+ {SEAT_1_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_LEFT, {.int32Values = {0}}},
+ {SEAT_2_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_FORE_AFT_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+ {SEAT_1_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_LEFT, {.int32Values = {0}}},
+ {SEAT_2_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_1_POS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -10,
+ .maxInt32Value = 10}}},
+ .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+ {SEAT_1_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_LEFT, {.int32Values = {0}}},
+ {SEAT_2_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+ {SEAT_1_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_LEFT, {.int32Values = {0}}},
+ {SEAT_2_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_2_POS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -10,
+ .maxInt32Value = 10}}},
+ .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+ {SEAT_1_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_LEFT, {.int32Values = {0}}},
+ {SEAT_2_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+ {SEAT_1_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_LEFT, {.int32Values = {0}}},
+ {SEAT_2_RIGHT, {.int32Values = {0}}},
+ {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_HEIGHT_POS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -10,
+ .maxInt32Value = 10}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_HEIGHT_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_DEPTH_POS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -10,
+ .maxInt32Value = 10}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_DEPTH_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_TILT_POS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -10,
+ .maxInt32Value = 10}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_TILT_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -10,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -10,
+ .maxInt32Value = 10}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = 0,
+ .maxInt32Value = 10}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_ANGLE_POS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = 0,
+ .maxInt32Value = 10}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_ANGLE_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_FORE_AFT_POS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = 0,
+ .maxInt32Value = 10},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = 0,
+ .maxInt32Value = 10}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config =
+ {
.prop = toInt(VehicleProperty::SEAT_OCCUPANCY),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -359,8 +877,9 @@
.prop = toInt(VehicleProperty::VEHICLE_CURB_WEIGHT),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::STATIC,
+ .configArray = {/*gross weight kg=*/2948},
},
- .initialValue = {.int32Values = {30}}},
+ .initialValue = {.int32Values = {2211 /*kg*/}}},
{.config =
{
@@ -467,6 +986,24 @@
{.config =
{
+ .prop = toInt(VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .configArray = {(int)VehicleUnit::LITER, (int)VehicleUnit::US_GALLON},
+ },
+ .initialValue = {.int32Values = {(int)VehicleUnit::LITER}}},
+
+ {.config =
+ {
+ .prop = toInt(
+ VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
+ .initialValue = {.int32Values = {1}}},
+
+ {.config =
+ {
.prop = toInt(VehicleProperty::HW_KEY_INPUT),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -493,6 +1030,12 @@
.int32Values = {0, 0, 0},
}},
+ {.config = {.prop = toInt(VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
+ .initialValue = {.int32Values = {50}}},
+
{.config = {.prop = toInt(VehicleProperty::HVAC_POWER_ON),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -630,6 +1173,25 @@
}}},
.initialValue = {.int32Values = {0}}}, // +ve values for heating and -ve for cooling
+ {.config = {.prop = toInt(VehicleProperty::HVAC_SIDE_MIRROR_HEAT),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{
+ .areaId = toInt(VehicleAreaMirror::DRIVER_LEFT) |
+ toInt(VehicleAreaMirror::DRIVER_RIGHT),
+ .minInt32Value = 0,
+ .maxInt32Value = 2,
+ }}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_CURRENT),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_LEFT},
+ VehicleAreaConfig{.areaId = HVAC_RIGHT}}},
+ .initialAreaValues = {{HVAC_LEFT, {.floatValues = {17.3f}}},
+ {HVAC_RIGHT, {.floatValues = {19.1f}}}}},
+
{.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -722,6 +1284,16 @@
{.config =
{
+ .prop = toInt(VehicleProperty::ENGINE_COOLANT_TEMP),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
+ .minSampleRate = 1.0f,
+ .maxSampleRate = 10.0f,
+ },
+ .initialValue = {.floatValues = {75.0f}}},
+
+ {.config =
+ {
.prop = toInt(VehicleProperty::ENGINE_OIL_LEVEL),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -781,6 +1353,76 @@
.areaId = DOOR_REAR, .minInt32Value = 0, .maxInt32Value = 1}}},
.initialValue = {.int32Values = {0}}},
+ {.config = {.prop = toInt(VehicleProperty::MIRROR_Z_POS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs =
+ {VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
+ .minInt32Value = -3,
+ .maxInt32Value = 3},
+ VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
+ .minInt32Value = -3,
+ .maxInt32Value = 3},
+ VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_CENTER),
+ .minInt32Value = -3,
+ .maxInt32Value = 3}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::MIRROR_Z_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs =
+ {VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_CENTER),
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::MIRROR_Y_POS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs =
+ {VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
+ .minInt32Value = -3,
+ .maxInt32Value = 3},
+ VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
+ .minInt32Value = -3,
+ .maxInt32Value = 3},
+ VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_CENTER),
+ .minInt32Value = -3,
+ .maxInt32Value = 3}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::MIRROR_Y_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs =
+ {VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_CENTER),
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialValue = {.int32Values = {0}}},
+
+ {.config = {.prop = toInt(VehicleProperty::MIRROR_LOCK),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
+ .initialValue = {.int32Values = {1}}},
+
+ {.config = {.prop = toInt(VehicleProperty::MIRROR_FOLD),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
+ .initialValue = {.int32Values = {1}}},
+
{.config = {.prop = toInt(VehicleProperty::WINDOW_LOCK),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -809,6 +1451,26 @@
.maxInt32Value = 10}}},
.initialValue = {.int32Values = {0}}},
+ {.config = {.prop = toInt(VehicleProperty::WINDOW_MOVE),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = WINDOW_1_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = WINDOW_1_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = WINDOW_2_LEFT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = WINDOW_2_RIGHT,
+ .minInt32Value = -1,
+ .maxInt32Value = 1},
+ VehicleAreaConfig{.areaId = WINDOW_ROOF_TOP_1,
+ .minInt32Value = -1,
+ .maxInt32Value = 1}}},
+ .initialValue = {.int32Values = {0}}},
+
{.config =
{
.prop = WHEEL_TICK,
@@ -891,14 +1553,6 @@
{.config =
{
- .prop = toInt(VehicleProperty::FOG_LIGHTS_STATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
- {.config =
- {
.prop = toInt(VehicleProperty::FRONT_FOG_LIGHTS_STATE),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -923,6 +1577,24 @@
{.config =
{
+ .prop = toInt(VehicleProperty::CABIN_LIGHTS_STATE),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
+ .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
+
+ {.config = {.prop = toInt(VehicleProperty::READING_LIGHTS_STATE),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER}}},
+ .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
+
+ {.config =
+ {
.prop = toInt(VehicleProperty::HEADLIGHTS_SWITCH),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -937,14 +1609,7 @@
},
.initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
- {.config =
- {
- .prop = toInt(VehicleProperty::FOG_LIGHTS_SWITCH),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
-
+ // FOG_LIGHTS_SWITCH must not be implemented when FRONT_FOG_LIGHTS_SWITCH is implemented
{.config =
{
.prop = toInt(VehicleProperty::FRONT_FOG_LIGHTS_SWITCH),
@@ -953,6 +1618,7 @@
},
.initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
+ // FOG_LIGHTS_SWITCH must not be implemented when REAR_FOG_LIGHTS_SWITCH is implemented
{.config =
{
.prop = toInt(VehicleProperty::REAR_FOG_LIGHTS_SWITCH),
@@ -971,6 +1637,24 @@
{.config =
{
+ .prop = toInt(VehicleProperty::CABIN_LIGHTS_SWITCH),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
+ .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
+
+ {.config = {.prop = toInt(VehicleProperty::READING_LIGHTS_SWITCH),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT},
+ VehicleAreaConfig{.areaId = SEAT_2_CENTER}}},
+ .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
+
+ {.config =
+ {
.prop = toInt(VehicleProperty::EVS_SERVICE_REQUEST),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index b64c1a6..20c34aa 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -217,17 +217,16 @@
[[fallthrough]];
case toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL):
// CPMS is in WAIT_FOR_VHAL state, simply move to ON and send back to HAL.
- // Must erase existing state because in the case when Car Service crashes, the power
- // state would already be ON when we receive WAIT_FOR_VHAL and thus new property change
- // event would be generated. However, Car Service always expect a property change event
- // even though there is not actual state change.
- mServerSidePropStore->removeValuesForProperty(
- toInt(VehicleProperty::AP_POWER_STATE_REQ));
prop = createApPowerStateReq(VehicleApPowerStateReq::ON);
- // ALWAYS update status for generated property value
+ // ALWAYS update status for generated property value, and force a property update event
+ // because in the case when Car Service crashes, the power state would already be ON
+ // when we receive WAIT_FOR_VHAL and thus new property change event would be generated.
+ // However, Car Service always expect a property change event even though there is no
+ // actual state change.
if (auto writeResult =
- mServerSidePropStore->writeValue(std::move(prop), /*updateStatus=*/true);
+ mServerSidePropStore->writeValue(std::move(prop), /*updateStatus=*/true,
+ VehiclePropertyStore::EventMode::ALWAYS);
!writeResult.ok()) {
return StatusError(getErrorCode(writeResult))
<< "failed to write AP_POWER_STATE_REQ into property store, error: "
@@ -894,10 +893,10 @@
return;
}
result.value()->timestamp = elapsedRealtimeNano();
- // Must remove the value before writing, otherwise, we would generate no update event since
- // the value is the same.
- mServerSidePropStore->removeValue(*result.value());
- mServerSidePropStore->writeValue(std::move(result.value()));
+ // For continuous properties, we must generate a new onPropertyChange event periodically
+ // according to the sample rate.
+ mServerSidePropStore->writeValue(std::move(result.value()), /*updateStatus=*/true,
+ VehiclePropertyStore::EventMode::ALWAYS);
});
mRecurrentTimer->registerTimerCallback(interval, action);
mRecurrentActions[propIdAreaId] = action;
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index a7fcdcf..8bc3c20 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -42,6 +42,7 @@
#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleArea.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleAreaDoor.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAreaMirror.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleAreaSeat.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleAreaWheel.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleAreaWindow.h>
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
index ddc4f68..3d25cd3 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
@@ -46,6 +46,33 @@
using ValueResultType = VhalResult<VehiclePropValuePool::RecyclableType>;
using ValuesResultType = VhalResult<std::vector<VehiclePropValuePool::RecyclableType>>;
+ enum class EventMode : uint8_t {
+ /**
+ * Only invoke OnValueChangeCallback if the new property value (ignoring timestamp) is
+ * different than the existing value.
+ *
+ * This should be used for regular cases.
+ */
+ ON_VALUE_CHANGE,
+ /**
+ * Always invoke OnValueChangeCallback.
+ *
+ * This should be used for the special properties that are used for delivering event, e.g.
+ * HW_KEY_INPUT.
+ */
+ ALWAYS,
+ /**
+ * Never invoke OnValueChangeCallback.
+ *
+ * This should be used for continuous property subscription when the sample rate for the
+ * subscription is smaller than the refresh rate for the property. E.g., the vehicle speed
+ * is refreshed at 20hz, but we are only subscribing at 10hz. In this case, we want to
+ * generate the property change event at 10hz, not 20hz, but we still want to refresh the
+ * timestamp (via writeValue) at 20hz.
+ */
+ NEVER,
+ };
+
explicit VehiclePropertyStore(std::shared_ptr<VehiclePropValuePool> valuePool)
: mValuePool(valuePool) {}
@@ -72,8 +99,10 @@
// 'status' would be initialized to {@code VehiclePropertyStatus::AVAILABLE}, if this is to
// override an existing value, the status for the existing value would be used for the
// overridden value.
+ // 'EventMode' controls whether the 'OnValueChangeCallback' will be called for this operation.
VhalResult<void> writeValue(VehiclePropValuePool::RecyclableType propValue,
- bool updateStatus = false);
+ bool updateStatus = false,
+ EventMode mode = EventMode::ON_VALUE_CHANGE);
// Remove a given property value from the property store. The 'propValue' would be used to
// generate the key for the value to remove.
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
index 8521c4d..2eca6b7 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
@@ -48,7 +48,7 @@
std::scoped_lock<std::mutex> lockGuard(mLock);
// Aligns the nextTime to multiply of interval.
- int64_t nextTime = ceil(elapsedRealtimeNano() / intervalInNano) * intervalInNano;
+ int64_t nextTime = ceil(uptimeNanos() / intervalInNano) * intervalInNano;
std::unique_ptr<CallbackInfo> info = std::make_unique<CallbackInfo>();
info->callback = callback;
@@ -128,7 +128,7 @@
}
// The first element is the nearest next event.
int64_t nextTime = mCallbackQueue[0]->nextTime;
- int64_t now = elapsedRealtimeNano();
+ int64_t now = uptimeNanos();
if (nextTime > now) {
interval = nextTime - now;
} else {
@@ -146,7 +146,7 @@
{
ScopedLockAssertion lockAssertion(mLock);
- int64_t now = elapsedRealtimeNano();
+ int64_t now = uptimeNanos();
while (mCallbackQueue.size() > 0) {
int64_t nextTime = mCallbackQueue[0]->nextTime;
if (nextTime > now) {
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
index c8fb994..646dc0e 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
@@ -106,7 +106,8 @@
}
VhalResult<void> VehiclePropertyStore::writeValue(VehiclePropValuePool::RecyclableType propValue,
- bool updateStatus) {
+ bool updateStatus,
+ VehiclePropertyStore::EventMode eventMode) {
std::scoped_lock<std::mutex> g(mLock);
int32_t propId = propValue->prop;
@@ -145,7 +146,12 @@
}
record->values[recId] = std::move(propValue);
- if (valueUpdated && mOnValueChangeCallback != nullptr) {
+
+ if (eventMode == EventMode::NEVER) {
+ return {};
+ }
+
+ if ((eventMode == EventMode::ALWAYS || valueUpdated) && mOnValueChangeCallback != nullptr) {
mOnValueChangeCallback(*(record->values[recId]));
}
return {};
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
index 4d6f811..fea5034 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
@@ -448,6 +448,67 @@
ASSERT_EQ(updatedValue.prop, INVALID_PROP_ID);
}
+TEST_F(VehiclePropertyStoreTest, testPropertyChangeCallbackNoUpdateForTimestampChange) {
+ VehiclePropValue updatedValue{
+ .prop = INVALID_PROP_ID,
+ };
+ VehiclePropValue fuelCapacity = {
+ .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
+ .value = {.floatValues = {1.0}},
+ };
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+ mStore->setOnValueChangeCallback(
+ [&updatedValue](const VehiclePropValue& value) { updatedValue = value; });
+
+ // Write the same value with different timestamp should succeed but should not trigger callback.
+ fuelCapacity.timestamp = 1;
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+ ASSERT_EQ(updatedValue.prop, INVALID_PROP_ID);
+}
+
+TEST_F(VehiclePropertyStoreTest, testPropertyChangeCallbackForceUpdate) {
+ VehiclePropValue updatedValue{
+ .prop = INVALID_PROP_ID,
+ };
+ VehiclePropValue fuelCapacity = {
+ .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
+ .value = {.floatValues = {1.0}},
+ };
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+ mStore->setOnValueChangeCallback(
+ [&updatedValue](const VehiclePropValue& value) { updatedValue = value; });
+
+ fuelCapacity.timestamp = 1;
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity), /*updateStatus=*/false,
+ VehiclePropertyStore::EventMode::ALWAYS));
+
+ ASSERT_EQ(updatedValue, fuelCapacity);
+}
+
+TEST_F(VehiclePropertyStoreTest, testPropertyChangeCallbackForceNoUpdate) {
+ VehiclePropValue updatedValue{
+ .prop = INVALID_PROP_ID,
+ };
+ VehiclePropValue fuelCapacity = {
+ .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
+ .value = {.floatValues = {1.0}},
+ };
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+ mStore->setOnValueChangeCallback(
+ [&updatedValue](const VehiclePropValue& value) { updatedValue = value; });
+ fuelCapacity.value.floatValues[0] = 2.0;
+ fuelCapacity.timestamp = 1;
+
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity), /*updateStatus=*/false,
+ VehiclePropertyStore::EventMode::NEVER));
+
+ ASSERT_EQ(updatedValue.prop, INVALID_PROP_ID);
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
index 57705bc..f940000 100644
--- a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
@@ -279,8 +279,10 @@
* with specified torchStrength if the torch is OFF.
*
* The torchStrength value must be within the valid range i.e. >=1 and
- * <= FLASH_INFO_STRENGTH_MAXIMUM_LEVEL. Whenever the torch is turned OFF,
- * the brightness level will reset to FLASH_INFO_STRENGTH_DEFAULT_LEVEL.
+ * <= FLASH_INFO_STRENGTH_MAXIMUM_LEVEL. The FLASH_INFO_STRENGTH_MAXIMUM_LEVEL must
+ * be set to a level which will not cause any burn out issues. Whenever
+ * the torch is turned OFF, the brightness level will reset to
+ * FLASH_INFO_STRENGTH_DEFAULT_LEVEL.
* When the client calls setTorchMode(ON) after turnOnTorchWithStrengthLevel(N),
* the flash unit will have brightness level equal to N. This level does not
* represent the real brightness units. It is linear in nature i.e. flashlight
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index bbf05cc..7110ac0 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -197,7 +197,7 @@
<regex-instance>[^/]+/[0-9]+</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
+ <hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.camera.provider</name>
<version>1</version>
<interface>
diff --git a/contexthub/aidl/default/ContextHub.cpp b/contexthub/aidl/default/ContextHub.cpp
index 4c23cbc..35e4650 100644
--- a/contexthub/aidl/default/ContextHub.cpp
+++ b/contexthub/aidl/default/ContextHub.cpp
@@ -107,10 +107,9 @@
ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) {
if (mConnectedHostEndpoints.count(in_hostEndpointId) > 0) {
mConnectedHostEndpoints.erase(in_hostEndpointId);
- return ndk::ScopedAStatus::ok();
- } else {
- return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
}
+
+ return ndk::ScopedAStatus::ok();
}
} // namespace contexthub
diff --git a/graphics/allocator/aidl/Android.bp b/graphics/allocator/aidl/Android.bp
index 272ab48..6dc983c 100644
--- a/graphics/allocator/aidl/Android.bp
+++ b/graphics/allocator/aidl/Android.bp
@@ -14,9 +14,11 @@
enabled: true,
support_system_process: true,
},
+ vndk_use_version: "1",
srcs: ["android/hardware/graphics/allocator/*.aidl"],
imports: [
"android.hardware.common-V2",
+ "android.hardware.graphics.common-V3",
],
stability: "vintf",
backend: {
diff --git a/identity/aidl/Android.bp b/identity/aidl/Android.bp
index c05dd33..2090473 100644
--- a/identity/aidl/Android.bp
+++ b/identity/aidl/Android.bp
@@ -67,20 +67,20 @@
cc_defaults {
name: "identity_use_latest_hal_aidl_ndk_static",
static_libs: [
- "android.hardware.identity-V5-ndk",
+ "android.hardware.identity-V4-ndk",
],
}
cc_defaults {
name: "identity_use_latest_hal_aidl_ndk_shared",
shared_libs: [
- "android.hardware.identity-V5-ndk",
+ "android.hardware.identity-V4-ndk",
],
}
cc_defaults {
name: "identity_use_latest_hal_aidl_cpp_static",
static_libs: [
- "android.hardware.identity-V5-cpp",
+ "android.hardware.identity-V4-cpp",
],
}
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/oemlock/aidl/default/OemLock.cpp b/oemlock/aidl/default/OemLock.cpp
index 646b532..234a8a9 100644
--- a/oemlock/aidl/default/OemLock.cpp
+++ b/oemlock/aidl/default/OemLock.cpp
@@ -24,29 +24,31 @@
// Methods from ::android::hardware::oemlock::IOemLock follow.
::ndk::ScopedAStatus OemLock::getName(std::string *out_name) {
- (void)out_name;
+ *out_name = "SomeCoolName";
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OemLock::setOemUnlockAllowedByCarrier(bool in_allowed, const std::vector<uint8_t> &in_signature, OemLockSecureStatus *_aidl_return) {
- (void)in_allowed;
+ // Default impl doesn't care about a valid vendor signature
(void)in_signature;
- (void)_aidl_return;
+
+ mAllowedByCarrier = in_allowed;
+ *_aidl_return = OemLockSecureStatus::OK;
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OemLock::isOemUnlockAllowedByCarrier(bool *out_allowed) {
- (void)out_allowed;
+ *out_allowed = mAllowedByCarrier;
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OemLock::setOemUnlockAllowedByDevice(bool in_allowed) {
- (void)in_allowed;
+ mAllowedByDevice = in_allowed;
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus OemLock::isOemUnlockAllowedByDevice(bool *out_allowed) {
- (void)out_allowed;
+ *out_allowed = mAllowedByDevice;
return ::ndk::ScopedAStatus::ok();
}
diff --git a/oemlock/aidl/default/OemLock.h b/oemlock/aidl/default/OemLock.h
index b0df414..9dff21a 100644
--- a/oemlock/aidl/default/OemLock.h
+++ b/oemlock/aidl/default/OemLock.h
@@ -36,6 +36,10 @@
::ndk::ScopedAStatus isOemUnlockAllowedByDevice(bool* out_allowed) override;
::ndk::ScopedAStatus setOemUnlockAllowedByCarrier(bool in_allowed, const std::vector<uint8_t>& in_signature, OemLockSecureStatus* _aidl_return) override;
::ndk::ScopedAStatus setOemUnlockAllowedByDevice(bool in_allowed) override;
+
+ private:
+ bool mAllowedByCarrier = false;
+ bool mAllowedByDevice = false;
};
} // namespace oemlock
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 4f361bb..97fe08a 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -251,6 +251,19 @@
EXPECT_LE(hwInfo.uniqueId->size(), 32);
}
+/**
+ * Verify implementation supports at least MIN_SUPPORTED_NUM_KEYS_IN_CSR keys in a CSR.
+ */
+TEST_P(GetHardwareInfoTests, supportedNumKeysInCsr) {
+ if (rpcHardwareInfo.versionNumber < VERSION_WITHOUT_TEST_MODE) {
+ return;
+ }
+
+ RpcHardwareInfo hwInfo;
+ ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
+ ASSERT_GE(hwInfo.supportedNumKeysInCsr, RpcHardwareInfo::MIN_SUPPORTED_NUM_KEYS_IN_CSR);
+}
+
using GenerateKeyTests = VtsRemotelyProvisionedComponentTests;
INSTANTIATE_REM_PROV_AIDL_TEST(GenerateKeyTests);
@@ -701,7 +714,8 @@
}
/**
- * Generate a non-empty certificate request. Make sure contents are reproducible.
+ * Generate a non-empty certificate request. Make sure contents are reproducible but allow for the
+ * signature to be different since algorithms including ECDSA P-256 can include a random value.
*/
TEST_P(CertificateRequestV2Test, NonEmptyRequestReproducible) {
generateKeys(false /* testMode */, 1 /* numKeys */);
@@ -711,27 +725,23 @@
auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
ASSERT_TRUE(status.isOk()) << status.getMessage();
- auto firstBcc = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
- ASSERT_TRUE(firstBcc) << firstBcc.message();
+ auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
+ ASSERT_TRUE(firstCsr) << firstCsr.message();
status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
ASSERT_TRUE(status.isOk()) << status.getMessage();
- auto secondBcc = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
- ASSERT_TRUE(secondBcc) << secondBcc.message();
+ auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
+ ASSERT_TRUE(secondCsr) << secondCsr.message();
- ASSERT_EQ(firstBcc->size(), secondBcc->size());
- for (auto i = 0; i < firstBcc->size(); i++) {
- ASSERT_EQ(firstBcc->at(i).pubKey, secondBcc->at(i).pubKey);
- }
+ ASSERT_EQ(**firstCsr, **secondCsr);
}
/**
* Generate a non-empty certificate request with multiple keys.
*/
TEST_P(CertificateRequestV2Test, NonEmptyRequestMultipleKeys) {
- // TODO(b/254137722): define a minimum number of keys that must be supported.
- generateKeys(false /* testMode */, 5 /* numKeys */);
+ generateKeys(false /* testMode */, rpcHardwareInfo.supportedNumKeysInCsr /* numKeys */);
bytevec csr;
diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h
index 6871e1b..1b94c62 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -181,14 +181,13 @@
* Verify the CSR as if the device is still early in the factory process and may not
* have all device identifiers provisioned yet.
*/
-ErrMsgOr<std::vector<BccEntryData>> verifyFactoryCsr(const cppbor::Array& keysToSign,
- const std::vector<uint8_t>& csr,
- IRemotelyProvisionedComponent* provisionable,
- const std::vector<uint8_t>& challenge);
+ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr(
+ const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
+ IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge);
/**
* Verify the CSR as if the device is a final production sample.
*/
-ErrMsgOr<std::vector<BccEntryData>> verifyProductionCsr(
+ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(
const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge);
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index f7ab3ac..7e164fd 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -521,11 +521,10 @@
return errMsg;
}
- std::unique_ptr<cppbor::Map> parsed(parsedVerifiedDeviceInfo->asMap());
+ std::unique_ptr<cppbor::Map> parsed(parsedVerifiedDeviceInfo.release()->asMap());
if (!parsed) {
return "DeviceInfo must be a CBOR map.";
}
- parsedVerifiedDeviceInfo.release();
if (parsed->clone()->asMap()->canonicalize().encode() != deviceInfoBytes) {
return "DeviceInfo ordering is non-canonical.";
@@ -846,54 +845,79 @@
return "";
}
-ErrMsgOr<cppbor::Array> parseAndValidateCsrPayload(const cppbor::Array& keysToSign,
- const std::vector<uint8_t>& csrPayload,
- IRemotelyProvisionedComponent* provisionable,
- const std::vector<uint8_t>& challenge,
- bool isFactory) {
+ErrMsgOr<std::unique_ptr<cppbor::Array>> parseAndValidateCsrPayload(
+ const cppbor::Array& keysToSign, const std::vector<uint8_t>& csrPayload,
+ IRemotelyProvisionedComponent* provisionable, bool isFactory) {
auto [parsedCsrPayload, _, errMsg] = cppbor::parse(csrPayload);
if (!parsedCsrPayload) {
return errMsg;
}
- if (!parsedCsrPayload->asArray()) {
+
+ std::unique_ptr<cppbor::Array> parsed(parsedCsrPayload.release()->asArray());
+ if (!parsed) {
return "CSR payload is not a CBOR array.";
}
- if (parsedCsrPayload->asArray()->size() != 5U) {
- return "CSR payload must contain version, certificate type, device info, challenge, keys. "
+
+ if (parsed->size() != 4U) {
+ return "CSR payload must contain version, certificate type, device info, keys. "
"However, the parsed CSR payload has " +
- std::to_string(parsedCsrPayload->asArray()->size()) + " entries.";
+ std::to_string(parsed->size()) + " entries.";
}
- auto& signedVersion = parsedCsrPayload->asArray()->get(0);
- auto& signedCertificateType = parsedCsrPayload->asArray()->get(1);
- auto& signedDeviceInfo = parsedCsrPayload->asArray()->get(2);
- auto& signedChallenge = parsedCsrPayload->asArray()->get(3);
- auto& signedKeys = parsedCsrPayload->asArray()->get(4);
+ auto signedVersion = parsed->get(0)->asUint();
+ auto signedCertificateType = parsed->get(1)->asTstr();
+ auto signedDeviceInfo = parsed->get(2)->asMap();
+ auto signedKeys = parsed->get(3)->asArray();
- if (!signedVersion || !signedVersion->asUint() || signedVersion->asUint()->value() != 1U) {
- return "CSR payload version must be an unsigned integer and must be equal to 1.";
+ if (!signedVersion || signedVersion->value() != 3U) {
+ return "CSR payload version must be an unsigned integer and must be equal to 3.";
}
- if (!signedCertificateType || !signedCertificateType->asTstr()) {
+ if (!signedCertificateType) {
// Certificate type is allowed to be extendend by vendor, i.e. we can't
// enforce its value.
return "Certificate type must be a Tstr.";
}
- if (!signedDeviceInfo || !signedDeviceInfo->asMap()) {
+ if (!signedDeviceInfo) {
return "Device info must be an Map.";
}
- if (!signedChallenge || !signedChallenge->asBstr()) {
- return "Challenge must be a Bstr.";
- }
- if (!signedKeys || !signedKeys->asArray()) {
+ if (!signedKeys) {
return "Keys must be an Array.";
}
- auto result = parseAndValidateDeviceInfo(signedDeviceInfo->asMap()->encode(), provisionable,
- isFactory);
+ auto result = parseAndValidateDeviceInfo(signedDeviceInfo->encode(), provisionable, isFactory);
if (!result) {
return result.message();
}
+ if (signedKeys->encode() != keysToSign.encode()) {
+ return "Signed keys do not match.";
+ }
+
+ return std::move(parsed);
+}
+
+ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequestSignedPayload(
+ const std::vector<uint8_t>& signedPayload, const std::vector<uint8_t>& challenge) {
+ auto [parsedSignedPayload, _, errMsg] = cppbor::parse(signedPayload);
+ if (!parsedSignedPayload) {
+ return errMsg;
+ }
+ if (!parsedSignedPayload->asArray()) {
+ return "SignedData payload is not a CBOR array.";
+ }
+ if (parsedSignedPayload->asArray()->size() != 2U) {
+ return "SignedData payload must contain the challenge and request. However, the parsed "
+ "SignedData payload has " +
+ std::to_string(parsedSignedPayload->asArray()->size()) + " entries.";
+ }
+
+ auto signedChallenge = parsedSignedPayload->asArray()->get(0)->asBstr();
+ auto signedRequest = parsedSignedPayload->asArray()->get(1)->asBstr();
+
+ if (!signedChallenge) {
+ return "Challenge must be a Bstr.";
+ }
+
if (challenge.size() < 32 || challenge.size() > 64) {
return "Challenge size must be between 32 and 64 bytes inclusive. "
"However, challenge is " +
@@ -901,68 +925,57 @@
}
auto challengeBstr = cppbor::Bstr(challenge);
- if (*signedChallenge->asBstr() != challengeBstr) {
+ if (*signedChallenge != challengeBstr) {
return "Signed challenge does not match."
"\n Actual: " +
cppbor::prettyPrint(signedChallenge->asBstr(), 64 /* maxBStrSize */) +
"\nExpected: " + cppbor::prettyPrint(&challengeBstr, 64 /* maxBStrSize */);
}
- if (signedKeys->asArray()->encode() != keysToSign.encode()) {
- return "Signed keys do not match.";
+ if (!signedRequest) {
+ return "Request must be a Bstr.";
}
- return std::move(*parsedCsrPayload->asArray());
+ return signedRequest->value();
}
-ErrMsgOr<std::vector<BccEntryData>> verifyCsr(const cppbor::Array& keysToSign,
- const std::vector<uint8_t>& csr,
- IRemotelyProvisionedComponent* provisionable,
- const std::vector<uint8_t>& challenge,
- bool isFactory) {
- auto [parsedCsr, _, csrErrMsg] = cppbor::parse(csr);
- if (!parsedCsr) {
+ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequest(const std::vector<uint8_t>& request,
+ const std::vector<uint8_t>& challenge) {
+ auto [parsedRequest, _, csrErrMsg] = cppbor::parse(request);
+ if (!parsedRequest) {
return csrErrMsg;
}
- if (!parsedCsr->asArray()) {
- return "CSR is not a CBOR array.";
+ if (!parsedRequest->asArray()) {
+ return "AuthenticatedRequest is not a CBOR array.";
}
- if (parsedCsr->asArray()->size() != 4U) {
- return "CSR must contain version, UDS certificates, DICE chain, and signed data. "
- "However, the parsed CSR has " +
- std::to_string(parsedCsr->asArray()->size()) + " entries.";
+ if (parsedRequest->asArray()->size() != 4U) {
+ return "AuthenticatedRequest must contain version, UDS certificates, DICE chain, and "
+ "signed data. However, the parsed AuthenticatedRequest has " +
+ std::to_string(parsedRequest->asArray()->size()) + " entries.";
}
- auto& version = parsedCsr->asArray()->get(0);
- auto& udsCerts = parsedCsr->asArray()->get(1);
- auto& diceCertChain = parsedCsr->asArray()->get(2);
- auto& signedData = parsedCsr->asArray()->get(3);
+ auto version = parsedRequest->asArray()->get(0)->asUint();
+ auto udsCerts = parsedRequest->asArray()->get(1)->asMap();
+ auto diceCertChain = parsedRequest->asArray()->get(2)->asArray();
+ auto signedData = parsedRequest->asArray()->get(3)->asArray();
- if (!version || !version->asUint() || version->asUint()->value() != 3U) {
- return "Version must be an unsigned integer and must be equal to 3.";
+ if (!version || version->value() != 1U) {
+ return "AuthenticatedRequest version must be an unsigned integer and must be equal to 1.";
}
- if (!udsCerts || !udsCerts->asMap()) {
- return "UdsCerts must be an Map.";
+ if (!udsCerts) {
+ return "AuthenticatedRequest UdsCerts must be an Map.";
}
- if (!diceCertChain || !diceCertChain->asArray()) {
- return "DiceCertChain must be an Array.";
+ if (!diceCertChain) {
+ return "AuthenticatedRequest DiceCertChain must be an Array.";
}
- if (!signedData || !signedData->asArray()) {
- return "SignedData must be an Array.";
- }
-
- RpcHardwareInfo info;
- provisionable->getHardwareInfo(&info);
- if (version->asUint()->value() != info.versionNumber) {
- return "CSR version (" + std::to_string(version->asUint()->value()) +
- ") does not match the remotely provisioned component version (" +
- std::to_string(info.versionNumber) + ").";
+ if (!signedData) {
+ return "AuthenticatedRequest SignedData must be an Array.";
}
// DICE chain is [ pubkey, + DiceChainEntry ]. Its format is the same as BCC from RKP v1-2.
- auto diceContents = validateBcc(diceCertChain->asArray());
+ auto diceContents = validateBcc(diceCertChain);
if (!diceContents) {
- return diceContents.message() + "\n" + prettyPrint(diceCertChain.get());
+ return diceContents.message() + "\n" + prettyPrint(diceCertChain);
}
if (diceContents->size() == 0U) {
return "The DICE chain is empty. It must contain at least one entry.";
@@ -970,33 +983,51 @@
auto& udsPub = diceContents->back().pubKey;
- auto error = validateUdsCerts(*udsCerts->asMap(), udsPub);
+ auto error = validateUdsCerts(*udsCerts, udsPub);
if (!error.empty()) {
return error;
}
- auto csrPayload = verifyAndParseCoseSign1(signedData->asArray(), udsPub, {} /* aad */);
+ auto signedPayload = verifyAndParseCoseSign1(signedData, udsPub, {} /* aad */);
+ if (!signedPayload) {
+ return signedPayload.message();
+ }
+
+ auto payload = parseAndValidateAuthenticatedRequestSignedPayload(*signedPayload, challenge);
+ if (!payload) {
+ return payload.message();
+ }
+
+ return payload;
+}
+
+ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyCsr(const cppbor::Array& keysToSign,
+ const std::vector<uint8_t>& csr,
+ IRemotelyProvisionedComponent* provisionable,
+ const std::vector<uint8_t>& challenge,
+ bool isFactory) {
+ RpcHardwareInfo info;
+ provisionable->getHardwareInfo(&info);
+ if (info.versionNumber != 3) {
+ return "Remotely provisioned component version (" + std::to_string(info.versionNumber) +
+ ") does not match expected version (3).";
+ }
+
+ auto csrPayload = parseAndValidateAuthenticatedRequest(csr, challenge);
if (!csrPayload) {
return csrPayload.message();
}
- auto parsedCsrPayload = parseAndValidateCsrPayload(keysToSign, *csrPayload, provisionable,
- challenge, isFactory);
- if (!parsedCsrPayload) {
- return parsedCsrPayload.message();
- }
-
- return *diceContents;
+ return parseAndValidateCsrPayload(keysToSign, *csrPayload, provisionable, isFactory);
}
-ErrMsgOr<std::vector<BccEntryData>> verifyFactoryCsr(const cppbor::Array& keysToSign,
- const std::vector<uint8_t>& csr,
- IRemotelyProvisionedComponent* provisionable,
- const std::vector<uint8_t>& challenge) {
+ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr(
+ const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
+ IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) {
return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/true);
}
-ErrMsgOr<std::vector<BccEntryData>> verifyProductionCsr(
+ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(
const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) {
return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false);
diff --git a/security/rkp/CHANGELOG.md b/security/rkp/CHANGELOG.md
index eb2041d..29b1a1c 100644
--- a/security/rkp/CHANGELOG.md
+++ b/security/rkp/CHANGELOG.md
@@ -36,4 +36,5 @@
* 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.
-
+* RpcHardwareInfo
+ * `supportedNumKeysInCsr` added to report the maximum number of keys supported in a CSR.
diff --git a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/RpcHardwareInfo.aidl
index 5ff45f8..b1f99e1 100644
--- a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/RpcHardwareInfo.aidl
+++ b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/RpcHardwareInfo.aidl
@@ -39,7 +39,9 @@
@utf8InCpp String rpcAuthorName;
int supportedEekCurve = 0;
@nullable @utf8InCpp String uniqueId;
+ int supportedNumKeysInCsr = 4;
const int CURVE_NONE = 0;
const int CURVE_P256 = 1;
const int CURVE_25519 = 2;
+ const int MIN_SUPPORTED_NUM_KEYS_IN_CSR = 20;
}
diff --git a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 86c1717..78969d1 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -315,13 +315,12 @@
*
* @return the following CBOR Certificate Signing Request (Csr) serialized into a byte array:
*
- * Csr = AuthenticatedMessage<CsrPayload>
+ * Csr = AuthenticatedRequest<CsrPayload>
*
* CsrPayload = [ ; CBOR Array defining the payload for Csr
- * version: 1, ; The CsrPayload CDDL Schema version.
+ * version: 3, ; The CsrPayload CDDL Schema version.
* CertificateType, ; The type of certificate being requested.
* DeviceInfo, ; Defined in DeviceInfo.aidl
- * challenge: bstr .size (32..64), ; Provided by the method parameters
* KeysToSign, ; Provided by the method parameters
* ]
*
@@ -335,11 +334,14 @@
*
* KeysToSign = [ * PublicKey ] ; Please see MacedPublicKey.aidl for the PublicKey definition.
*
- * AuthenticatedMessage<T> = [
- * version: 3, ; The AuthenticatedMessage CDDL Schema version.
- * UdsCerts,
- * DiceCertChain,
- * SignedData<T>,
+ * AuthenticatedRequest<T> = [
+ * version: 1, ; The AuthenticatedRequest CDDL Schema version.
+ * UdsCerts,
+ * DiceCertChain,
+ * SignedData<[
+ * challenge: bstr .size (32..64), ; Provided by the method parameters
+ * bstr .cbor T,
+ * ]>,
* ]
*
* ; COSE_Sign1 (untagged)
diff --git a/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
index 0cb33ce..5fe5b00 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
@@ -74,4 +74,17 @@
*
*/
@nullable @utf8InCpp String uniqueId;
+
+ /**
+ * supportedNumKeysInCsr is the maximum number of keys in a CSR that this implementation can
+ * support. This value is implementation defined.
+ *
+ * From version 3 onwards, supportedNumKeysInCsr must be larger or equal to
+ * MIN_SUPPORTED_NUM_KEYS_IN_CSR.
+ *
+ * The default value was chosen as the value enforced by the VTS test in versions 1 and 2 of
+ * this interface.
+ */
+ const int MIN_SUPPORTED_NUM_KEYS_IN_CSR = 20;
+ int supportedNumKeysInCsr = 4;
}
diff --git a/usb/1.0/default/Android.bp b/usb/1.0/default/Android.bp
index 4bed2c7..5f56fe0 100644
--- a/usb/1.0/default/Android.bp
+++ b/usb/1.0/default/Android.bp
@@ -21,21 +21,11 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
-filegroup {
- name: "android.hardware.usb@1.0-service.xml",
- srcs: ["android.hardware.usb@1.0-service.xml"],
-}
-
-filegroup {
- name: "android.hardware.usb@1.0-service.rc",
- srcs: ["android.hardware.usb@1.0-service.rc"],
-}
-
cc_binary {
name: "android.hardware.usb@1.0-service",
defaults: ["hidl_defaults"],
- init_rc: [":android.hardware.usb@1.0-service.rc"],
- vintf_fragments: [":android.hardware.usb@1.0-service.xml"],
+ init_rc: ["android.hardware.usb@1.0-service.rc"],
+ vintf_fragments: ["android.hardware.usb@1.0-service.xml"],
relative_install_path: "hw",
vendor: true,
srcs: [
diff --git a/usb/1.0/default/apex/manifest.json b/usb/1.0/default/apex/manifest.json
deleted file mode 100644
index 6a1095f..0000000
--- a/usb/1.0/default/apex/manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "com.android.hardware.usb",
- "version": 1
-}
diff --git a/usb/aidl/default/Android.bp b/usb/aidl/default/Android.bp
index 7cb2822..ad331f9 100644
--- a/usb/aidl/default/Android.bp
+++ b/usb/aidl/default/Android.bp
@@ -37,8 +37,18 @@
"android.hardware.usb-V1-ndk",
"libbase",
"libbinder_ndk",
- "libcutils",
+ "libcutils",
"liblog",
"libutils",
],
}
+
+filegroup {
+ name: "android.hardware.usb-service.example.xml",
+ srcs: ["android.hardware.usb-service.example.xml"],
+}
+
+filegroup {
+ name: "android.hardware.usb-service.example.rc",
+ srcs: ["android.hardware.usb-service.example.rc"],
+}
diff --git a/usb/1.0/default/apex/Android.bp b/usb/apex/Android.bp
similarity index 84%
rename from usb/1.0/default/apex/Android.bp
rename to usb/apex/Android.bp
index ee50fdf..765aa21 100644
--- a/usb/1.0/default/apex/Android.bp
+++ b/usb/apex/Android.bp
@@ -27,19 +27,6 @@
certificate: "com.android.hardware.usb",
}
-genrule {
- name: "com.android.hardware.usb.rc-gen",
- srcs: [":android.hardware.usb@1.0-service.rc"],
- out: ["com.android.hardware.usb.rc"],
- cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.usb/' $(in) > $(out)",
-}
-
-prebuilt_etc {
- name: "com.android.hardware.usb.rc",
- src: ":com.android.hardware.usb.rc-gen",
- installable: false,
-}
-
apex {
name: "com.android.hardware.usb",
manifest: "manifest.json",
@@ -49,11 +36,25 @@
updatable: false,
soc_specific: true,
use_vndk_as_stable: true,
- binaries: ["android.hardware.usb@1.0-service"],
+ binaries: ["android.hardware.usb-service.example"],
prebuilts: [
- "com.android.hardware.usb.rc",
+ "com.android.hardware.usb.rc", // init .rc
"android.hardware.usb.accessory.prebuilt.xml",
"android.hardware.usb.host.prebuilt.xml",
],
- vintf_fragments: [":android.hardware.usb@1.0-service.xml"],
+ vintf_fragments: [":android.hardware.usb-service.example.xml"],
+}
+
+// Replace the binary path from /vendor/bin to /apex/{name}/bin in the init .rc file
+genrule {
+ name: "com.android.hardware.usb.rc-gen",
+ srcs: [":android.hardware.usb-service.example.rc"],
+ out: ["com.android.hardware.usb.rc"],
+ cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.usb/' $(in) > $(out)",
+}
+
+prebuilt_etc {
+ name: "com.android.hardware.usb.rc",
+ src: ":com.android.hardware.usb.rc-gen",
+ installable: false,
}
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey b/usb/apex/com.android.hardware.usb.avbpubkey
similarity index 100%
rename from usb/1.0/default/apex/com.android.hardware.usb.avbpubkey
rename to usb/apex/com.android.hardware.usb.avbpubkey
Binary files differ
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.pem b/usb/apex/com.android.hardware.usb.pem
similarity index 100%
rename from usb/1.0/default/apex/com.android.hardware.usb.pem
rename to usb/apex/com.android.hardware.usb.pem
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.pk8 b/usb/apex/com.android.hardware.usb.pk8
similarity index 100%
rename from usb/1.0/default/apex/com.android.hardware.usb.pk8
rename to usb/apex/com.android.hardware.usb.pk8
Binary files differ
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.x509.pem b/usb/apex/com.android.hardware.usb.x509.pem
similarity index 100%
rename from usb/1.0/default/apex/com.android.hardware.usb.x509.pem
rename to usb/apex/com.android.hardware.usb.x509.pem
diff --git a/usb/1.0/default/apex/file_contexts b/usb/apex/file_contexts
similarity index 66%
rename from usb/1.0/default/apex/file_contexts
rename to usb/apex/file_contexts
index bc84ac4..f223a56 100644
--- a/usb/1.0/default/apex/file_contexts
+++ b/usb/apex/file_contexts
@@ -2,4 +2,4 @@
# Permission XMLs
/etc/permissions(/.*)? u:object_r:vendor_configs_file:s0
# binary
-/bin/hw/android\.hardware\.usb@1\.0-service u:object_r:hal_usb_default_exec:s0
\ No newline at end of file
+/bin/hw/android\.hardware\.usb-service\.example u:object_r:hal_usb_default_exec:s0
\ No newline at end of file
diff --git a/usb/apex/manifest.json b/usb/apex/manifest.json
new file mode 100644
index 0000000..1a41b90
--- /dev/null
+++ b/usb/apex/manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.hardware.usb",
+ "version": 1
+}
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index ddc6ee0..01602ab 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -59,7 +59,10 @@
const std::shared_ptr<IVibratorCallback>& callback) {
LOG(VERBOSE) << "Vibrator on for timeoutMs: " << timeoutMs;
if (callback != nullptr) {
- std::thread([=] {
+ // Note that thread lambdas aren't using implicit capture [=], to avoid capturing "this",
+ // which may be asynchronously destructed.
+ // If "this" is needed, use [sharedThis = this->ref<Vibrator>()].
+ std::thread([timeoutMs, callback] {
LOG(VERBOSE) << "Starting on on another thread";
usleep(timeoutMs * 1000);
LOG(VERBOSE) << "Notifying on complete";
@@ -87,7 +90,7 @@
constexpr size_t kEffectMillis = 100;
if (callback != nullptr) {
- std::thread([=] {
+ std::thread([callback] {
LOG(VERBOSE) << "Starting perform on another thread";
usleep(kEffectMillis * 1000);
LOG(VERBOSE) << "Notifying perform complete";
@@ -174,7 +177,8 @@
}
}
- std::thread([=] {
+ // The thread may theoretically outlive the vibrator, so take a proper reference to it.
+ std::thread([sharedThis = this->ref<Vibrator>(), composite, callback] {
LOG(VERBOSE) << "Starting compose on another thread";
for (auto& e : composite) {
@@ -185,7 +189,7 @@
<< e.scale;
int32_t durationMs;
- getPrimitiveDuration(e.primitive, &durationMs);
+ sharedThis->getPrimitiveDuration(e.primitive, &durationMs);
usleep(durationMs * 1000);
}
@@ -396,7 +400,7 @@
}
}
- std::thread([=] {
+ std::thread([totalDuration, callback] {
LOG(VERBOSE) << "Starting composePwle on another thread";
usleep(totalDuration * 1000);
if (callback != nullptr) {
diff --git a/vibrator/aidl/default/VibratorManager.cpp b/vibrator/aidl/default/VibratorManager.cpp
index 7cf9e6a..26edf5a 100644
--- a/vibrator/aidl/default/VibratorManager.cpp
+++ b/vibrator/aidl/default/VibratorManager.cpp
@@ -66,7 +66,7 @@
ndk::ScopedAStatus VibratorManager::triggerSynced(
const std::shared_ptr<IVibratorCallback>& callback) {
LOG(INFO) << "Vibrator Manager trigger synced";
- std::thread([=] {
+ std::thread([callback] {
if (callback != nullptr) {
LOG(INFO) << "Notifying perform complete";
callback->onComplete();
diff --git a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
index 44fa3be..e8ed26a 100644
--- a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
@@ -96,6 +96,7 @@
if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
if (vibratorIds.empty()) return;
EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+ EXPECT_TRUE(manager->cancelSynced().isOk());
}
TEST_P(VibratorAidl, PrepareSyncedEmptySetIsInvalid) {
@@ -208,6 +209,7 @@
EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
Status status = manager->triggerSynced(callback);
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_TRUE(manager->cancelSynced().isOk());
}
}