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
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 84395a2..c3ebd3b 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -159,6 +159,7 @@
     const std::string mDefaultConfigDir;
     const std::string mOverrideConfigDir;
     const bool mForceOverride;
+    bool mAddExtraTestVendorConfigs;
 
     // Only used during initialization.
     JsonConfigLoader mLoader;
@@ -248,6 +249,8 @@
     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,
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 577442e..740d3f6 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -64,6 +64,7 @@
 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::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 @@
 }
 
 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 @@
         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 @@
   [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 @@
                         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();
diff --git a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h b/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
index d92ccfd..e53947e 100644
--- a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
@@ -35,6 +35,8 @@
     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.
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index 0439ac6..2c2cf1a 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -164,6 +164,7 @@
     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 @@
     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 @@
 
     bool checkDumpPermission();
 
+    bool getAllPropConfigsFromHardware();
+
     // The looping handler function to process all onBinderDied or onBinderUnlinked events in
     // mBinderEvents.
     void onBinderDiedUnlinkedHandler();
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index a7ac1b4..98cfc39 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -128,23 +128,10 @@
 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 @@
     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 @@
         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;