Use FakeUserHal in FakeVehicleHardware.
Handle fake user hal properties in FakeVehicleHardware.
Test: atest FakeVehicleHardwareTest
Bug: 201830716
Change-Id: Ia60bbf7ae6a0fc5909dc8d27363af5c9939055d3
diff --git a/automotive/vehicle/TEST_MAPPING b/automotive/vehicle/TEST_MAPPING
index f55016f..3696351 100644
--- a/automotive/vehicle/TEST_MAPPING
+++ b/automotive/vehicle/TEST_MAPPING
@@ -17,6 +17,9 @@
},
{
"name": "FakeObd2FrameTest"
+ },
+ {
+ "name": "FakeUserHalTest"
}
]
}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
index f59a6ed..dfc2efc 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
@@ -35,6 +35,7 @@
"VehicleHalUtils",
"FakeVehicleHalValueGenerators",
"FakeObd2Frame",
+ "FakeUserHal",
],
shared_libs: [
"libjsoncpp",
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
index e1cd8bd..46a526c 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -19,6 +19,7 @@
#include <DefaultConfig.h>
#include <FakeObd2Frame.h>
+#include <FakeUserHal.h>
#include <IVehicleHardware.h>
#include <VehicleHalTypes.h>
#include <VehiclePropertyStore.h>
@@ -91,6 +92,7 @@
const std::shared_ptr<VehiclePropValuePool> mValuePool;
const std::shared_ptr<VehiclePropertyStore> mServerSidePropStore;
const std::unique_ptr<obd2frame::FakeObd2Frame> mFakeObd2Frame;
+ const std::unique_ptr<FakeUserHal> mFakeUserHal;
std::mutex mCallbackLock;
OnPropertyChangeCallback mOnPropertyChangeCallback GUARDED_BY(mCallbackLock);
OnPropertySetErrorCallback mOnPropertySetErrorCallback GUARDED_BY(mCallbackLock);
@@ -107,16 +109,21 @@
// Override the properties using config files in 'overrideDir'.
void overrideProperties(const char* overrideDir);
- ::aidl::android::hardware::automotive::vehicle::StatusCode maybeSetSpecialValue(
+ ::android::base::Result<void> maybeSetSpecialValue(
const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
bool* isSpecialValue);
::android::base::Result<VehiclePropValuePool::RecyclableType> maybeGetSpecialValue(
const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
bool* isSpecialValue) const;
- ::aidl::android::hardware::automotive::vehicle::StatusCode setApPowerStateReport(
+ ::android::base::Result<void> setApPowerStateReport(
const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
VehiclePropValuePool::RecyclableType createApPowerStateReq(
::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq state);
+ ::android::base::Result<void> setUserHalProp(
+ const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
+ ::android::base::Result<VehiclePropValuePool::RecyclableType> getUserHalProp(
+ const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
+ bool isHvacPropAndHvacNotAvailable(int32_t propId);
};
} // namespace fake
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 15db767..104147a 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <fstream>
#include <regex>
+#include <unordered_set>
#include <vector>
namespace android {
@@ -55,6 +56,7 @@
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::android::base::Error;
using ::android::base::Result;
const char* VENDOR_OVERRIDE_DIR = "/vendor/etc/automotive/vhaloverride/";
@@ -69,6 +71,11 @@
}
template <class T>
+int getIntErrorCode(const Result<T>& result) {
+ return toInt(getErrorCode(result));
+}
+
+template <class T>
std::string getErrorMsg(const Result<T>& result) {
if (result.ok()) {
return "";
@@ -114,7 +121,7 @@
mServerSidePropStore->writeValue(mValuePool->obtain(prop), /*updateStatus=*/true);
if (!result.ok()) {
ALOGE("failed to write default config value, error: %s, status: %d",
- getErrorMsg(result).c_str(), getErrorCode(result));
+ getErrorMsg(result).c_str(), getIntErrorCode(result));
}
}
}
@@ -122,14 +129,16 @@
FakeVehicleHardware::FakeVehicleHardware()
: mValuePool(new VehiclePropValuePool),
mServerSidePropStore(new VehiclePropertyStore(mValuePool)),
- mFakeObd2Frame(new obd2frame::FakeObd2Frame(mServerSidePropStore)) {
+ mFakeObd2Frame(new obd2frame::FakeObd2Frame(mServerSidePropStore)),
+ mFakeUserHal(new FakeUserHal(mValuePool)) {
init();
}
FakeVehicleHardware::FakeVehicleHardware(std::unique_ptr<VehiclePropValuePool> valuePool)
: mValuePool(std::move(valuePool)),
mServerSidePropStore(new VehiclePropertyStore(mValuePool)),
- mFakeObd2Frame(new obd2frame::FakeObd2Frame(mServerSidePropStore)) {
+ mFakeObd2Frame(new obd2frame::FakeObd2Frame(mServerSidePropStore)),
+ mFakeUserHal(new FakeUserHal(mValuePool)) {
init();
}
@@ -179,16 +188,14 @@
return req;
}
-StatusCode FakeVehicleHardware::setApPowerStateReport(const VehiclePropValue& value) {
+Result<void> FakeVehicleHardware::setApPowerStateReport(const VehiclePropValue& value) {
auto updatedValue = mValuePool->obtain(value);
updatedValue->timestamp = elapsedRealtimeNano();
if (auto writeResult = mServerSidePropStore->writeValue(std::move(updatedValue));
!writeResult.ok()) {
- StatusCode errorCode = getErrorCode(writeResult);
- ALOGE("failed to write value into property store, error: %s, code: %d",
- getErrorMsg(writeResult).c_str(), errorCode);
- return errorCode;
+ return Error(getIntErrorCode(writeResult))
+ << "failed to write value into property store, error: " << getErrorMsg(writeResult);
}
VehiclePropValuePool::RecyclableType prop;
@@ -208,10 +215,9 @@
if (auto writeResult =
mServerSidePropStore->writeValue(std::move(prop), /*updateStatus=*/true);
!writeResult.ok()) {
- StatusCode errorCode = getErrorCode(writeResult);
- ALOGE("failed to write AP_POWER_STATE_REQ into property store, error: %s, code: %d",
- getErrorMsg(writeResult).c_str(), errorCode);
- return errorCode;
+ return Error(getIntErrorCode(writeResult))
+ << "failed to write AP_POWER_STATE_REQ into property store, error: "
+ << getErrorMsg(writeResult);
}
break;
case toInt(VehicleApPowerStateReport::DEEP_SLEEP_ENTRY):
@@ -226,17 +232,73 @@
if (auto writeResult =
mServerSidePropStore->writeValue(std::move(prop), /*updateStatus=*/true);
!writeResult.ok()) {
- StatusCode errorCode = getErrorCode(writeResult);
- ALOGE("failed to write AP_POWER_STATE_REQ into property store, error: %s, code: %d",
- getErrorMsg(writeResult).c_str(), errorCode);
- return errorCode;
+ return Error(getIntErrorCode(writeResult))
+ << "failed to write AP_POWER_STATE_REQ into property store, error: "
+ << getErrorMsg(writeResult);
}
break;
default:
ALOGE("Unknown VehicleApPowerStateReport: %d", state);
break;
}
- return StatusCode::OK;
+ return {};
+}
+
+bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId) {
+ std::unordered_set<int32_t> powerProps(std::begin(HVAC_POWER_PROPERTIES),
+ std::end(HVAC_POWER_PROPERTIES));
+ if (powerProps.count(propId)) {
+ auto hvacPowerOnResult =
+ mServerSidePropStore->readValue(toInt(VehicleProperty::HVAC_POWER_ON), HVAC_ALL);
+
+ if (hvacPowerOnResult.ok() && hvacPowerOnResult.value()->value.int32Values.size() == 1 &&
+ hvacPowerOnResult.value()->value.int32Values[0] == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+Result<void> FakeVehicleHardware::setUserHalProp(const VehiclePropValue& value) {
+ auto result = mFakeUserHal->onSetProperty(value);
+ if (!result.ok()) {
+ return Error(getIntErrorCode(result))
+ << "onSetProperty(): HAL returned error: " << getErrorMsg(result);
+ }
+ auto& updatedValue = result.value();
+ if (updatedValue != nullptr) {
+ ALOGI("onSetProperty(): updating property returned by HAL: %s",
+ updatedValue->toString().c_str());
+ if (auto writeResult = mServerSidePropStore->writeValue(std::move(result.value()));
+ !writeResult.ok()) {
+ return Error(getIntErrorCode(writeResult))
+ << "failed to write value into property store, error: "
+ << getErrorMsg(writeResult);
+ }
+ }
+ return {};
+}
+
+Result<VehiclePropValuePool::RecyclableType> FakeVehicleHardware::getUserHalProp(
+ const VehiclePropValue& value) const {
+ auto propId = value.prop;
+ ALOGI("get(): getting value for prop %d from User HAL", propId);
+
+ auto result = mFakeUserHal->onGetProperty(value);
+ if (!result.ok()) {
+ return Error(getIntErrorCode(result))
+ << "get(): User HAL returned error: " << getErrorMsg(result);
+ } else {
+ auto& gotValue = result.value();
+ if (gotValue != nullptr) {
+ ALOGI("get(): User HAL returned value: %s", gotValue->toString().c_str());
+ gotValue->timestamp = elapsedRealtimeNano();
+ return result;
+ } else {
+ return Error(toInt(StatusCode::INTERNAL_ERROR))
+ << "get(): User HAL returned null value";
+ }
+ }
}
Result<VehiclePropValuePool::RecyclableType> FakeVehicleHardware::maybeGetSpecialValue(
@@ -245,6 +307,11 @@
int32_t propId = value.prop;
Result<VehiclePropValuePool::RecyclableType> result;
+ if (mFakeUserHal->isSupported(propId)) {
+ *isSpecialValue = true;
+ return getUserHalProp(value);
+ }
+
switch (propId) {
case OBD2_FREEZE_FRAME:
*isSpecialValue = true;
@@ -268,12 +335,23 @@
return nullptr;
}
-StatusCode FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValue& value,
- bool* isSpecialValue) {
+Result<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValue& value,
+ bool* isSpecialValue) {
*isSpecialValue = false;
VehiclePropValuePool::RecyclableType updatedValue;
+ int32_t propId = value.prop;
- switch (value.prop) {
+ if (mFakeUserHal->isSupported(propId)) {
+ *isSpecialValue = true;
+ return setUserHalProp(value);
+ }
+
+ if (isHvacPropAndHvacNotAvailable(propId)) {
+ *isSpecialValue = true;
+ return Error(toInt(StatusCode::NOT_AVAILABLE)) << "hvac not available";
+ }
+
+ switch (propId) {
case toInt(VehicleProperty::AP_POWER_STATE_REPORT):
*isSpecialValue = true;
return setApPowerStateReport(value);
@@ -281,7 +359,7 @@
// Placeholder for future implementation of VMS property in the default hal. For
// now, just returns OK; otherwise, hal clients crash with property not supported.
*isSpecialValue = true;
- return StatusCode::OK;
+ return {};
case OBD2_FREEZE_FRAME_CLEAR:
*isSpecialValue = true;
return mFakeObd2Frame->clearObd2FreezeFrames(value);
@@ -309,18 +387,17 @@
updatedValue->areaId = value.areaId;
if (auto writeResult = mServerSidePropStore->writeValue(std::move(updatedValue));
!writeResult.ok()) {
- StatusCode errorCode = getErrorCode(writeResult);
- ALOGE("failed to write value into property store, error: %s, code: %d",
- getErrorMsg(writeResult).c_str(), errorCode);
- return errorCode;
+ return Error(getIntErrorCode(writeResult))
+ << "failed to write value into property store, error: "
+ << getErrorMsg(writeResult);
}
- return StatusCode::OK;
+ return {};
#endif // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
default:
break;
}
- return StatusCode::OK;
+ return {};
}
StatusCode FakeVehicleHardware::setValues(FakeVehicleHardware::SetValuesCallback&& callback,
@@ -338,13 +415,14 @@
setValueResult.status = StatusCode::OK;
bool isSpecialValue = false;
- StatusCode status = maybeSetSpecialValue(value, &isSpecialValue);
+ auto setSpecialValueResult = maybeSetSpecialValue(value, &isSpecialValue);
if (isSpecialValue) {
- if (status != StatusCode::OK) {
- ALOGE("failed to set special value for property ID: %d, status: %d", propId,
- status);
- setValueResult.status = status;
+ if (!setSpecialValueResult.ok()) {
+ ALOGE("failed to set special value for property ID: %d, error: %s, status: %d",
+ propId, getErrorMsg(setSpecialValueResult).c_str(),
+ getIntErrorCode(setSpecialValueResult));
+ setValueResult.status = getErrorCode(setSpecialValueResult);
}
// Special values are already handled.
@@ -358,10 +436,9 @@
auto writeResult = mServerSidePropStore->writeValue(std::move(updatedValue));
if (!writeResult.ok()) {
- StatusCode errorCode = getErrorCode(writeResult);
ALOGE("failed to write value into property store, error: %s, code: %d",
- getErrorMsg(writeResult).c_str(), errorCode);
- setValueResult.status = errorCode;
+ getErrorMsg(writeResult).c_str(), getIntErrorCode(writeResult));
+ setValueResult.status = getErrorCode(writeResult);
}
results.push_back(std::move(setValueResult));
}
@@ -387,10 +464,9 @@
auto result = maybeGetSpecialValue(value, &isSpecialValue);
if (isSpecialValue) {
if (!result.ok()) {
- StatusCode errorCode = getErrorCode(result);
ALOGE("failed to get special value: %d, error: %s, code: %d", value.prop,
- getErrorMsg(result).c_str(), errorCode);
- getValueResult.status = errorCode;
+ getErrorMsg(result).c_str(), getIntErrorCode(result));
+ getValueResult.status = getErrorCode(result);
} else {
getValueResult.status = StatusCode::OK;
getValueResult.prop = *result.value();
@@ -406,7 +482,7 @@
ALOGW("%s", "value has not been set yet");
} else {
ALOGE("failed to get value, error: %s, code: %d", getErrorMsg(readResult).c_str(),
- errorCode);
+ toInt(errorCode));
}
getValueResult.status = errorCode;
} else {
@@ -476,7 +552,7 @@
/*updateStatus=*/true);
!result.ok()) {
ALOGW("failed to write vendor override properties: %d, error: %s, code: %d",
- prop.prop, getErrorMsg(result).c_str(), getErrorCode(result));
+ prop.prop, getErrorMsg(result).c_str(), getIntErrorCode(result));
}
}
}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
index b40c906..90d1516 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
@@ -33,6 +33,7 @@
"FakeVehicleHardware",
"FakeVehicleHalValueGenerators",
"FakeObd2Frame",
+ "FakeUserHal",
"libgtest",
"libgmock",
],
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index 6f59ce7..88834f3 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -18,6 +18,7 @@
#include <DefaultConfig.h>
#include <FakeObd2Frame.h>
+#include <FakeUserHal.h>
#include <PropertyUtils.h>
#include <TestPropertyUtils.h>
@@ -74,7 +75,12 @@
class FakeVehicleHardwareTest : public ::testing::Test {
protected:
- void SetUp() override {}
+ void SetUp() override {
+ getHardware()->registerOnPropertyChangeEvent(
+ [this](const std::vector<VehiclePropValue>& values) {
+ return onPropertyChangeEvent(values);
+ });
+ }
FakeVehicleHardware* getHardware() { return &mHardware; }
@@ -171,6 +177,8 @@
const std::vector<VehiclePropValue>& getChangedProperties() { return mChangedProperties; }
+ void clearChangedProperties() { mChangedProperties.clear(); }
+
static void addSetValueRequest(std::vector<SetValueRequest>& requests,
std::vector<SetValueResult>& expectedResults, int64_t requestId,
const VehiclePropValue& value, StatusCode expectedStatus) {
@@ -257,6 +265,11 @@
continue;
}
+ if (FakeUserHal::isSupported(config.config.prop)) {
+ // Ignore fake user HAL properties, they have special logic for getting values.
+ continue;
+ }
+
int propId = config.config.prop;
if (isGlobalProp(propId)) {
if (config.initialValue == RawPropValues{}) {
@@ -353,6 +366,7 @@
}
TEST_F(FakeVehicleHardwareTest, testRegisterOnPropertyChangeEvent) {
+ // We have already registered this callback in Setup, here we are registering again.
getHardware()->registerOnPropertyChangeEvent(std::bind(
&FakeVehicleHardwareTest_testRegisterOnPropertyChangeEvent_Test::onPropertyChangeEvent,
this, std::placeholders::_1));
@@ -870,11 +884,6 @@
public testing::WithParamInterface<SetSpecialValueTestCase> {};
TEST_P(FakeVehicleHardwareSpecialValuesTest, testSetSpecialProperties) {
- getHardware()->registerOnPropertyChangeEvent(
- [this](const std::vector<VehiclePropValue>& values) {
- return onPropertyChangeEvent(values);
- });
-
const SetSpecialValueTestCase& tc = GetParam();
for (const auto& value : tc.valuesToSet) {
@@ -970,6 +979,227 @@
EXPECT_EQ(getValueResult.error(), StatusCode::NOT_AVAILABLE);
}
+TEST_F(FakeVehicleHardwareTest, testGetUserPropertySetOnly) {
+ for (VehicleProperty prop : std::vector<VehicleProperty>({
+ VehicleProperty::INITIAL_USER_INFO,
+ VehicleProperty::SWITCH_USER,
+ VehicleProperty::CREATE_USER,
+ VehicleProperty::REMOVE_USER,
+ })) {
+ auto result = getValue(VehiclePropValue{.prop = toInt(prop)});
+
+ EXPECT_FALSE(result.ok());
+ if (!result.ok()) {
+ EXPECT_EQ(result.error(), StatusCode::INVALID_ARG);
+ }
+ }
+}
+
+TEST_F(FakeVehicleHardwareTest, testGetUserIdAssoc) {
+ int32_t userIdAssocProp = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION);
+
+ auto result = getValue(VehiclePropValue{.prop = userIdAssocProp});
+
+ // Default returns NOT_AVAILABLE.
+ ASSERT_FALSE(result.ok());
+ ASSERT_EQ(result.error(), StatusCode::NOT_AVAILABLE);
+
+ // This is the same example as used in User HAL Emulation doc.
+ VehiclePropValue valueToSet = {
+ .prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION),
+ .areaId = 1,
+ .value.int32Values = {666, 1, 1, 2},
+ };
+
+ StatusCode status = setValue(valueToSet);
+
+ ASSERT_EQ(status, StatusCode::OK);
+
+ result = getValue(VehiclePropValue{
+ .prop = userIdAssocProp,
+ // Request ID
+ .value.int32Values = {1},
+ });
+
+ ASSERT_TRUE(result.ok());
+
+ auto& gotValue = result.value();
+ gotValue.timestamp = 0;
+
+ // Expect to get the same request ID.
+ valueToSet.value.int32Values[0] = 1;
+
+ ASSERT_EQ(gotValue, valueToSet);
+}
+
+TEST_F(FakeVehicleHardwareTest, testSwitchUser) {
+ // This is the same example as used in User HAL Emulation doc.
+ VehiclePropValue valueToSet = {
+ .prop = toInt(VehicleProperty::SWITCH_USER),
+ .areaId = 1,
+ .value.int32Values = {666, 3, 2},
+ };
+
+ StatusCode status = setValue(valueToSet);
+
+ ASSERT_EQ(status, StatusCode::OK);
+
+ // Simulate a request from Android side.
+ VehiclePropValue switchUserRequest = {
+ .prop = toInt(VehicleProperty::SWITCH_USER),
+ .areaId = 0,
+ .value.int32Values = {666, 3},
+ };
+ // Clear existing events.
+ clearChangedProperties();
+
+ status = setValue(switchUserRequest);
+
+ ASSERT_EQ(status, StatusCode::OK);
+
+ // Should generate an event for user hal response.
+ auto events = getChangedProperties();
+ ASSERT_EQ(events.size(), static_cast<size_t>(1));
+
+ events[0].timestamp = 0;
+ ASSERT_EQ(events[0], valueToSet);
+
+ // Try to get switch_user again, should return default value.
+ clearChangedProperties();
+ status = setValue(switchUserRequest);
+ ASSERT_EQ(status, StatusCode::OK);
+
+ events = getChangedProperties();
+ ASSERT_EQ(events.size(), static_cast<size_t>(1));
+ events[0].timestamp = 0;
+ ASSERT_EQ(events[0], (VehiclePropValue{
+ .areaId = 0,
+ .prop = toInt(VehicleProperty::SWITCH_USER),
+ .value.int32Values =
+ {
+ // Request ID
+ 666,
+ // VEHICLE_RESPONSE
+ 3,
+ // SUCCESS
+ 1,
+ },
+ }));
+}
+
+TEST_F(FakeVehicleHardwareTest, testCreateUser) {
+ // This is the same example as used in User HAL Emulation doc.
+ VehiclePropValue valueToSet = {
+ .prop = toInt(VehicleProperty::CREATE_USER),
+ .areaId = 1,
+ .value.int32Values = {666, 2},
+ };
+
+ StatusCode status = setValue(valueToSet);
+
+ ASSERT_EQ(status, StatusCode::OK);
+
+ // Simulate a request from Android side.
+ VehiclePropValue createUserRequest = {
+ .prop = toInt(VehicleProperty::CREATE_USER),
+ .areaId = 0,
+ .value.int32Values = {666},
+ };
+ // Clear existing events.
+ clearChangedProperties();
+
+ status = setValue(createUserRequest);
+
+ ASSERT_EQ(status, StatusCode::OK);
+
+ // Should generate an event for user hal response.
+ auto events = getChangedProperties();
+ ASSERT_EQ(events.size(), static_cast<size_t>(1));
+ events[0].timestamp = 0;
+ EXPECT_EQ(events[0], valueToSet);
+
+ // Try to get create_user again, should return default value.
+ clearChangedProperties();
+ status = setValue(createUserRequest);
+ ASSERT_EQ(status, StatusCode::OK);
+
+ events = getChangedProperties();
+ ASSERT_EQ(events.size(), static_cast<size_t>(1));
+ events[0].timestamp = 0;
+ ASSERT_EQ(events[0], (VehiclePropValue{
+ .areaId = 0,
+ .prop = toInt(VehicleProperty::CREATE_USER),
+ .value.int32Values =
+ {
+ // Request ID
+ 666,
+ // SUCCESS
+ 1,
+ },
+ }));
+}
+
+TEST_F(FakeVehicleHardwareTest, testInitialUserInfo) {
+ // This is the same example as used in User HAL Emulation doc.
+ VehiclePropValue valueToSet = {
+ .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
+ .areaId = 1,
+ .value.int32Values = {666, 1, 11},
+ };
+
+ StatusCode status = setValue(valueToSet);
+
+ ASSERT_EQ(status, StatusCode::OK);
+
+ // Simulate a request from Android side.
+ VehiclePropValue initialUserInfoRequest = {
+ .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
+ .areaId = 0,
+ .value.int32Values = {3},
+ };
+ // Clear existing events.
+ clearChangedProperties();
+
+ status = setValue(initialUserInfoRequest);
+
+ ASSERT_EQ(status, StatusCode::OK);
+
+ // Should generate an event for user hal response.
+ auto events = getChangedProperties();
+ ASSERT_EQ(events.size(), static_cast<size_t>(1));
+ events[0].timestamp = 0;
+ EXPECT_EQ(events[0], (VehiclePropValue{
+ .areaId = 1,
+ .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
+ .value.int32Values = {3, 1, 11},
+ }));
+
+ // Try to get create_user again, should return default value.
+ clearChangedProperties();
+ status = setValue(initialUserInfoRequest);
+ ASSERT_EQ(status, StatusCode::OK);
+
+ events = getChangedProperties();
+ ASSERT_EQ(events.size(), static_cast<size_t>(1));
+ events[0].timestamp = 0;
+ EXPECT_EQ(events[0], (VehiclePropValue{
+ .areaId = 0,
+ .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
+ .value.int32Values =
+ {
+ // Request ID
+ 3,
+ // ACTION: DEFAULT
+ 0,
+ // User id: 0
+ 0,
+ // Flags: 0
+ 0,
+ },
+ .value.stringValue = "||",
+ }));
+}
+
} // namespace fake
} // namespace vehicle
} // namespace automotive
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/include/FakeObd2Frame.h b/automotive/vehicle/aidl/impl/fake_impl/obd2frame/include/FakeObd2Frame.h
index aee6866..118bb34 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/include/FakeObd2Frame.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/obd2frame/include/FakeObd2Frame.h
@@ -42,7 +42,7 @@
const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue&
requestedPropValue) const;
::android::base::Result<VehiclePropValuePool::RecyclableType> getObd2DtcInfo() const;
- ::aidl::android::hardware::automotive::vehicle::StatusCode clearObd2FreezeFrames(
+ ::android::base::Result<void> clearObd2FreezeFrames(
const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue);
static bool isDiagnosticProperty(
const ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig& propConfig);
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/src/FakeObd2Frame.cpp b/automotive/vehicle/aidl/impl/fake_impl/obd2frame/src/FakeObd2Frame.cpp
index a9e865d..5585fb4 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/src/FakeObd2Frame.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/obd2frame/src/FakeObd2Frame.cpp
@@ -169,20 +169,21 @@
return outValue;
}
-StatusCode FakeObd2Frame::clearObd2FreezeFrames(const VehiclePropValue& propValue) {
+Result<void> FakeObd2Frame::clearObd2FreezeFrames(const VehiclePropValue& propValue) {
if (propValue.value.int64Values.size() == 0) {
mPropStore->removeValuesForProperty(OBD2_FREEZE_FRAME);
- return StatusCode::OK;
+ return {};
}
for (int64_t timestamp : propValue.value.int64Values) {
- auto result = mPropStore->readValue(OBD2_FREEZE_FRAME, /*area=*/0, timestamp);
+ auto result = mPropStore->readValue(OBD2_FREEZE_FRAME, 0, timestamp);
if (!result.ok()) {
- ALOGE("asked for OBD2_FREEZE_FRAME at invalid timestamp");
- return StatusCode::INVALID_ARG;
+ return Error(toInt(StatusCode::INVALID_ARG))
+ << "asked for OBD2_FREEZE_FRAME at invalid timestamp, error: %s"
+ << result.error().message();
}
mPropStore->removeValue(*result.value());
}
- return StatusCode::OK;
+ return {};
}
bool FakeObd2Frame::isDiagnosticProperty(const VehiclePropConfig& propConfig) {
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/FakeObd2FrameTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/FakeObd2FrameTest.cpp
index 987115a..54ec1b2 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/FakeObd2FrameTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/FakeObd2FrameTest.cpp
@@ -167,7 +167,7 @@
ASSERT_EQ(result.value()->prop, OBD2_FREEZE_FRAME_INFO);
ASSERT_EQ(result.value()->value.int64Values.size(), static_cast<size_t>(3));
- getFakeObd2Frame()->clearObd2FreezeFrames(VehiclePropValue{});
+ ASSERT_TRUE(getFakeObd2Frame()->clearObd2FreezeFrames(VehiclePropValue{}).ok());
result = getFakeObd2Frame()->getObd2DtcInfo();
@@ -185,9 +185,11 @@
ASSERT_EQ(result.value()->prop, OBD2_FREEZE_FRAME_INFO);
ASSERT_EQ(result.value()->value.int64Values.size(), static_cast<size_t>(3));
- getFakeObd2Frame()->clearObd2FreezeFrames(
- VehiclePropValue{.value.int64Values = {result.value()->value.int64Values[0],
- result.value()->value.int64Values[1]}});
+ ASSERT_TRUE(getFakeObd2Frame()
+ ->clearObd2FreezeFrames(VehiclePropValue{
+ .value.int64Values = {result.value()->value.int64Values[0],
+ result.value()->value.int64Values[1]}})
+ .ok());
result = getFakeObd2Frame()->getObd2DtcInfo();
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h b/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
index 441c54b..2743578 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
@@ -107,7 +107,7 @@
constexpr int HVAC_RIGHT = SEAT_1_RIGHT | SEAT_2_RIGHT;
constexpr int HVAC_ALL = HVAC_LEFT | HVAC_RIGHT;
-const int32_t kHvacPowerProperties[] = {
+const int32_t HVAC_POWER_PROPERTIES[] = {
toInt(propertyutils_impl::VehicleProperty::HVAC_FAN_SPEED),
toInt(propertyutils_impl::VehicleProperty::HVAC_FAN_DIRECTION),
};