Loading automotive/vehicle/2.0/default/Android.bp +2 −1 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ cc_library_static { local_include_dirs: ["common/include/vhal_v2_0"], export_include_dirs: ["impl"], whole_static_libs: [ "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib", "android.hardware.automotive.vehicle@2.0-manager-lib", ], shared_libs: [ Loading Loading @@ -215,8 +216,8 @@ cc_test { "android.hardware.automotive.vehicle@2.0-libproto-native", ], data: [ ":vhal_test_override_json", ":vhal_test_json", ":vhal_test_override_json", ], test_suites: ["general-tests"], } Loading automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp +78 −0 Original line number Diff line number Diff line Loading @@ -89,11 +89,38 @@ DefaultVehicleHal::DefaultVehicleHal(VehiclePropertyStore* propStore, VehicleHal }); } VehicleHal::VehiclePropValuePtr DefaultVehicleHal::getUserHalProp( const VehiclePropValue& requestedPropValue, StatusCode* outStatus) { auto propId = requestedPropValue.prop; ALOGI("get(): getting value for prop %d from User HAL", propId); const auto& ret = mEmulatedUserHal.onGetProperty(requestedPropValue); VehicleHal::VehiclePropValuePtr v = nullptr; if (!ret.ok()) { ALOGE("get(): User HAL returned error: %s", ret.error().message().c_str()); *outStatus = StatusCode(ret.error().code()); } else { auto value = ret.value().get(); if (value != nullptr) { ALOGI("get(): User HAL returned value: %s", toString(*value).c_str()); v = getValuePool()->obtain(*value); *outStatus = StatusCode::OK; } else { ALOGE("get(): User HAL returned null value"); *outStatus = StatusCode::INTERNAL_ERROR; } } return addTimestamp(std::move(v)); } VehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(const VehiclePropValue& requestedPropValue, StatusCode* outStatus) { auto propId = requestedPropValue.prop; ALOGV("get(%d)", propId); if (mEmulatedUserHal.isSupported(propId)) { return getUserHalProp(requestedPropValue, outStatus); } VehiclePropValuePtr v = nullptr; if (propId == OBD2_FREEZE_FRAME) { v = getValuePool()->obtainComplex(); Loading Loading @@ -127,6 +154,36 @@ std::vector<VehiclePropConfig> DefaultVehicleHal::listProperties() { } bool DefaultVehicleHal::dump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) { int nativeFd = fd->data[0]; if (nativeFd < 0) { ALOGW("Invalid fd from HIDL handle: %d", nativeFd); return false; } if (options.size() > 0) { if (options[0] == "--help") { std::string buffer; buffer += "Emulated user hal usage:\n"; buffer += mEmulatedUserHal.showDumpHelp(); buffer += "\n"; buffer += "VHAL server debug usage:\n"; buffer += "--debughal: send debug command to VHAL server, see '--debughal --help'\n"; buffer += "\n"; dprintf(nativeFd, "%s", buffer.c_str()); return false; } else if (options[0] == kUserHalDumpOption) { dprintf(nativeFd, "%s", mEmulatedUserHal.dump("").c_str()); return false; } } else { // No options, dump the emulated user hal state first and then send command to VHAL server // to dump its state. std::string buffer; buffer += "Emulator user hal state:\n"; buffer += mEmulatedUserHal.dump(" "); buffer += "\n"; dprintf(nativeFd, "%s", buffer.c_str()); } return mVehicleClient->dump(fd, options); } Loading Loading @@ -285,6 +342,23 @@ StatusCode DefaultVehicleHal::checkValueRange(const VehiclePropValue& value, return StatusCode::OK; } StatusCode DefaultVehicleHal::setUserHalProp(const VehiclePropValue& propValue) { ALOGI("onSetProperty(): property %d will be handled by UserHal", propValue.prop); const auto& ret = mEmulatedUserHal.onSetProperty(propValue); if (!ret.ok()) { ALOGE("onSetProperty(): HAL returned error: %s", ret.error().message().c_str()); return StatusCode(ret.error().code()); } auto updatedValue = ret.value().get(); if (updatedValue != nullptr) { ALOGI("onSetProperty(): updating property returned by HAL: %s", toString(*updatedValue).c_str()); onPropertyValue(*updatedValue, true); } return StatusCode::OK; } StatusCode DefaultVehicleHal::set(const VehiclePropValue& propValue) { if (propValue.status != VehiclePropertyStatus::AVAILABLE) { // Android side cannot set property status - this value is the Loading @@ -293,6 +367,10 @@ StatusCode DefaultVehicleHal::set(const VehiclePropValue& propValue) { return StatusCode::INVALID_ARG; } if (mEmulatedUserHal.isSupported(propValue.prop)) { return setUserHalProp(propValue); } std::unordered_set<int32_t> powerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)); if (powerProps.count(propValue.prop)) { Loading automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h +7 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <vhal_v2_0/VehicleHal.h> #include <vhal_v2_0/VehiclePropertyStore.h> #include "EmulatedUserHal.h" #include "VehicleHalClient.h" namespace android { Loading Loading @@ -55,6 +56,7 @@ class DefaultVehicleHal : public VehicleHal { VehiclePropertyStore* mPropStore; RecurrentTimer mRecurrentTimer; VehicleHalClient* mVehicleClient; EmulatedUserHal mEmulatedUserHal; // The callback that would be called when a property value is updated. This function could // be extended to handle specific property update event. Loading @@ -79,6 +81,11 @@ class DefaultVehicleHal : public VehicleHal { // Register the heart beat event to be sent every 3s. This is required to inform watch dog that // VHAL is alive. Subclasses should always calls this function during onCreate. void registerHeartBeatEvent(); // Get a user HAL property. VehiclePropValuePtr getUserHalProp(const VehiclePropValue& requestedPropValue, StatusCode* outStatus); // Set a user HAL property. StatusCode setUserHalProp(const VehiclePropValue& propValue); // Create a VHAL heart beat property. VehicleHal::VehiclePropValuePtr createVhalHeartBeatProp(); Loading automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp +216 −0 Original line number Diff line number Diff line Loading @@ -1047,4 +1047,220 @@ TEST_F(DefaultVhalImplTest, testClearObd2FreezeFrameOneFrame) { ASSERT_EQ(StatusCode::INVALID_ARG, status); } TEST_F(DefaultVhalImplTest, testGetUserPropertySetOnly) { VehiclePropValue value; value.prop = toInt(VehicleProperty::INITIAL_USER_INFO); StatusCode status; mHal->get(value, &status); ASSERT_EQ(StatusCode::INVALID_ARG, status); value.prop = toInt(VehicleProperty::SWITCH_USER); mHal->get(value, &status); ASSERT_EQ(StatusCode::INVALID_ARG, status); value.prop = toInt(VehicleProperty::CREATE_USER); mHal->get(value, &status); ASSERT_EQ(StatusCode::INVALID_ARG, status); value.prop = toInt(VehicleProperty::REMOVE_USER); mHal->get(value, &status); ASSERT_EQ(StatusCode::INVALID_ARG, status); } TEST_F(DefaultVhalImplTest, testGetUserIdAssoc) { VehiclePropValue value; value.prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION); StatusCode status; mHal->get(value, &status); // Default returns NOT_AVAILABLE. ASSERT_EQ(StatusCode::NOT_AVAILABLE, status); // This is the same example as used in User HAL Emulation doc. VehiclePropValue setValue = { .prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION), .areaId = 1, .value.int32Values = {666, 1, 1, 2}, }; status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); auto gotValue = mHal->get(value, &status); ASSERT_EQ(StatusCode::OK, status); ASSERT_EQ((size_t)4, gotValue->value.int32Values.size()); EXPECT_EQ(1, gotValue->areaId); EXPECT_EQ(666, gotValue->value.int32Values[0]); EXPECT_EQ(1, gotValue->value.int32Values[1]); EXPECT_EQ(1, gotValue->value.int32Values[2]); EXPECT_EQ(2, gotValue->value.int32Values[3]); EXPECT_EQ(toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION), gotValue->prop); } TEST_F(DefaultVhalImplTest, testSwitchUser) { // This is the same example as used in User HAL Emulation doc. VehiclePropValue setValue = { .prop = toInt(VehicleProperty::SWITCH_USER), .areaId = 1, .value.int32Values = {666, 3, 2}, }; auto status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); // Simulate a request from Android side. setValue = { .prop = toInt(VehicleProperty::SWITCH_USER), .areaId = 0, .value.int32Values = {666, 3}, }; // Clear existing events. mEventQueue.flush(); status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); // Should generate an event for user hal response. auto events = mEventQueue.flush(); ASSERT_EQ((size_t)1, events.size()); EXPECT_EQ(1, events[0]->areaId); EXPECT_EQ(toInt(VehicleProperty::SWITCH_USER), events[0]->prop); ASSERT_EQ((size_t)3, events[0]->value.int32Values.size()); EXPECT_EQ(666, events[0]->value.int32Values[0]); EXPECT_EQ(3, events[0]->value.int32Values[1]); EXPECT_EQ(2, events[0]->value.int32Values[2]); // Try to get switch_user again, should return default value. status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); events = mEventQueue.flush(); ASSERT_EQ((size_t)1, events.size()); EXPECT_EQ(0, events[0]->areaId); EXPECT_EQ(toInt(VehicleProperty::SWITCH_USER), events[0]->prop); ASSERT_EQ((size_t)3, events[0]->value.int32Values.size()); // Request ID EXPECT_EQ(666, events[0]->value.int32Values[0]); // VEHICLE_RESPONSE EXPECT_EQ(3, events[0]->value.int32Values[1]); // SUCCESS EXPECT_EQ(1, events[0]->value.int32Values[2]); } TEST_F(DefaultVhalImplTest, testCreateUser) { // This is the same example as used in User HAL Emulation doc. VehiclePropValue setValue = { .prop = toInt(VehicleProperty::CREATE_USER), .areaId = 1, .value.int32Values = {666, 2}, }; auto status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); // Simulate a request from Android side. setValue = { .prop = toInt(VehicleProperty::CREATE_USER), .areaId = 0, .value.int32Values = {666}, }; // Clear existing events. mEventQueue.flush(); status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); // Should generate an event for user hal response. auto events = mEventQueue.flush(); ASSERT_EQ((size_t)1, events.size()); EXPECT_EQ(1, events[0]->areaId); EXPECT_EQ(toInt(VehicleProperty::CREATE_USER), events[0]->prop); ASSERT_EQ((size_t)2, events[0]->value.int32Values.size()); EXPECT_EQ(666, events[0]->value.int32Values[0]); EXPECT_EQ(2, events[0]->value.int32Values[1]); // Try to get create_user again, should return default value. status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); events = mEventQueue.flush(); ASSERT_EQ((size_t)1, events.size()); EXPECT_EQ(0, events[0]->areaId); EXPECT_EQ(toInt(VehicleProperty::CREATE_USER), events[0]->prop); ASSERT_EQ((size_t)2, events[0]->value.int32Values.size()); // Request ID EXPECT_EQ(666, events[0]->value.int32Values[0]); // SUCCESS EXPECT_EQ(1, events[0]->value.int32Values[1]); } TEST_F(DefaultVhalImplTest, testInitialUserInfo) { // This is the same example as used in User HAL Emulation doc. VehiclePropValue setValue = { .prop = toInt(VehicleProperty::INITIAL_USER_INFO), .areaId = 1, .value.int32Values = {666, 1, 11}, }; auto status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); // Simulate a request from Android side. setValue = { .prop = toInt(VehicleProperty::INITIAL_USER_INFO), .areaId = 0, .value.int32Values = {3}, }; // Clear existing events. mEventQueue.flush(); status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); // Should generate an event for user hal response. auto events = mEventQueue.flush(); ASSERT_EQ((size_t)1, events.size()); EXPECT_EQ(1, events[0]->areaId); EXPECT_EQ(toInt(VehicleProperty::INITIAL_USER_INFO), events[0]->prop); ASSERT_EQ((size_t)3, events[0]->value.int32Values.size()); EXPECT_EQ(3, events[0]->value.int32Values[0]); EXPECT_EQ(1, events[0]->value.int32Values[1]); EXPECT_EQ(11, events[0]->value.int32Values[2]); // Try to get create_user again, should return default value. status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); events = mEventQueue.flush(); ASSERT_EQ((size_t)1, events.size()); EXPECT_EQ(0, events[0]->areaId); EXPECT_EQ(toInt(VehicleProperty::INITIAL_USER_INFO), events[0]->prop); ASSERT_EQ((size_t)4, events[0]->value.int32Values.size()); // Request ID EXPECT_EQ(3, events[0]->value.int32Values[0]); // ACTION: DEFAULT EXPECT_EQ(0, events[0]->value.int32Values[1]); // User id: 0 EXPECT_EQ(0, events[0]->value.int32Values[2]); // Flags: 0 EXPECT_EQ(0, events[0]->value.int32Values[3]); } } // namespace automotive/vehicle/2.0/default/impl/vhal_v2_0/userhal/Android.bp 0 → 100644 +31 −0 Original line number Diff line number Diff line // Copyright (C) 2021 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. // Library used to emulate User HAL behavior through lshal debug requests. cc_library { name: "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib", vendor: true, defaults: ["vhal_v2_0_target_defaults"], srcs: ["EmulatedUserHal.cpp"], shared_libs: [ "libbase", "libutils", "libcutils", ], local_include_dirs: ["include"], export_include_dirs: ["include"], whole_static_libs: [ "android.hardware.automotive.vehicle@2.0-user-hal-helper-lib", ], } Loading
automotive/vehicle/2.0/default/Android.bp +2 −1 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ cc_library_static { local_include_dirs: ["common/include/vhal_v2_0"], export_include_dirs: ["impl"], whole_static_libs: [ "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib", "android.hardware.automotive.vehicle@2.0-manager-lib", ], shared_libs: [ Loading Loading @@ -215,8 +216,8 @@ cc_test { "android.hardware.automotive.vehicle@2.0-libproto-native", ], data: [ ":vhal_test_override_json", ":vhal_test_json", ":vhal_test_override_json", ], test_suites: ["general-tests"], } Loading
automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp +78 −0 Original line number Diff line number Diff line Loading @@ -89,11 +89,38 @@ DefaultVehicleHal::DefaultVehicleHal(VehiclePropertyStore* propStore, VehicleHal }); } VehicleHal::VehiclePropValuePtr DefaultVehicleHal::getUserHalProp( const VehiclePropValue& requestedPropValue, StatusCode* outStatus) { auto propId = requestedPropValue.prop; ALOGI("get(): getting value for prop %d from User HAL", propId); const auto& ret = mEmulatedUserHal.onGetProperty(requestedPropValue); VehicleHal::VehiclePropValuePtr v = nullptr; if (!ret.ok()) { ALOGE("get(): User HAL returned error: %s", ret.error().message().c_str()); *outStatus = StatusCode(ret.error().code()); } else { auto value = ret.value().get(); if (value != nullptr) { ALOGI("get(): User HAL returned value: %s", toString(*value).c_str()); v = getValuePool()->obtain(*value); *outStatus = StatusCode::OK; } else { ALOGE("get(): User HAL returned null value"); *outStatus = StatusCode::INTERNAL_ERROR; } } return addTimestamp(std::move(v)); } VehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(const VehiclePropValue& requestedPropValue, StatusCode* outStatus) { auto propId = requestedPropValue.prop; ALOGV("get(%d)", propId); if (mEmulatedUserHal.isSupported(propId)) { return getUserHalProp(requestedPropValue, outStatus); } VehiclePropValuePtr v = nullptr; if (propId == OBD2_FREEZE_FRAME) { v = getValuePool()->obtainComplex(); Loading Loading @@ -127,6 +154,36 @@ std::vector<VehiclePropConfig> DefaultVehicleHal::listProperties() { } bool DefaultVehicleHal::dump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) { int nativeFd = fd->data[0]; if (nativeFd < 0) { ALOGW("Invalid fd from HIDL handle: %d", nativeFd); return false; } if (options.size() > 0) { if (options[0] == "--help") { std::string buffer; buffer += "Emulated user hal usage:\n"; buffer += mEmulatedUserHal.showDumpHelp(); buffer += "\n"; buffer += "VHAL server debug usage:\n"; buffer += "--debughal: send debug command to VHAL server, see '--debughal --help'\n"; buffer += "\n"; dprintf(nativeFd, "%s", buffer.c_str()); return false; } else if (options[0] == kUserHalDumpOption) { dprintf(nativeFd, "%s", mEmulatedUserHal.dump("").c_str()); return false; } } else { // No options, dump the emulated user hal state first and then send command to VHAL server // to dump its state. std::string buffer; buffer += "Emulator user hal state:\n"; buffer += mEmulatedUserHal.dump(" "); buffer += "\n"; dprintf(nativeFd, "%s", buffer.c_str()); } return mVehicleClient->dump(fd, options); } Loading Loading @@ -285,6 +342,23 @@ StatusCode DefaultVehicleHal::checkValueRange(const VehiclePropValue& value, return StatusCode::OK; } StatusCode DefaultVehicleHal::setUserHalProp(const VehiclePropValue& propValue) { ALOGI("onSetProperty(): property %d will be handled by UserHal", propValue.prop); const auto& ret = mEmulatedUserHal.onSetProperty(propValue); if (!ret.ok()) { ALOGE("onSetProperty(): HAL returned error: %s", ret.error().message().c_str()); return StatusCode(ret.error().code()); } auto updatedValue = ret.value().get(); if (updatedValue != nullptr) { ALOGI("onSetProperty(): updating property returned by HAL: %s", toString(*updatedValue).c_str()); onPropertyValue(*updatedValue, true); } return StatusCode::OK; } StatusCode DefaultVehicleHal::set(const VehiclePropValue& propValue) { if (propValue.status != VehiclePropertyStatus::AVAILABLE) { // Android side cannot set property status - this value is the Loading @@ -293,6 +367,10 @@ StatusCode DefaultVehicleHal::set(const VehiclePropValue& propValue) { return StatusCode::INVALID_ARG; } if (mEmulatedUserHal.isSupported(propValue.prop)) { return setUserHalProp(propValue); } std::unordered_set<int32_t> powerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)); if (powerProps.count(propValue.prop)) { Loading
automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h +7 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <vhal_v2_0/VehicleHal.h> #include <vhal_v2_0/VehiclePropertyStore.h> #include "EmulatedUserHal.h" #include "VehicleHalClient.h" namespace android { Loading Loading @@ -55,6 +56,7 @@ class DefaultVehicleHal : public VehicleHal { VehiclePropertyStore* mPropStore; RecurrentTimer mRecurrentTimer; VehicleHalClient* mVehicleClient; EmulatedUserHal mEmulatedUserHal; // The callback that would be called when a property value is updated. This function could // be extended to handle specific property update event. Loading @@ -79,6 +81,11 @@ class DefaultVehicleHal : public VehicleHal { // Register the heart beat event to be sent every 3s. This is required to inform watch dog that // VHAL is alive. Subclasses should always calls this function during onCreate. void registerHeartBeatEvent(); // Get a user HAL property. VehiclePropValuePtr getUserHalProp(const VehiclePropValue& requestedPropValue, StatusCode* outStatus); // Set a user HAL property. StatusCode setUserHalProp(const VehiclePropValue& propValue); // Create a VHAL heart beat property. VehicleHal::VehiclePropValuePtr createVhalHeartBeatProp(); Loading
automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp +216 −0 Original line number Diff line number Diff line Loading @@ -1047,4 +1047,220 @@ TEST_F(DefaultVhalImplTest, testClearObd2FreezeFrameOneFrame) { ASSERT_EQ(StatusCode::INVALID_ARG, status); } TEST_F(DefaultVhalImplTest, testGetUserPropertySetOnly) { VehiclePropValue value; value.prop = toInt(VehicleProperty::INITIAL_USER_INFO); StatusCode status; mHal->get(value, &status); ASSERT_EQ(StatusCode::INVALID_ARG, status); value.prop = toInt(VehicleProperty::SWITCH_USER); mHal->get(value, &status); ASSERT_EQ(StatusCode::INVALID_ARG, status); value.prop = toInt(VehicleProperty::CREATE_USER); mHal->get(value, &status); ASSERT_EQ(StatusCode::INVALID_ARG, status); value.prop = toInt(VehicleProperty::REMOVE_USER); mHal->get(value, &status); ASSERT_EQ(StatusCode::INVALID_ARG, status); } TEST_F(DefaultVhalImplTest, testGetUserIdAssoc) { VehiclePropValue value; value.prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION); StatusCode status; mHal->get(value, &status); // Default returns NOT_AVAILABLE. ASSERT_EQ(StatusCode::NOT_AVAILABLE, status); // This is the same example as used in User HAL Emulation doc. VehiclePropValue setValue = { .prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION), .areaId = 1, .value.int32Values = {666, 1, 1, 2}, }; status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); auto gotValue = mHal->get(value, &status); ASSERT_EQ(StatusCode::OK, status); ASSERT_EQ((size_t)4, gotValue->value.int32Values.size()); EXPECT_EQ(1, gotValue->areaId); EXPECT_EQ(666, gotValue->value.int32Values[0]); EXPECT_EQ(1, gotValue->value.int32Values[1]); EXPECT_EQ(1, gotValue->value.int32Values[2]); EXPECT_EQ(2, gotValue->value.int32Values[3]); EXPECT_EQ(toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION), gotValue->prop); } TEST_F(DefaultVhalImplTest, testSwitchUser) { // This is the same example as used in User HAL Emulation doc. VehiclePropValue setValue = { .prop = toInt(VehicleProperty::SWITCH_USER), .areaId = 1, .value.int32Values = {666, 3, 2}, }; auto status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); // Simulate a request from Android side. setValue = { .prop = toInt(VehicleProperty::SWITCH_USER), .areaId = 0, .value.int32Values = {666, 3}, }; // Clear existing events. mEventQueue.flush(); status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); // Should generate an event for user hal response. auto events = mEventQueue.flush(); ASSERT_EQ((size_t)1, events.size()); EXPECT_EQ(1, events[0]->areaId); EXPECT_EQ(toInt(VehicleProperty::SWITCH_USER), events[0]->prop); ASSERT_EQ((size_t)3, events[0]->value.int32Values.size()); EXPECT_EQ(666, events[0]->value.int32Values[0]); EXPECT_EQ(3, events[0]->value.int32Values[1]); EXPECT_EQ(2, events[0]->value.int32Values[2]); // Try to get switch_user again, should return default value. status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); events = mEventQueue.flush(); ASSERT_EQ((size_t)1, events.size()); EXPECT_EQ(0, events[0]->areaId); EXPECT_EQ(toInt(VehicleProperty::SWITCH_USER), events[0]->prop); ASSERT_EQ((size_t)3, events[0]->value.int32Values.size()); // Request ID EXPECT_EQ(666, events[0]->value.int32Values[0]); // VEHICLE_RESPONSE EXPECT_EQ(3, events[0]->value.int32Values[1]); // SUCCESS EXPECT_EQ(1, events[0]->value.int32Values[2]); } TEST_F(DefaultVhalImplTest, testCreateUser) { // This is the same example as used in User HAL Emulation doc. VehiclePropValue setValue = { .prop = toInt(VehicleProperty::CREATE_USER), .areaId = 1, .value.int32Values = {666, 2}, }; auto status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); // Simulate a request from Android side. setValue = { .prop = toInt(VehicleProperty::CREATE_USER), .areaId = 0, .value.int32Values = {666}, }; // Clear existing events. mEventQueue.flush(); status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); // Should generate an event for user hal response. auto events = mEventQueue.flush(); ASSERT_EQ((size_t)1, events.size()); EXPECT_EQ(1, events[0]->areaId); EXPECT_EQ(toInt(VehicleProperty::CREATE_USER), events[0]->prop); ASSERT_EQ((size_t)2, events[0]->value.int32Values.size()); EXPECT_EQ(666, events[0]->value.int32Values[0]); EXPECT_EQ(2, events[0]->value.int32Values[1]); // Try to get create_user again, should return default value. status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); events = mEventQueue.flush(); ASSERT_EQ((size_t)1, events.size()); EXPECT_EQ(0, events[0]->areaId); EXPECT_EQ(toInt(VehicleProperty::CREATE_USER), events[0]->prop); ASSERT_EQ((size_t)2, events[0]->value.int32Values.size()); // Request ID EXPECT_EQ(666, events[0]->value.int32Values[0]); // SUCCESS EXPECT_EQ(1, events[0]->value.int32Values[1]); } TEST_F(DefaultVhalImplTest, testInitialUserInfo) { // This is the same example as used in User HAL Emulation doc. VehiclePropValue setValue = { .prop = toInt(VehicleProperty::INITIAL_USER_INFO), .areaId = 1, .value.int32Values = {666, 1, 11}, }; auto status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); // Simulate a request from Android side. setValue = { .prop = toInt(VehicleProperty::INITIAL_USER_INFO), .areaId = 0, .value.int32Values = {3}, }; // Clear existing events. mEventQueue.flush(); status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); // Should generate an event for user hal response. auto events = mEventQueue.flush(); ASSERT_EQ((size_t)1, events.size()); EXPECT_EQ(1, events[0]->areaId); EXPECT_EQ(toInt(VehicleProperty::INITIAL_USER_INFO), events[0]->prop); ASSERT_EQ((size_t)3, events[0]->value.int32Values.size()); EXPECT_EQ(3, events[0]->value.int32Values[0]); EXPECT_EQ(1, events[0]->value.int32Values[1]); EXPECT_EQ(11, events[0]->value.int32Values[2]); // Try to get create_user again, should return default value. status = mHal->set(setValue); ASSERT_EQ(StatusCode::OK, status); events = mEventQueue.flush(); ASSERT_EQ((size_t)1, events.size()); EXPECT_EQ(0, events[0]->areaId); EXPECT_EQ(toInt(VehicleProperty::INITIAL_USER_INFO), events[0]->prop); ASSERT_EQ((size_t)4, events[0]->value.int32Values.size()); // Request ID EXPECT_EQ(3, events[0]->value.int32Values[0]); // ACTION: DEFAULT EXPECT_EQ(0, events[0]->value.int32Values[1]); // User id: 0 EXPECT_EQ(0, events[0]->value.int32Values[2]); // Flags: 0 EXPECT_EQ(0, events[0]->value.int32Values[3]); } } // namespace
automotive/vehicle/2.0/default/impl/vhal_v2_0/userhal/Android.bp 0 → 100644 +31 −0 Original line number Diff line number Diff line // Copyright (C) 2021 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. // Library used to emulate User HAL behavior through lshal debug requests. cc_library { name: "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib", vendor: true, defaults: ["vhal_v2_0_target_defaults"], srcs: ["EmulatedUserHal.cpp"], shared_libs: [ "libbase", "libutils", "libcutils", ], local_include_dirs: ["include"], export_include_dirs: ["include"], whole_static_libs: [ "android.hardware.automotive.vehicle@2.0-user-hal-helper-lib", ], }