Added debug statement and refresh in default vehicle hal

Added a debug statement to allow for a debug command to generate a large
amount of propConfigs to test large parcelables. DefaultVehicleHal
needed to refresh the properties when DefaultVehicleHal's
getAllPropConfigs is called

Bug: 270740905
Test: atest DefaultVehicleHalTest
Test: atest android.car.apitest.CarPropertyManagerTest
Test: --rerun-until-failure 3
Test: Manual
Change-Id: I95eb98cef64e327894760783ffe9883975359d89
This commit is contained in:
terryguan 2023-03-30 09:20:08 -07:00
parent 98d6368ebb
commit f3cd073e86
5 changed files with 70 additions and 16 deletions

View file

@ -159,6 +159,7 @@ class FakeVehicleHardware : public IVehicleHardware {
const std::string mDefaultConfigDir;
const std::string mOverrideConfigDir;
const bool mForceOverride;
bool mAddExtraTestVendorConfigs;
// Only used during initialization.
JsonConfigLoader mLoader;
@ -248,6 +249,8 @@ class FakeVehicleHardware : public IVehicleHardware {
std::string genFakeDataCommand(const std::vector<std::string>& options);
void sendHvacPropertiesCurrentValues(int32_t areaId);
void sendAdasPropertiesState(int32_t propertyId, int32_t state);
void generateVendorConfigs(
std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig>&) const;
static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,

View file

@ -64,6 +64,7 @@ using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
using ::aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
@ -79,6 +80,11 @@ using ::android::base::ScopedLockAssertion;
using ::android::base::StartsWith;
using ::android::base::StringPrintf;
// In order to test large number of vehicle property configs, we might generate additional fake
// property config start from this ID. Note these fake properties are for getAllPropertyConfigs
// testing only.
constexpr int32_t STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST = 0x5000;
constexpr int32_t NUMBER_OF_TEST_VENDOR_CODES = 0x3000;
// The directory for default property configuration file.
// For config file format, see impl/default_config/config/README.md.
constexpr char DEFAULT_CONFIG_DIR[] = "/vendor/etc/automotive/vhalconfig/";
@ -291,7 +297,11 @@ void FakeVehicleHardware::init() {
}
std::vector<VehiclePropConfig> FakeVehicleHardware::getAllPropertyConfigs() const {
return mServerSidePropStore->getAllConfigs();
std::vector<VehiclePropConfig> allConfigs = mServerSidePropStore->getAllConfigs();
if (mAddExtraTestVendorConfigs) {
generateVendorConfigs(/* outAllConfigs= */ allConfigs);
}
return allConfigs;
}
VehiclePropValuePool::RecyclableType FakeVehicleHardware::createApPowerStateReq(
@ -953,6 +963,12 @@ DumpResult FakeVehicleHardware::dump(const std::vector<std::string>& options) {
result.buffer = mFakeUserHal->dump();
} else if (EqualsIgnoreCase(option, "--genfakedata")) {
result.buffer = genFakeDataCommand(options);
} else if (EqualsIgnoreCase(option, "--genTestVendorConfigs")) {
mAddExtraTestVendorConfigs = true;
result.refreshPropertyConfigs = true;
} else if (EqualsIgnoreCase(option, "--restoreVendorConfigs")) {
mAddExtraTestVendorConfigs = false;
result.refreshPropertyConfigs = true;
} else {
result.buffer = StringPrintf("Invalid option: %s\n", option.c_str());
}
@ -1003,6 +1019,13 @@ provided, it would iterate indefinitely.
[pressure(float)] [size(float)]
Generate a motion input event. --pointer option can be specified multiple times.
--genTestVendorConfigs: Generates fake VehiclePropConfig ranging from 0x5000 to 0x8000 all with
vendor property group, global vehicle area, and int32 vehicle property type. This is mainly used
for testing
--restoreVendorConfigs: Restores to to the default state if genTestVendorConfigs was used.
Otherwise this will do nothing.
)";
}
@ -1012,6 +1035,19 @@ std::string FakeVehicleHardware::parseErrMsg(std::string fieldName, std::string
value.c_str(), genFakeDataHelp().c_str());
}
void FakeVehicleHardware::generateVendorConfigs(
std::vector<VehiclePropConfig>& outAllConfigs) const {
for (int i = STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST;
i < STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST + NUMBER_OF_TEST_VENDOR_CODES; i++) {
VehiclePropConfig config;
config.prop = i | toInt(propertyutils_impl::VehiclePropertyGroup::VENDOR) |
toInt(propertyutils_impl::VehicleArea::GLOBAL) |
toInt(propertyutils_impl::VehiclePropertyType::INT32);
config.access = VehiclePropertyAccess::READ_WRITE;
outAllConfigs.push_back(config);
}
}
std::string FakeVehicleHardware::genFakeDataCommand(const std::vector<std::string>& options) {
if (options.size() < 2) {
return "No subcommand specified for genfakedata\n" + genFakeDataHelp();

View file

@ -35,6 +35,8 @@ struct DumpResult {
bool callerShouldDumpState;
// The dumped information for the caller to print.
std::string buffer;
// To pass if DefaultVehicleHal should refresh the property configs
bool refreshPropertyConfigs = false;
};
// A structure to represent a set value error event reported from vehicle.

View file

@ -164,6 +164,7 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi
static constexpr int64_t TIMEOUT_IN_NANO = 30'000'000'000;
// heart beat event interval: 3s
static constexpr int64_t HEART_BEAT_INTERVAL_IN_NANO = 3'000'000'000;
bool mShouldRefreshPropertyConfigs;
std::unique_ptr<IVehicleHardware> mVehicleHardware;
// mConfigsByPropId and mConfigFile are only modified during initialization, so no need to
@ -212,7 +213,6 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi
android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
const std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>&
requests);
VhalResult<void> checkSubscribeOptions(
const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>&
options);
@ -236,6 +236,8 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi
bool checkDumpPermission();
bool getAllPropConfigsFromHardware();
// The looping handler function to process all onBinderDied or onBinderUnlinked events in
// mBinderEvents.
void onBinderDiedUnlinkedHandler();

View file

@ -128,23 +128,10 @@ size_t DefaultVehicleHal::SubscriptionClients::countClients() {
DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware)
: mVehicleHardware(std::move(vehicleHardware)),
mPendingRequestPool(std::make_shared<PendingRequestPool>(TIMEOUT_IN_NANO)) {
auto configs = mVehicleHardware->getAllPropertyConfigs();
for (auto& config : configs) {
mConfigsByPropId[config.prop] = config;
}
VehiclePropConfigs vehiclePropConfigs;
vehiclePropConfigs.payloads = std::move(configs);
auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs);
if (!result.ok()) {
ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
result.error().message().c_str(), static_cast<int>(result.error().code()));
if (!getAllPropConfigsFromHardware()) {
return;
}
if (result.value() != nullptr) {
mConfigFile = std::move(result.value());
}
mSubscriptionClients = std::make_shared<SubscriptionClients>(mPendingRequestPool);
auto subscribeIdByClient = std::make_shared<SubscribeIdByClient>();
@ -304,6 +291,27 @@ void DefaultVehicleHal::setTimeout(int64_t timeoutInNano) {
mPendingRequestPool = std::make_unique<PendingRequestPool>(timeoutInNano);
}
bool DefaultVehicleHal::getAllPropConfigsFromHardware() {
auto configs = mVehicleHardware->getAllPropertyConfigs();
for (auto& config : configs) {
mConfigsByPropId[config.prop] = config;
}
VehiclePropConfigs vehiclePropConfigs;
vehiclePropConfigs.payloads = std::move(configs);
auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs);
if (!result.ok()) {
ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
result.error().message().c_str(), static_cast<int>(result.error().code()));
mConfigFile = nullptr;
return false;
}
if (result.value() != nullptr) {
mConfigFile = std::move(result.value());
}
return true;
}
ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) {
if (mConfigFile != nullptr) {
output->payloads.clear();
@ -798,6 +806,9 @@ binder_status_t DefaultVehicleHal::dump(int fd, const char** args, uint32_t numA
options.clear();
}
DumpResult result = mVehicleHardware->dump(options);
if (result.refreshPropertyConfigs) {
getAllPropConfigsFromHardware();
}
dprintf(fd, "%s", (result.buffer + "\n").c_str());
if (!result.callerShouldDumpState) {
return STATUS_OK;