Merge "Fix wrong integer type in AIDL bcradio utils lib" into main
diff --git a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
index 1c5a6b8..fc2d78e 100644
--- a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
+++ b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
@@ -67,7 +67,7 @@
                     "PortLocationType"
                 ],
                 "data_enum": "PortLocationType",
-                "description": "EV port location"
+                "description": "EV port location\nThis property must communicate the location of the charging port on the EV using the PortLocationType enum. If there are multiple ports available on the vehicle, this property must return the port that allows the fastest charging. To communicate all port locations, use INFO_MULTI_EV_PORT_LOCATIONS."
             },
             {
                 "name": "INFO_DRIVER_SEAT",
@@ -90,7 +90,7 @@
                     "PortLocationType"
                 ],
                 "data_enum": "PortLocationType",
-                "description": "Multiple EV port locations\nImplement this property if the vehicle has multiple EV ports. Port locations are defined in PortLocationType. For example, a car has one port in front left and one port in rear left: int32Values[0] = PortLocationType::FRONT_LEFT int32Values[0] = PortLocationType::REAR_LEFT"
+                "description": "Multiple EV port locations\nImplement this property if the vehicle has multiple EV ports. Port locations are defined in PortLocationType. For example, a car has one port in front left and one port in rear left: int32Values[0] = PortLocationType::FRONT_LEFT int32Values[1] = PortLocationType::REAR_LEFT\nIf only one port exists on the vehicle, this property's value should list just one element. See INFO_EV_PORT_LOCATION for describing just one port location."
             },
             {
                 "name": "PERF_ODOMETER",
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
index 9dafa91..2681f6c 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -170,6 +170,11 @@
     /**
      * EV port location
      *
+     * This property must communicate the location of the charging port on the EV using the
+     * PortLocationType enum. If there are multiple ports available on the vehicle, this property
+     * must return the port that allows the fastest charging. To communicate all port locations,
+     * use INFO_MULTI_EV_PORT_LOCATIONS.
+     *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @data_enum PortLocationType
@@ -214,7 +219,10 @@
      * Port locations are defined in PortLocationType.
      * For example, a car has one port in front left and one port in rear left:
      *   int32Values[0] = PortLocationType::FRONT_LEFT
-     *   int32Values[0] = PortLocationType::REAR_LEFT
+     *   int32Values[1] = PortLocationType::REAR_LEFT
+     *
+     * If only one port exists on the vehicle, this property's value should list just one element.
+     * See INFO_EV_PORT_LOCATION for describing just one port location.
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.h b/graphics/composer/aidl/vts/VtsComposerClient.h
index fabc82a..d3842c5 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.h
+++ b/graphics/composer/aidl/vts/VtsComposerClient.h
@@ -258,13 +258,13 @@
 
     struct DisplayConfig {
         DisplayConfig(int32_t vsyncPeriod_, int32_t configGroup_,
-                      std::optional<VrrConfig> vrrConfig_ = {})
+                      std::optional<VrrConfig> vrrConfigOpt_ = {})
             : vsyncPeriod(vsyncPeriod_),
               configGroup(configGroup_),
-              vrrConfig(std::move(vrrConfig_)) {}
+              vrrConfigOpt(std::move(vrrConfigOpt_)) {}
         int32_t vsyncPeriod;
         int32_t configGroup;
-        std::optional<VrrConfig> vrrConfig;
+        std::optional<VrrConfig> vrrConfigOpt;
     };
 
     void addDisplayConfig(int32_t config, DisplayConfig displayConfig) {
@@ -273,6 +273,21 @@
 
     DisplayConfig getDisplayConfig(int32_t config) { return mDisplayConfigs.find(config)->second; }
 
+    bool isRateSameBetweenConfigs(int config1, int config2) {
+        const auto displayConfig1 = getDisplayConfig(config1);
+        const auto displayConfig2 = getDisplayConfig(config2);
+        const auto vrrConfigOpt1 = displayConfig1.vrrConfigOpt;
+        const auto vrrConfigOpt2 = displayConfig2.vrrConfigOpt;
+
+        if (vrrConfigOpt1 && vrrConfigOpt2 &&
+            vrrConfigOpt1->minFrameIntervalNs == vrrConfigOpt2->minFrameIntervalNs) {
+            return true;
+        } else if (displayConfig1.vsyncPeriod == displayConfig2.vsyncPeriod) {
+            return true;
+        }
+        return false;
+    }
+
     std::unordered_map<int32_t, DisplayConfig> getDisplayConfigs() { return mDisplayConfigs; }
 
   private:
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index cef552c..61df350 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -1603,18 +1603,24 @@
                 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
                 sendRefreshFrame(display, nullptr);
 
-                const auto displayConfigGroup1 = display.getDisplayConfig(config1);
-                int32_t vsyncPeriod1 = displayConfigGroup1.vsyncPeriod;
-                int32_t configGroup1 = displayConfigGroup1.configGroup;
+                const auto displayConfig1 = display.getDisplayConfig(config1);
+                int32_t vsyncPeriod1 = displayConfig1.vsyncPeriod;
+                int32_t configGroup1 = displayConfig1.configGroup;
 
-                const auto displayConfigGroup2 = display.getDisplayConfig(config2);
-                int32_t vsyncPeriod2 = displayConfigGroup2.vsyncPeriod;
-                int32_t configGroup2 = displayConfigGroup2.configGroup;
+                const auto displayConfig2 = display.getDisplayConfig(config2);
+                int32_t vsyncPeriod2 = displayConfig2.vsyncPeriod;
+                int32_t configGroup2 = displayConfig2.configGroup;
 
                 if (vsyncPeriod1 == vsyncPeriod2) {
                     return;  // continue
                 }
 
+                if ((!displayConfig1.vrrConfigOpt && displayConfig2.vrrConfigOpt) ||
+                    (displayConfig1.vrrConfigOpt && !displayConfig2.vrrConfigOpt)) {
+                    // switching between vrr to non-vrr modes
+                    return;  // continue
+                }
+
                 // We don't allow delayed change when changing config groups
                 if (params.delayForChange > 0 && configGroup1 != configGroup2) {
                     return;  // continue
@@ -2738,7 +2744,7 @@
         const auto displayFilter = [&](auto refreshRateChangedDebugData) {
             bool nonVrrRateMatching = true;
             if (std::optional<VrrConfig> vrrConfigOpt =
-                        display.getDisplayConfig(configId).vrrConfig;
+                        display.getDisplayConfig(configId).vrrConfigOpt;
                 getInterfaceVersion() >= 3 && !vrrConfigOpt) {
                 nonVrrRateMatching = refreshRateChangedDebugData.refreshPeriodNanos ==
                                      refreshRateChangedDebugData.vsyncPeriodNanos;
@@ -2836,10 +2842,7 @@
                             .isOk());
 
         forEachTwoConfigs(displayId, [&](int32_t config1, int32_t config2) {
-            const int32_t vsyncPeriod1 = display.getDisplayConfig(config1).vsyncPeriod;
-            const int32_t vsyncPeriod2 = display.getDisplayConfig(config2).vsyncPeriod;
-
-            if (vsyncPeriod1 == vsyncPeriod2) {
+            if (display.isRateSameBetweenConfigs(config1, config2)) {
                 return;  // continue
             }
 
@@ -2854,6 +2857,7 @@
                 sendRefreshFrame(display, &timeline);
             }
 
+            const int32_t vsyncPeriod2 = display.getDisplayConfig(config2).vsyncPeriod;
             const auto callbackFilter = [displayId,
                                          vsyncPeriod2](auto refreshRateChangedDebugData) {
                 constexpr int kVsyncThreshold = 1000;