Add system_ext matrix and FCM levels.

Read all files in /system_ext/etc/vintf and treat files the same way
we treat system matrix at each FCM level in /system/etc/vintf.

Bug: 140280874
Test: vintf_object_test

Change-Id: I70e12ec91192ba44d42c411629ffec40e03ccd5a
diff --git a/VintfObject.cpp b/VintfObject.cpp
index 5c9f8d9..fe57152 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -404,6 +404,7 @@
                                                   std::string* error) {
     std::vector<std::string> dirs = {
         kSystemVintfDir,
+        kSystemExtVintfDir,
         kProductVintfDir,
     };
     for (const auto& dir : dirs) {
@@ -555,6 +556,7 @@
 const std::string kVendorVintfDir = "/vendor/etc/vintf/";
 const std::string kOdmVintfDir = "/odm/etc/vintf/";
 const std::string kProductVintfDir = "/product/etc/vintf/";
+const std::string kSystemExtVintfDir = "/system_ext/etc/vintf";
 
 const std::string kVendorManifest = kVendorVintfDir + "manifest.xml";
 const std::string kSystemManifest = kSystemVintfDir + "manifest.xml";
@@ -582,6 +584,7 @@
         kVendorVintfDir,
         kOdmVintfDir,
         kProductVintfDir,
+        kSystemExtVintfDir,
         kOdmLegacyVintfDir,
         kVendorLegacyManifest,
         kVendorLegacyMatrix,
diff --git a/include/vintf/VintfObject.h b/include/vintf/VintfObject.h
index 145bae1..3194aec 100644
--- a/include/vintf/VintfObject.h
+++ b/include/vintf/VintfObject.h
@@ -354,6 +354,7 @@
 extern const std::string kVendorVintfDir;
 extern const std::string kOdmVintfDir;
 extern const std::string kProductVintfDir;
+extern const std::string kSystemExtVintfDir;
 extern const std::string kOdmLegacyVintfDir;
 extern const std::string kOdmLegacyManifest;
 extern const std::string kVendorManifest;
diff --git a/test/vintf_object_tests.cpp b/test/vintf_object_tests.cpp
index 31e54a1..ad230dc 100644
--- a/test/vintf_object_tests.cpp
+++ b/test/vintf_object_tests.cpp
@@ -1616,7 +1616,7 @@
 }
 
 class OemFcmLevelTest : public MultiMatrixTest,
-                        public WithParamInterface<std::tuple<size_t, bool>> {
+                        public WithParamInterface<std::tuple<size_t, bool, bool>> {
    protected:
     virtual void SetUp() override {
         MultiMatrixTest::SetUp();
@@ -1634,12 +1634,15 @@
 };
 
 TEST_P(OemFcmLevelTest, Test) {
-    auto&& [level, hasProduct] = GetParam();
+    auto&& [level, hasProduct, hasSystemExt] = GetParam();
 
     expectTargetFcmVersion(level);
     if (hasProduct) {
         SetUpMockMatrices(kProductVintfDir, GetOemFcmMatrixLevels("product"));
     }
+    if (hasSystemExt) {
+        SetUpMockMatrices(kSystemExtVintfDir, GetOemFcmMatrixLevels("systemext"));
+    }
 
     auto fcm = vintfObject->getFrameworkCompatibilityMatrix();
     ASSERT_NE(nullptr, fcm);
@@ -1654,19 +1657,24 @@
                                          "android.hardware.major@1.0::IMajor/default"));
     EXPECT_THAT(instances, containsOrNot(level == 1 && hasProduct,
                                          "vendor.foo.product@1.0::IExtra/default"));
+    EXPECT_THAT(instances, containsOrNot(level == 1 && hasSystemExt,
+                                         "vendor.foo.systemext@1.0::IExtra/default"));
     EXPECT_THAT(instances, Contains("android.hardware.major@2.0::IMajor/default"));
     EXPECT_THAT(instances, containsOrNot(hasProduct,
                                          "vendor.foo.product@2.0::IExtra/default"));
+    EXPECT_THAT(instances, containsOrNot(hasSystemExt,
+                                         "vendor.foo.systemext@2.0::IExtra/default"));
 }
 
 static std::string OemFcmLevelTestParamToString(
         const TestParamInfo<OemFcmLevelTest::ParamType>& info) {
-    auto&& [level, hasProduct] = info.param;
+    auto&& [level, hasProduct, hasSystemExt] = info.param;
     auto name = "Level" + std::to_string(level);
     name += "With"s + (hasProduct ? "" : "out") + "Product";
+    name += "With"s + (hasSystemExt ? "" : "out") + "SystemExt";
     return name;
 }
-INSTANTIATE_TEST_SUITE_P(OemFcmLevel, OemFcmLevelTest, Combine(Values(1, 2), Bool()),
+INSTANTIATE_TEST_SUITE_P(OemFcmLevel, OemFcmLevelTest, Combine(Values(1, 2), Bool(), Bool()),
     OemFcmLevelTestParamToString);
 // clang-format on