Fix AIDL versions in checkMissingHalsInMatrices.

Previously when AIDL HALs are checked in checkMissingHalsInMatrices,
versions doesn't exist in AIDL HALs. Now that AIDL HALs have versions,
properly check the versions in matrices.

libaidlmetadata lists only frozen versions in the .versions
field. When has_development is true, also add the next version
to the list so the next version is required to be in compatibility
matrices (or excluded).

Test: TH
Bug: 255383566
Change-Id: I3fa7a0ede59d89a87bf3c55ca260823f8e8d7b97
diff --git a/VintfObject.cpp b/VintfObject.cpp
index dacf0e8..3b1da82 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -1140,6 +1140,8 @@
     return fqName.getPackageAndVersion().string();
 }
 
+// StripAidlType(android.hardware.foo.IFoo)
+// -> android.hardware.foo
 std::string StripAidlType(const std::string& type) {
     auto items = android::base::Split(type, ".");
     if (items.empty()) {
@@ -1149,6 +1151,12 @@
     return android::base::Join(items, ".");
 }
 
+// GetAidlPackageAndVersion(android.hardware.foo.IFoo, 1)
+// -> android.hardware.foo@1
+std::string GetAidlPackageAndVersion(const std::string& package, size_t version) {
+    return package + "@" + std::to_string(version);
+}
+
 // android.hardware.foo@1.0
 std::set<std::string> HidlMetadataToPackagesAndVersions(
     const std::vector<HidlInterfaceMetadata>& hidlMetadata,
@@ -1160,16 +1168,32 @@
     return ret;
 }
 
-// android.hardware.foo
+// android.hardware.foo@1
 // All non-vintf stable interfaces are filtered out.
-std::set<std::string> AidlMetadataToVintfPackages(
+android::base::Result<std::set<std::string>> AidlMetadataToVintfPackagesAndVersions(
     const std::vector<AidlInterfaceMetadata>& aidlMetadata,
     const std::function<bool(const std::string&)>& shouldCheck) {
     std::set<std::string> ret;
     for (const auto& item : aidlMetadata) {
-        if (item.stability == "vintf") {
-            for (const auto& type : item.types) {
-                InsertIf(StripAidlType(type), shouldCheck, &ret);
+        if (item.stability != "vintf") {
+            continue;
+        }
+        for (const auto& type : item.types) {
+            auto package = StripAidlType(type);
+            for (const auto& version : item.versions) {
+                InsertIf(GetAidlPackageAndVersion(package, version), shouldCheck, &ret);
+            }
+            if (item.has_development) {
+                auto maxVerIt = std::max_element(item.versions.begin(), item.versions.end());
+                // If no frozen versions, the in-development version is 1.
+                size_t maxVer = maxVerIt == item.versions.end() ? 0 : *maxVerIt;
+                auto nextVer = maxVer + 1;
+                if (nextVer < maxVer) {
+                    return android::base::Error()
+                           << "Bad version " << maxVer << " for AIDL type " << type
+                           << "; integer overflow when inferring in-development version";
+                }
+                InsertIf(GetAidlPackageAndVersion(package, nextVer), shouldCheck, &ret);
             }
         }
     }
@@ -1233,7 +1257,9 @@
     if (!matrixFragments.ok()) return matrixFragments.error();
 
     // Filter aidlMetadata and hidlMetadata with shouldCheck.
-    auto allAidlVintfPackages = AidlMetadataToVintfPackages(aidlMetadata, shouldCheckAidl);
+    auto allAidlPackagesAndVersions =
+        AidlMetadataToVintfPackagesAndVersions(aidlMetadata, shouldCheckAidl);
+    if (!allAidlPackagesAndVersions.ok()) return allAidlPackagesAndVersions.error();
     auto allHidlPackagesAndVersions =
         HidlMetadataToPackagesAndVersions(hidlMetadata, shouldCheckHidl);
 
@@ -1244,7 +1270,11 @@
         matrix.forEachInstance([&](const MatrixInstance& matrixInstance) {
             switch (matrixInstance.format()) {
                 case HalFormat::AIDL: {
-                    allAidlVintfPackages.erase(matrixInstance.package());
+                    for (Version v = matrixInstance.versionRange().minVer();
+                         v <= matrixInstance.versionRange().maxVer(); ++v.minorVer) {
+                        allAidlPackagesAndVersions->erase(
+                            GetAidlPackageAndVersion(matrixInstance.package(), v.minorVer));
+                    }
                     return true;  // continue to next instance
                 }
                 case HalFormat::HIDL: {
@@ -1275,10 +1305,10 @@
             "The following HIDL packages are not found in any compatibility matrix fragments:\t\n" +
             android::base::Join(allHidlPackagesAndVersions, "\t\n"));
     }
-    if (!allAidlVintfPackages.empty()) {
+    if (!allAidlPackagesAndVersions->empty()) {
         errors.push_back(
             "The following AIDL packages are not found in any compatibility matrix fragments:\t\n" +
-            android::base::Join(allAidlVintfPackages, "\t\n"));
+            android::base::Join(*allAidlPackagesAndVersions, "\t\n"));
     }
 
     if (!errors.empty()) {
diff --git a/test/vintf_object_tests.cpp b/test/vintf_object_tests.cpp
index 0265df8..60cb028 100644
--- a/test/vintf_object_tests.cpp
+++ b/test/vintf_object_tests.cpp
@@ -2565,7 +2565,7 @@
 TEST_F(CheckMissingHalsTest, Pass) {
     std::vector<HidlInterfaceMetadata> hidl{{.name = "android.hardware.hidl@1.0::IHidl"}};
     std::vector<AidlInterfaceMetadata> aidl{
-        {.types = {"android.hardware.aidl.IAidl"}, .stability = "vintf"}};
+        {.types = {"android.hardware.aidl.IAidl"}, .stability = "vintf", .versions = {1}}};
     EXPECT_THAT(vintfObject->checkMissingHalsInMatrices(hidl, {}, defaultPred, defaultPred), Ok());
     EXPECT_THAT(vintfObject->checkMissingHalsInMatrices({}, aidl, defaultPred, defaultPred), Ok());
     EXPECT_THAT(vintfObject->checkMissingHalsInMatrices(hidl, aidl, defaultPred, defaultPred),
@@ -2575,7 +2575,7 @@
 TEST_F(CheckMissingHalsTest, FailVendor) {
     std::vector<HidlInterfaceMetadata> hidl{{.name = "vendor.foo.hidl@1.0"}};
     std::vector<AidlInterfaceMetadata> aidl{
-        {.types = {"vendor.foo.aidl.IAidl"}, .stability = "vintf"}};
+        {.types = {"vendor.foo.aidl.IAidl"}, .stability = "vintf", .versions = {1}}};
 
     auto res = vintfObject->checkMissingHalsInMatrices(hidl, {}, defaultPred, defaultPred);
     EXPECT_THAT(res, HasError(WithMessage(HasSubstr("vendor.foo.hidl@1.0"))));
@@ -2595,10 +2595,10 @@
     EXPECT_THAT(vintfObject->checkMissingHalsInMatrices(hidl, aidl, predicate, predicate), Ok());
 }
 
-TEST_F(CheckMissingHalsTest, FailVersion) {
+TEST_F(CheckMissingHalsTest, FailMajorVersion) {
     std::vector<HidlInterfaceMetadata> hidl{{.name = "android.hardware.hidl@2.0"}};
     std::vector<AidlInterfaceMetadata> aidl{
-        {.types = {"android.hardware.aidl2.IAidl"}, .stability = "vintf"}};
+        {.types = {"android.hardware.aidl2.IAidl"}, .stability = "vintf", .versions = {1}}};
 
     auto res = vintfObject->checkMissingHalsInMatrices(hidl, {}, defaultPred, defaultPred);
     EXPECT_THAT(res, HasError(WithMessage(HasSubstr("android.hardware.hidl@2.0"))));
@@ -2625,6 +2625,42 @@
     EXPECT_THAT(res, HasError(WithMessage(HasSubstr("android.hardware.aidl2"))));
 }
 
+TEST_F(CheckMissingHalsTest, FailMinorVersion) {
+    std::vector<HidlInterfaceMetadata> hidl{{.name = "android.hardware.hidl@1.1"}};
+    std::vector<AidlInterfaceMetadata> aidl{
+        {.types = {"android.hardware.aidl.IAidl"}, .stability = "vintf", .versions = {1, 2}}};
+
+    auto res = vintfObject->checkMissingHalsInMatrices(hidl, {}, defaultPred, defaultPred);
+    EXPECT_THAT(res, HasError(WithMessage(HasSubstr("android.hardware.hidl@1.1"))));
+
+    res = vintfObject->checkMissingHalsInMatrices({}, aidl, defaultPred, defaultPred);
+    EXPECT_THAT(res, HasError(WithMessage(HasSubstr("android.hardware.aidl@2"))));
+
+    res = vintfObject->checkMissingHalsInMatrices(hidl, aidl, defaultPred, defaultPred);
+    EXPECT_THAT(res, HasError(WithMessage(HasSubstr("android.hardware.hidl@1.1"))));
+    EXPECT_THAT(res, HasError(WithMessage(HasSubstr("android.hardware.aidl@2"))));
+}
+
+TEST_F(CheckMissingHalsTest, PassAidlInDevelopment) {
+    std::vector<AidlInterfaceMetadata> aidl{{.types = {"android.hardware.aidl.IAidl"},
+                                             .stability = "vintf",
+                                             .versions = {},
+                                             .has_development = true}};
+
+    auto res = vintfObject->checkMissingHalsInMatrices({}, aidl, defaultPred, defaultPred);
+    EXPECT_THAT(res, Ok());
+}
+
+TEST_F(CheckMissingHalsTest, FailAidlInDevelopment) {
+    std::vector<AidlInterfaceMetadata> aidl{{.types = {"android.hardware.aidl.IAidl"},
+                                             .stability = "vintf",
+                                             .versions = {1},
+                                             .has_development = true}};
+
+    auto res = vintfObject->checkMissingHalsInMatrices({}, aidl, defaultPred, defaultPred);
+    EXPECT_THAT(res, HasError(WithMessage(HasSubstr("android.hardware.aidl@2"))));
+}
+
 // A set of tests on VintfObject::checkMatrixHalsHasDefinition
 class CheckMatrixHalsHasDefinitionTest : public CheckMatricesWithHalDefTestBase {};