Merge "Free version buffer in the Vendor HAL's XML parsing logic." into udc-dev
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
index d4ab0f7..2335d6d 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
@@ -119,6 +119,7 @@
         {VehicleProperty::AP_POWER_STATE_REPORT, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::AP_POWER_BOOTUP_REASON, VehiclePropertyAccess::READ},
         {VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::HW_KEY_INPUT, VehiclePropertyAccess::READ},
         {VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyAccess::READ},
         {VehicleProperty::HW_MOTION_INPUT, VehiclePropertyAccess::READ},
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
index d56de3f..a0911c5 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
@@ -119,6 +119,7 @@
         {VehicleProperty::AP_POWER_STATE_REPORT, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::AP_POWER_BOOTUP_REASON, VehiclePropertyChangeMode::STATIC},
         {VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::HW_KEY_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::HW_MOTION_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
index caeb266..e9670c1 100644
--- a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
@@ -111,6 +111,7 @@
         Map.entry(VehicleProperty.AP_POWER_STATE_REPORT, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.AP_POWER_BOOTUP_REASON, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyAccess.READ),
diff --git a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
index 0beab94..2513e4e 100644
--- a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
@@ -111,6 +111,7 @@
         Map.entry(VehicleProperty.AP_POWER_STATE_REPORT, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.AP_POWER_BOOTUP_REASON, VehiclePropertyChangeMode.STATIC),
         Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
index cc06bf3..a525ab0 100644
--- a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -117,6 +117,7 @@
   AP_POWER_STATE_REPORT = (((0x0A01 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475073 */,
   AP_POWER_BOOTUP_REASON = (((0x0A02 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409538 */,
   DISPLAY_BRIGHTNESS = (((0x0A03 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409539 */,
+  PER_DISPLAY_BRIGHTNESS = (((0x0A04 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475076 */,
   HW_KEY_INPUT = (((0x0A10 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475088 */,
   HW_KEY_INPUT_V2 = (((0x0A11 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 367004177 */,
   HW_MOTION_INPUT = (((0x0A12 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 367004178 */,
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 473dffc..b350f90 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -1252,9 +1252,16 @@
     AP_POWER_BOOTUP_REASON = 0x0A02 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
     /**
-     * Property to represent brightness of the display. Some cars have single
-     * control for the brightness of all displays and this property is to share
-     * change in that control.
+     * Property to represent brightness of the display.
+     *
+     * Some cars have single control for the brightness of all displays and this
+     * property is to share change in that control. In cars which have displays
+     * whose brightness is controlled separately, they must use
+     * PER_DISPLAY_BRIGHTNESS.
+     *
+     * Only one of DISPLAY_BRIGHTNESS and PER_DISPLAY_BRIGHTNESS should be
+     * implemented. If both are available, PER_DISPLAY_BRIGHTNESS is used by
+     * AAOS.
      *
      * If this is writable, android side can set this value when user changes
      * display brightness from Settings. If this is read only, user may still
@@ -1267,6 +1274,29 @@
     DISPLAY_BRIGHTNESS = 0x0A03 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
     /**
+     * Property to represent brightness of the displays which are controlled separately.
+     *
+     * Some cars have one or more displays whose brightness is controlled
+     * separately and this property is to inform the brightness of each
+     * passenger display. In cars where all displays' brightness is controlled
+     * together, they must use DISPLAY_BRIGHTNESS.
+     *
+     * Only one of DISPLAY_BRIGHTNESS and PER_DISPLAY_BRIGHTNESS should be
+     * implemented. If both are available, PER_DISPLAY_BRIGHTNESS is used by
+     * AAOS.
+     *
+     * The display port uniquely identifies a physical connector on the device
+     * for display output, ranging from 0 to 255.
+     *
+     * int32Values[0] : display port
+     * int32Values[1] : brightness
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    PER_DISPLAY_BRIGHTNESS = 0x0A04 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
      * Property to feed H/W input events to android
      *
      * int32Values[0] : action defined by VehicleHwKeyInputAction
diff --git a/health/aidl/OWNERS b/health/aidl/OWNERS
index 9bbcef8..0f1bee2 100644
--- a/health/aidl/OWNERS
+++ b/health/aidl/OWNERS
@@ -2,3 +2,4 @@
 elsk@google.com
 smoreland@google.com
 wjack@google.com
+apelosi@google.com
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl
index e543886..4d70588 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl
@@ -34,11 +34,11 @@
 package android.hardware.health;
 @Backing(type="int") @VintfStability
 enum BatteryCapacityLevel {
-  UNSUPPORTED = -1,
-  UNKNOWN = 0,
-  CRITICAL = 1,
-  LOW = 2,
-  NORMAL = 3,
-  HIGH = 4,
-  FULL = 5,
+  UNSUPPORTED = (-1) /* -1 */,
+  UNKNOWN,
+  CRITICAL,
+  LOW,
+  NORMAL,
+  HIGH,
+  FULL,
 }
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
index d523fad..2dd01b1 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
@@ -36,4 +36,5 @@
 parcelable BatteryHealthData {
   long batteryManufacturingDateSeconds;
   long batteryFirstUsageSeconds;
+  long batteryStateOfHealth;
 }
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
index 664cc70..bfa1475 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
@@ -57,9 +57,8 @@
   android.hardware.health.BatteryCapacityLevel batteryCapacityLevel;
   long batteryChargeTimeToFullNowSeconds;
   int batteryFullChargeDesignCapacityUah;
-  int batteryStateOfHealth;
   android.hardware.health.BatteryChargingState chargingState;
   android.hardware.health.BatteryChargingPolicy chargingPolicy;
   @nullable android.hardware.health.BatteryHealthData batteryHealthData;
-  const int BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED = -1;
+  const int BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED = (-1) /* -1 */;
 }
diff --git a/health/aidl/android/hardware/health/BatteryHealthData.aidl b/health/aidl/android/hardware/health/BatteryHealthData.aidl
index fb17f63..594bcce 100644
--- a/health/aidl/android/hardware/health/BatteryHealthData.aidl
+++ b/health/aidl/android/hardware/health/BatteryHealthData.aidl
@@ -29,4 +29,11 @@
      * The date of first usage is reported in epoch.
      */
     long batteryFirstUsageSeconds;
+    /**
+     * Measured battery state of health (remaining estimate full charge capacity
+     * relative to the rated capacity in %).
+     * Value must be 0 if batteryStatus is UNKNOWN.
+     * Otherwise, value must be in the range 0 to 100.
+     */
+    long batteryStateOfHealth;
 }
diff --git a/health/aidl/android/hardware/health/HealthInfo.aidl b/health/aidl/android/hardware/health/HealthInfo.aidl
index 238f524..af84089 100644
--- a/health/aidl/android/hardware/health/HealthInfo.aidl
+++ b/health/aidl/android/hardware/health/HealthInfo.aidl
@@ -137,13 +137,6 @@
      */
     int batteryFullChargeDesignCapacityUah;
     /**
-     * Measured battery state of health (remaining estimate full charge capacity
-     * relative to the rated capacity in %).
-     * Value must be 0 if batteryStatus is UNKNOWN.
-     * Otherwise, value must be in the range 0 to 100.
-     */
-    int batteryStateOfHealth;
-    /**
      * Battery charging state
      */
     BatteryChargingState chargingState;
diff --git a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
index 6506ea2..69d4789 100644
--- a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
+++ b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
@@ -278,6 +278,10 @@
         *result_listener << " for batteryFirstUsageSeconds.";
         return false;
     }
+    if (!ExplainMatchResult(Ge(-1), arg.batteryStateOfHealth, result_listener)) {
+        *result_listener << " for batteryStateOfHealth.";
+        return false;
+    }
 
     return true;
 }
diff --git a/security/dice/aidl/default/Android.bp b/security/dice/aidl/default/Android.bp
index b67a44a..5ff4847 100644
--- a/security/dice/aidl/default/Android.bp
+++ b/security/dice/aidl/default/Android.bp
@@ -14,7 +14,6 @@
     vendor: true,
     rustlibs: [
         "android.hardware.security.dice-V1-rust",
-        "libdiced_open_dice_cbor",
         "libdiced_sample_inputs",
         "libdiced_vendor",
         "libandroid_logger",
diff --git a/security/dice/aidl/default/service.rs b/security/dice/aidl/default/service.rs
index 0197f2c..4363e91 100644
--- a/security/dice/aidl/default/service.rs
+++ b/security/dice/aidl/default/service.rs
@@ -14,7 +14,7 @@
 
 //! Main entry point for the android.hardware.security.dice service.
 
-use anyhow::Result;
+use anyhow::{anyhow, Result};
 use diced::{
     dice,
     hal_node::{DiceArtifacts, DiceDevice, ResidentHal, UpdatableDiceArtifacts},
@@ -40,8 +40,8 @@
     fn cdi_seal(&self) -> &[u8; dice::CDI_SIZE] {
         &self.cdi_seal
     }
-    fn bcc(&self) -> Vec<u8> {
-        self.bcc.clone()
+    fn bcc(&self) -> Option<&[u8]> {
+        Some(&self.bcc)
     }
 }
 
@@ -56,7 +56,10 @@
         Ok(Self {
             cdi_attest: *new_artifacts.cdi_attest(),
             cdi_seal: *new_artifacts.cdi_seal(),
-            bcc: new_artifacts.bcc(),
+            bcc: new_artifacts
+                .bcc()
+                .ok_or_else(|| anyhow!("bcc is none"))?
+                .to_vec(),
         })
     }
 }
@@ -77,16 +80,19 @@
 
     let dice_artifacts =
         make_sample_bcc_and_cdis().expect("Failed to construct sample dice chain.");
-
+    let mut cdi_attest = [0u8; dice::CDI_SIZE];
+    cdi_attest.copy_from_slice(dice_artifacts.cdi_attest());
+    let mut cdi_seal = [0u8; dice::CDI_SIZE];
+    cdi_seal.copy_from_slice(dice_artifacts.cdi_seal());
     let hal_impl = Arc::new(
         unsafe {
             // Safety: ResidentHal cannot be used in multi threaded processes.
             // This service does not start a thread pool. The main thread is the only thread
             // joining the thread pool, thereby keeping the process single threaded.
             ResidentHal::new(InsecureSerializableArtifacts {
-                cdi_attest: dice_artifacts.cdi_values.cdi_attest,
-                cdi_seal: dice_artifacts.cdi_values.cdi_seal,
-                bcc: dice_artifacts.bcc[..].to_vec(),
+                cdi_attest,
+                cdi_seal,
+                bcc: dice_artifacts.bcc().expect("bcc is none").to_vec(),
             })
         }
         .expect("Failed to create ResidentHal implementation."),
diff --git a/security/dice/aidl/vts/functional/Android.bp b/security/dice/aidl/vts/functional/Android.bp
index f5bc949..2a85a19 100644
--- a/security/dice/aidl/vts/functional/Android.bp
+++ b/security/dice/aidl/vts/functional/Android.bp
@@ -23,7 +23,7 @@
         "android.hardware.security.dice-V1-rust",
         "libanyhow",
         "libbinder_rs",
-        "libdiced_open_dice_cbor",
+        "libdiced_open_dice",
         "libdiced_sample_inputs",
         "libdiced_utils",
         "libkeystore2_vintf_rust",
@@ -46,7 +46,7 @@
         "android.hardware.security.dice-V1-rust",
         "libanyhow",
         "libbinder_rs",
-        "libdiced_open_dice_cbor",
+        "libdiced_open_dice",
         "libdiced_sample_inputs",
         "libdiced_utils",
         "libkeystore2_vintf_rust",
diff --git a/security/dice/aidl/vts/functional/dice_demote_test.rs b/security/dice/aidl/vts/functional/dice_demote_test.rs
index 1a17ec7..49aea67 100644
--- a/security/dice/aidl/vts/functional/dice_demote_test.rs
+++ b/security/dice/aidl/vts/functional/dice_demote_test.rs
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+use diced_open_dice::DiceArtifacts;
 use diced_sample_inputs;
 use diced_utils;
 use std::convert::TryInto;
@@ -44,11 +45,10 @@
         .unwrap();
 
         let artifacts = artifacts.execute_steps(input_values.iter()).unwrap();
-        let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
         let from_former = diced_utils::make_bcc_handover(
-            cdi_attest[..].try_into().unwrap(),
-            cdi_seal[..].try_into().unwrap(),
-            &bcc,
+            artifacts.cdi_attest(),
+            artifacts.cdi_seal(),
+            artifacts.bcc().expect("bcc is none"),
         )
         .unwrap();
         // TODO b/204938506 when we have a parser/verifier, check equivalence rather
diff --git a/security/dice/aidl/vts/functional/dice_test.rs b/security/dice/aidl/vts/functional/dice_test.rs
index 190f187..fbbdd81 100644
--- a/security/dice/aidl/vts/functional/dice_test.rs
+++ b/security/dice/aidl/vts/functional/dice_test.rs
@@ -12,9 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+use diced_open_dice::DiceArtifacts;
 use diced_sample_inputs;
 use diced_utils;
-use std::convert::TryInto;
 
 mod utils;
 use utils::with_connection;
@@ -44,11 +44,10 @@
         .unwrap();
 
         let artifacts = artifacts.execute_steps(input_values.iter()).unwrap();
-        let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
         let from_former = diced_utils::make_bcc_handover(
-            cdi_attest[..].try_into().unwrap(),
-            cdi_seal[..].try_into().unwrap(),
-            &bcc,
+            artifacts.cdi_attest(),
+            artifacts.cdi_seal(),
+            artifacts.bcc().expect("bcc is none"),
         )
         .unwrap();
         // TODO b/204938506 when we have a parser/verifier, check equivalence rather
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 1b9e758..357405f 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -1214,7 +1214,7 @@
  * that has been generated using an associate IRemotelyProvisionedComponent.
  */
 TEST_P(NewKeyGenerationTest, EcdsaWithRkpAttestation) {
-    if (get_vsr_api_level() < 32 || AidlVersion() < 2) {
+    if (get_vsr_api_level() <= 32 || AidlVersion() < 2) {
         GTEST_SKIP() << "Only required for VSR 12+ and KeyMint 2+";
     }
 
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index efd6598..d3cf7bf 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -3300,6 +3300,64 @@
     return channel_category_mask;
 }
 
+bool convertLegacyIfaceMaskToIfaceConcurrencyType(u32 mask,
+                                                  std::vector<IfaceConcurrencyType>* types) {
+    if (!mask) return false;
+
+#ifndef BIT
+#define BIT(x) (1 << (x))
+#endif
+    if (mask & BIT(WIFI_INTERFACE_TYPE_STA)) types->push_back(IfaceConcurrencyType::STA);
+    if (mask & BIT(WIFI_INTERFACE_TYPE_AP)) types->push_back(IfaceConcurrencyType::AP);
+    if (mask & BIT(WIFI_INTERFACE_TYPE_AP_BRIDGED))
+        types->push_back(IfaceConcurrencyType::AP_BRIDGED);
+    if (mask & BIT(WIFI_INTERFACE_TYPE_P2P)) types->push_back(IfaceConcurrencyType::P2P);
+    if (mask & BIT(WIFI_INTERFACE_TYPE_NAN)) types->push_back(IfaceConcurrencyType::NAN_IFACE);
+
+    return true;
+}
+
+bool convertLegacyIfaceCombinationsMatrixToChipMode(
+        legacy_hal::wifi_iface_concurrency_matrix& legacy_matrix, IWifiChip::ChipMode* chip_mode) {
+    if (!chip_mode) {
+        LOG(ERROR) << "chip_mode is null";
+        return false;
+    }
+    *chip_mode = {};
+
+    int num_combinations = legacy_matrix.num_iface_combinations;
+    std::vector<IWifiChip::ChipConcurrencyCombination> driver_Combinations_vec;
+    if (!num_combinations) {
+        LOG(ERROR) << "zero iface combinations";
+        return false;
+    }
+
+    for (int i = 0; i < num_combinations; i++) {
+        IWifiChip::ChipConcurrencyCombination chipComb;
+        std::vector<IWifiChip::ChipConcurrencyCombinationLimit> limits;
+        wifi_iface_combination* comb = &legacy_matrix.iface_combinations[i];
+        if (!comb->num_iface_limits) continue;
+        for (u32 j = 0; j < comb->num_iface_limits; j++) {
+            IWifiChip::ChipConcurrencyCombinationLimit chipLimit;
+            chipLimit.maxIfaces = comb->iface_limits[j].max_limit;
+            std::vector<IfaceConcurrencyType> types;
+            if (!convertLegacyIfaceMaskToIfaceConcurrencyType(comb->iface_limits[j].iface_mask,
+                                                              &types)) {
+                LOG(ERROR) << "Failed to convert from iface_mask:"
+                           << comb->iface_limits[j].iface_mask;
+                return false;
+            }
+            chipLimit.types = types;
+            limits.push_back(chipLimit);
+        }
+        chipComb.limits = limits;
+        driver_Combinations_vec.push_back(chipComb);
+    }
+
+    chip_mode->availableCombinations = driver_Combinations_vec;
+    return true;
+}
+
 }  // namespace aidl_struct_util
 }  // namespace wifi
 }  // namespace hardware
diff --git a/wifi/aidl/default/aidl_struct_util.h b/wifi/aidl/default/aidl_struct_util.h
index 904ba81..208b734 100644
--- a/wifi/aidl/default/aidl_struct_util.h
+++ b/wifi/aidl/default/aidl_struct_util.h
@@ -67,6 +67,8 @@
         WifiRadioCombinationMatrix* aidl_matrix);
 WifiBand convertLegacyMacBandToAidlWifiBand(uint32_t band);
 WifiAntennaMode convertLegacyAntennaConfigurationToAidl(uint32_t antenna_cfg);
+bool convertLegacyIfaceCombinationsMatrixToChipMode(
+        legacy_hal::wifi_iface_concurrency_matrix& legacy_matrix, IWifiChip::ChipMode* chip_mode);
 
 // STA iface conversion methods.
 bool convertLegacyFeaturesToAidlStaCapabilities(uint64_t legacy_feature_set, uint32_t* aidl_caps);
diff --git a/wifi/aidl/default/wifi_chip.cpp b/wifi/aidl/default/wifi_chip.cpp
index b4c2ccd..bb3eaf0 100644
--- a/wifi/aidl/default/wifi_chip.cpp
+++ b/wifi/aidl/default/wifi_chip.cpp
@@ -377,6 +377,35 @@
       debug_ring_buffer_cb_registered_(false),
       subsystemCallbackHandler_(handler) {
     setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
+    using_dynamic_iface_combination_ = false;
+}
+
+void WifiChip::retrieveDynamicIfaceCombination() {
+    if (using_dynamic_iface_combination_) return;
+
+    legacy_hal::wifi_iface_concurrency_matrix legacy_matrix;
+    legacy_hal::wifi_error legacy_status;
+
+    std::tie(legacy_status, legacy_matrix) =
+            legacy_hal_.lock()->getSupportedIfaceConcurrencyMatrix();
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to get SupportedIfaceCombinations matrix from legacy HAL: "
+                   << legacyErrorToString(legacy_status);
+        return;
+    }
+
+    IWifiChip::ChipMode aidl_chip_mode;
+    if (!aidl_struct_util::convertLegacyIfaceCombinationsMatrixToChipMode(legacy_matrix,
+                                                                          &aidl_chip_mode)) {
+        LOG(ERROR) << "Failed convertLegacyIfaceCombinationsMatrixToChipMode() ";
+        return;
+    }
+
+    LOG(INFO) << "Reloading iface concurrency combination from driver";
+    aidl_chip_mode.id = feature_flags::chip_mode_ids::kV3;
+    modes_.clear();
+    modes_.push_back(aidl_chip_mode);
+    using_dynamic_iface_combination_ = true;
 }
 
 std::shared_ptr<WifiChip> WifiChip::create(
@@ -1509,6 +1538,8 @@
                      version_info.first.firmwareDescription.c_str());
         property_set("vendor.wlan.driver.version", version_info.first.driverDescription.c_str());
     }
+    // Get the driver supported interface combination.
+    retrieveDynamicIfaceCombination();
 
     return ndk::ScopedAStatus::ok();
 }
diff --git a/wifi/aidl/default/wifi_chip.h b/wifi/aidl/default/wifi_chip.h
index ff4ee9c..def5da0 100644
--- a/wifi/aidl/default/wifi_chip.h
+++ b/wifi/aidl/default/wifi_chip.h
@@ -262,6 +262,7 @@
     getSupportedRadioCombinationsMatrixInternal();
     std::pair<WifiChipCapabilities, ndk::ScopedAStatus> getWifiChipCapabilitiesInternal();
     ndk::ScopedAStatus setMloModeInternal(const ChipMloMode in_mode);
+    void retrieveDynamicIfaceCombination();
     void setWeakPtr(std::weak_ptr<WifiChip> ptr);
 
     int32_t chip_id_;
@@ -283,6 +284,7 @@
     // registration mechanism. Use this to check if we have already
     // registered a callback.
     bool debug_ring_buffer_cb_registered_;
+    bool using_dynamic_iface_combination_;
     aidl_callback_util::AidlCallbackHandler<IWifiChipEventCallback> event_cb_handler_;
     std::weak_ptr<WifiChip> weak_ptr_this_;
 
diff --git a/wifi/aidl/default/wifi_legacy_hal.cpp b/wifi/aidl/default/wifi_legacy_hal.cpp
index dbf5a68..209670b 100644
--- a/wifi/aidl/default/wifi_legacy_hal.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal.cpp
@@ -1885,6 +1885,14 @@
     return global_func_table_.wifi_set_mlo_mode(global_handle_, mode);
 }
 
+std::pair<wifi_error, wifi_iface_concurrency_matrix>
+WifiLegacyHal::getSupportedIfaceConcurrencyMatrix() {
+    wifi_iface_concurrency_matrix iface_concurrency_matrix;
+    wifi_error status = global_func_table_.wifi_get_supported_iface_concurrency_matrix(
+            global_handle_, &iface_concurrency_matrix);
+    return {status, iface_concurrency_matrix};
+}
+
 void WifiLegacyHal::invalidate() {
     global_handle_ = nullptr;
     iface_name_to_handle_.clear();
diff --git a/wifi/aidl/default/wifi_legacy_hal.h b/wifi/aidl/default/wifi_legacy_hal.h
index 1d59b17..5168a8b 100644
--- a/wifi/aidl/default/wifi_legacy_hal.h
+++ b/wifi/aidl/default/wifi_legacy_hal.h
@@ -290,6 +290,7 @@
 using ::WIFI_ERROR_UNKNOWN;
 using ::wifi_gscan_capabilities;
 using ::wifi_hal_fn;
+using ::wifi_iface_concurrency_matrix;
 using ::WIFI_INDOOR_CHANNEL;
 using ::wifi_information_element;
 using ::WIFI_INTERFACE_IBSS;
@@ -779,6 +780,7 @@
     std::pair<wifi_error, wifi_chip_capabilities> getWifiChipCapabilities();
     wifi_error enableStaChannelForPeerNetwork(uint32_t channelCategoryEnableFlag);
     wifi_error setMloMode(wifi_mlo_mode mode);
+    std::pair<wifi_error, wifi_iface_concurrency_matrix> getSupportedIfaceConcurrencyMatrix();
 
   private:
     // Retrieve interface handles for all the available interfaces.
diff --git a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
index 77d1cb5..b5196c9 100644
--- a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
@@ -178,6 +178,7 @@
     populateStubFor(&hal_fn->wifi_nan_resume_request);
     populateStubFor(&hal_fn->wifi_set_scan_mode);
     populateStubFor(&hal_fn->wifi_set_mlo_mode);
+    populateStubFor(&hal_fn->wifi_get_supported_iface_concurrency_matrix);
     return true;
 }