Add a function for VINTF test to get shipping API level

If ro.product.first_api_level is 0, assume the device is a newly
launched product. The test case determines its shipping API level by
ro.build.version.sdk which is defined by the system image.

Bug: 77142177
Test: vts-tradefed run commandAndExit vts -m VtsTrebleVendorVintfTest
Change-Id: I2202049f38aea15fe90e9a2d3152aeb0fd226464
Merged-In: I2202049f38aea15fe90e9a2d3152aeb0fd226464
diff --git a/treble/vintf/DeviceManifestTest.cpp b/treble/vintf/DeviceManifestTest.cpp
index 09b476a..1240c6b 100644
--- a/treble/vintf/DeviceManifestTest.cpp
+++ b/treble/vintf/DeviceManifestTest.cpp
@@ -16,12 +16,9 @@
 
 #include "DeviceManifestTest.h"
 
-#include <android-base/properties.h>
 #include <vintf/VintfObject.h>
 #include "SingleManifestTest.h"
 
-using android::base::GetUintProperty;
-
 namespace android {
 namespace vintf {
 namespace testing {
@@ -37,11 +34,10 @@
 // Tests that Shipping FCM Version in the device manifest is at least the
 // minimum Shipping FCM Version as required by Shipping API level.
 TEST_F(DeviceManifestTest, ShippingFcmVersion) {
-  uint64_t shipping_api_level =
-      GetUintProperty<uint64_t>(kShippingApiLevelProp, 0);
+  uint64_t shipping_api_level = GetShippingApiLevel();
+  ASSERT_NE(shipping_api_level, 0u)
+      << "Device's shipping API level cannot be determined.";
 
-  ASSERT_NE(shipping_api_level, 0u) << "sysprop " << kShippingApiLevelProp
-                                    << " is missing or cannot be parsed.";
   Level shipping_fcm_version = VintfObject::GetDeviceHalManifest()->level();
   if (shipping_fcm_version == Level::UNSPECIFIED) {
     // O / O-MR1 vendor image doesn't have shipping FCM version declared and
diff --git a/treble/vintf/utils.cpp b/treble/vintf/utils.cpp
index 09690f5..59b3e5f 100644
--- a/treble/vintf/utils.cpp
+++ b/treble/vintf/utils.cpp
@@ -21,6 +21,10 @@
 #include <string>
 #include <vector>
 
+#include <android-base/properties.h>
+
+using android::base::GetUintProperty;
+
 namespace android {
 namespace vintf {
 namespace testing {
@@ -71,7 +75,16 @@
                       // P
                       {28, static_cast<Level>(3)}}};
 
-const string kShippingApiLevelProp = "ro.product.first_api_level";
+// Returns ro.product.first_api_level if it is defined and not 0. Returns
+// ro.build.version.sdk otherwise.
+uint64_t GetShippingApiLevel() {
+  uint64_t api_level =
+      GetUintProperty<uint64_t>("ro.product.first_api_level", 0);
+  if (api_level != 0) {
+    return api_level;
+  }
+  return GetUintProperty<uint64_t>("ro.build.version.sdk", 0);
+}
 
 // For a given interface returns package root if known. Returns empty string
 // otherwise.
diff --git a/treble/vintf/utils.h b/treble/vintf/utils.h
index 68c5133..8c9c0db 100644
--- a/treble/vintf/utils.h
+++ b/treble/vintf/utils.h
@@ -77,7 +77,9 @@
 extern const map<size_t /* Shipping API Level */, Level /* FCM Version */>
     kFcm2ApiLevelMap;
 
-extern const string kShippingApiLevelProp;
+// Returns ro.product.first_api_level if it is defined and not 0. Returns
+// ro.build.version.sdk otherwise.
+uint64_t GetShippingApiLevel();
 
 // For a given interface returns package root if known. Returns empty string
 // otherwise.