Merge Android 13 QPR1

Bug: 261731544
Merged-In: I4fe9ddd1c22ebfff03f5660ec9b01de2521f8533
Change-Id: Ic59ecf4fbb0438607c4069829426fbdfa7c7abd1
This commit is contained in:
Xin Li
2022-12-09 10:29:52 -08:00
22 changed files with 1076 additions and 86 deletions

View File

@@ -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

View File

@@ -238,12 +238,27 @@ void Effect::effectOffloadParamToHal(const EffectOffloadParameter& offload,
}
// 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 @@ std::vector<uint8_t> Effect::parameterToHal(uint32_t paramSize, const void* para
*valueData = halParam->data + valueOffsetFromData;
}
}
return halParamBuffer;
return true;
}
Result Effect::analyzeCommandStatus(const char* commandName, const char* context, status_t status) {
@@ -301,6 +316,11 @@ void Effect::getConfigImpl(int commandCode, const char* commandName, GetConfigCa
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 @@ Result Effect::getParameterImpl(uint32_t paramSize, const void* paramData,
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::getParameterImpl(uint32_t paramSize, const void* paramData,
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::setConfigImpl(int commandCode, const char* commandName, const Eff
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]);
}

View File

@@ -184,6 +184,9 @@ struct Effect : public IEffect {
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 @@ struct Effect : public IEffect {
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);

View File

@@ -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 @@ TEST_P(AudioEffectHidlTest, GetParameter) {
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 @@ TEST_P(AudioEffectHidlTest, SetCurrentConfigForFeature) {
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:

View File

@@ -33,7 +33,9 @@ parcelable EvsEventDesc {
@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;
}

View File

@@ -47,7 +47,10 @@ oneway interface IEvsCameraStream {
/**
* 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);
}

View File

@@ -84,7 +84,10 @@ cc_library_static {
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 @@ cc_test {
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"],

View File

@@ -1109,6 +1109,19 @@ const ConfigDeclaration kVehicleProperties[]{
},
.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 @@ const ConfigDeclaration kVehicleProperties[]{
},
},
#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

View File

@@ -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

View File

@@ -141,7 +141,7 @@ class DefaultVhalImplTest : public ::testing::Test {
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) {

View File

@@ -40,6 +40,7 @@ using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
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;
@@ -178,6 +179,523 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
},
.initialValue = {.int32Values = {toInt(VehicleUnit::KILOMETERS_PER_HOUR)}}},
{.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),
@@ -359,8 +877,9 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
.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 =
{
@@ -465,6 +984,24 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
},
.initialValue = {.int32Values = {0}}},
{.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),
@@ -493,6 +1030,12 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
.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 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
}}},
.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,
@@ -720,6 +1282,16 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
},
.initialValue = {.int32Values = {toInt(VehicleIgnitionState::ON)}}},
{.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),
@@ -781,6 +1353,76 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
.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 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
.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,
@@ -889,14 +1551,6 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
},
.initialValue = {.int32Values = {LIGHT_STATE_ON}}},
{.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),
@@ -921,6 +1575,24 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
},
.initialValue = {.int32Values = {LIGHT_STATE_ON}}},
{.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),
@@ -937,14 +1609,7 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
},
.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 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
},
.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),
@@ -969,6 +1635,24 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
},
.initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
{.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),

View File

@@ -217,17 +217,16 @@ VhalResult<void> FakeVehicleHardware::setApPowerStateReport(const VehiclePropVal
[[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 @@ StatusCode FakeVehicleHardware::updateSampleRate(int32_t propId, int32_t areaId,
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;

View File

@@ -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>

View File

@@ -46,6 +46,33 @@ class VehiclePropertyStore final {
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 @@ class VehiclePropertyStore final {
// '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.

View File

@@ -48,7 +48,7 @@ void RecurrentTimer::registerTimerCallback(int64_t intervalInNano,
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 @@ void RecurrentTimer::loop() {
}
// 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 @@ void RecurrentTimer::loop() {
{
ScopedLockAssertion lockAssertion(mLock);
int64_t now = elapsedRealtimeNano();
int64_t now = uptimeNanos();
while (mCallbackQueue.size() > 0) {
int64_t nextTime = mCallbackQueue[0]->nextTime;
if (nextTime > now) {

View File

@@ -106,7 +106,8 @@ void VehiclePropertyStore::registerProperty(const VehiclePropConfig& config,
}
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 @@ VhalResult<void> VehiclePropertyStore::writeValue(VehiclePropValuePool::Recyclab
}
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 {};

View File

@@ -448,6 +448,67 @@ TEST_F(VehiclePropertyStoreTest, testPropertyChangeCallbackNoUpdate) {
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

View File

@@ -279,8 +279,10 @@ interface ICameraDevice {
* 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

View File

@@ -107,10 +107,9 @@ ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_inf
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

View File

@@ -59,7 +59,10 @@ ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs,
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 @@ ndk::ScopedAStatus Vibrator::perform(Effect effect, EffectStrength strength,
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 @@ ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect>& composi
}
}
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 @@ ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect>& composi
<< e.scale;
int32_t durationMs;
getPrimitiveDuration(e.primitive, &durationMs);
sharedThis->getPrimitiveDuration(e.primitive, &durationMs);
usleep(durationMs * 1000);
}
@@ -396,7 +400,7 @@ ndk::ScopedAStatus Vibrator::composePwle(const std::vector<PrimitivePwle> &compo
}
}
std::thread([=] {
std::thread([totalDuration, callback] {
LOG(VERBOSE) << "Starting composePwle on another thread";
usleep(totalDuration * 1000);
if (callback != nullptr) {

View File

@@ -66,7 +66,7 @@ ndk::ScopedAStatus VibratorManager::prepareSynced(const std::vector<int32_t>& vi
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();

View File

@@ -96,6 +96,7 @@ TEST_P(VibratorAidl, ValidatePrepareSyncedExistingVibrators) {
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 @@ TEST_P(VibratorAidl, TriggerCallbackNotSupported) {
EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
Status status = manager->triggerSynced(callback);
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
EXPECT_TRUE(manager->cancelSynced().isOk());
}
}