Define getVendorApiLevel() function
Vendor API level is defined in ro.board.api_level or
ro.board.first_api_level. Define getVendorApiLevel() to read the API
level of the vendor implementation.
Bug: 181284704
Test: atest compatibility-host-util-tests
Change-Id: I8260257705f3d55d1d5f9fd5889319a374095f93
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/PropertyUtil.java b/common/host-side/util/src/com/android/compatibility/common/util/PropertyUtil.java
index b354f66..b833a8f 100644
--- a/common/host-side/util/src/com/android/compatibility/common/util/PropertyUtil.java
+++ b/common/host-side/util/src/com/android/compatibility/common/util/PropertyUtil.java
@@ -38,11 +38,16 @@
private static final String BUILD_TYPE_PROPERTY = "ro.build.type";
private static final String MANUFACTURER_PROPERTY = "ro.product.manufacturer";
private static final String TAG_DEV_KEYS = "dev-keys";
+ private static final String VENDOR_API_LEVEL = "ro.board.api_level";
+ private static final String VENDOR_FIRST_API_LEVEL = "ro.board.first_api_level";
private static final String VNDK_VERSION = "ro.vndk.version";
/** Value to be returned by getPropertyInt() if property is not found */
public static final int INT_VALUE_IF_UNSET = -1;
+ /** API level for current in development */
+ public static final int API_LEVEL_CURRENT = 10000;
+
public static final String GOOGLE_SETTINGS_QUERY =
"content query --uri content://com.google.settings/partner";
@@ -63,27 +68,53 @@
}
/**
- * Return the first API level for this product. If the read-only property is unset,
- * this means the first API level is the current API level, and the current API level
- * is returned.
+ * Return the first API level for this product. If the read-only property is unset, this means
+ * the first API level is the current API level, and the current API level is returned.
*/
public static int getFirstApiLevel(ITestDevice device) throws DeviceNotAvailableException {
- String propString = device.getProperty(FIRST_API_LEVEL);
- return (propString == null) ? device.getApiLevel() : Integer.parseInt(propString);
+ int firstApiLevel = getPropertyInt(device, FIRST_API_LEVEL);
+ return (firstApiLevel == INT_VALUE_IF_UNSET) ? device.getApiLevel() : firstApiLevel;
}
/**
- * Return whether the SDK version of the vendor partiton is newer than the given API level.
- * If the property is set to non-integer value, this means the vendor partition is using
- * current API level and true is returned.
+ * Return the API level of the vendor partition. It will read the following properties in order
+ * and returns the value of the first defined property. If none of them are defined, or the
+ * value is a VERSION CODENAME, returns the current API level which is defined in
+ * API_LEVEL_CURRENT.
+ *
+ * <ul>
+ * <li>ro.board.api_level
+ * <li>ro.board.first_api_level
+ * <li>ro.vndk.version
+ * </ul>
*/
+ public static int getVendorApiLevel(ITestDevice device) throws DeviceNotAvailableException {
+ String[] vendorApiLevelProps = {
+ // Use the properties in order.
+ VENDOR_API_LEVEL, VENDOR_FIRST_API_LEVEL, VNDK_VERSION,
+ };
+ for (String prop : vendorApiLevelProps) {
+ int apiLevel = getPropertyInt(device, prop);
+ if (apiLevel != INT_VALUE_IF_UNSET) {
+ return apiLevel;
+ }
+ }
+ return API_LEVEL_CURRENT;
+ }
+
+ /** Return whether the API level of the vendor partition is newer than the given API level. */
public static boolean isVendorApiLevelNewerThan(ITestDevice device, int apiLevel)
throws DeviceNotAvailableException {
- int vendorApiLevel = getPropertyInt(device, VNDK_VERSION);
- if (vendorApiLevel == INT_VALUE_IF_UNSET) {
- return true;
- }
- return vendorApiLevel > apiLevel;
+ return getVendorApiLevel(device) > apiLevel;
+ }
+
+ /**
+ * Return whether the API level of the vendor partition is same or newer than the given API
+ * level.
+ */
+ public static boolean isVendorApiLevelAtLeast(ITestDevice device, int apiLevel)
+ throws DeviceNotAvailableException {
+ return getVendorApiLevel(device) >= apiLevel;
}
/**
diff --git a/common/host-side/util/tests/src/com/android/compatibility/common/util/PropertyUtilTest.java b/common/host-side/util/tests/src/com/android/compatibility/common/util/PropertyUtilTest.java
new file mode 100644
index 0000000..e094686
--- /dev/null
+++ b/common/host-side/util/tests/src/com/android/compatibility/common/util/PropertyUtilTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.compatibility.common.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Unit tests for {@link PropertyUtil} */
+@RunWith(JUnit4.class)
+public class PropertyUtilTest {
+ private static final String FIRST_API_LEVEL = "ro.product.first_api_level";
+ private static final String VENDOR_API_LEVEL = "ro.board.api_level";
+ private static final String VENDOR_FIRST_API_LEVEL = "ro.board.first_api_level";
+ private static final String VNDK_VERSION = "ro.vndk.version";
+
+ private PropertyUtil mPropertyUtil;
+ private ITestDevice mMockDevice;
+
+ @Before
+ public void setUp() {
+ mPropertyUtil = new PropertyUtil();
+ mMockDevice = EasyMock.createMock(ITestDevice.class);
+ }
+
+ @Test
+ public void testGetFirstApiLevelFromProductFirstApiLevel() throws DeviceNotAvailableException {
+ EasyMock.expect(mMockDevice.getProperty(FIRST_API_LEVEL)).andReturn("31");
+ EasyMock.replay(mMockDevice);
+ assertEquals(31, mPropertyUtil.getFirstApiLevel(mMockDevice));
+ EasyMock.verify(mMockDevice);
+ }
+
+ @Test
+ public void testGetFirstApiLevelFromSdkVersion() throws DeviceNotAvailableException {
+ EasyMock.expect(mMockDevice.getProperty(FIRST_API_LEVEL)).andReturn(null);
+ EasyMock.expect(mMockDevice.getApiLevel()).andReturn(31);
+ EasyMock.replay(mMockDevice);
+ assertEquals(31, mPropertyUtil.getFirstApiLevel(mMockDevice));
+ EasyMock.verify(mMockDevice);
+ }
+
+ @Test
+ public void testGetVendorApiLevelFromVendorApiLevel() throws DeviceNotAvailableException {
+ EasyMock.expect(mMockDevice.getProperty(VENDOR_API_LEVEL)).andReturn("31");
+ EasyMock.replay(mMockDevice);
+ assertEquals(31, mPropertyUtil.getVendorApiLevel(mMockDevice));
+ EasyMock.verify(mMockDevice);
+ }
+
+ @Test
+ public void testGetVendorApiLevelFromVendorFirstApiLevel() throws DeviceNotAvailableException {
+ EasyMock.expect(mMockDevice.getProperty(VENDOR_API_LEVEL)).andReturn(null);
+ EasyMock.expect(mMockDevice.getProperty(VENDOR_FIRST_API_LEVEL)).andReturn("31");
+ EasyMock.replay(mMockDevice);
+ assertEquals(31, mPropertyUtil.getVendorApiLevel(mMockDevice));
+ EasyMock.verify(mMockDevice);
+ }
+
+ @Test
+ public void testGetVendorApiLevelFromVndkVersion() throws DeviceNotAvailableException {
+ EasyMock.expect(mMockDevice.getProperty(VENDOR_API_LEVEL)).andReturn(null);
+ EasyMock.expect(mMockDevice.getProperty(VENDOR_FIRST_API_LEVEL)).andReturn(null);
+ EasyMock.expect(mMockDevice.getProperty(VNDK_VERSION)).andReturn("31");
+ EasyMock.replay(mMockDevice);
+ assertEquals(31, mPropertyUtil.getVendorApiLevel(mMockDevice));
+ EasyMock.verify(mMockDevice);
+ }
+
+ @Test
+ public void testGetVendorApiLevelCurrent() throws DeviceNotAvailableException {
+ EasyMock.expect(mMockDevice.getProperty(VENDOR_API_LEVEL)).andReturn(null);
+ EasyMock.expect(mMockDevice.getProperty(VENDOR_FIRST_API_LEVEL)).andReturn(null);
+ EasyMock.expect(mMockDevice.getProperty(VNDK_VERSION)).andReturn(null);
+ EasyMock.replay(mMockDevice);
+ assertEquals(PropertyUtil.API_LEVEL_CURRENT, mPropertyUtil.getVendorApiLevel(mMockDevice));
+ EasyMock.verify(mMockDevice);
+ }
+
+ @Test
+ public void testGetVendorApiLevelCurrent2() throws DeviceNotAvailableException {
+ EasyMock.expect(mMockDevice.getProperty(VENDOR_API_LEVEL)).andReturn(null);
+ EasyMock.expect(mMockDevice.getProperty(VENDOR_FIRST_API_LEVEL)).andReturn(null);
+ EasyMock.expect(mMockDevice.getProperty(VNDK_VERSION)).andReturn("S");
+ EasyMock.replay(mMockDevice);
+ assertEquals(PropertyUtil.API_LEVEL_CURRENT, mPropertyUtil.getVendorApiLevel(mMockDevice));
+ EasyMock.verify(mMockDevice);
+ }
+
+ @Test
+ public void testIsVendorApiLevelNewerThan() throws DeviceNotAvailableException {
+ EasyMock.expect(mMockDevice.getProperty(VENDOR_API_LEVEL)).andReturn(null);
+ EasyMock.expect(mMockDevice.getProperty(VENDOR_FIRST_API_LEVEL)).andReturn("30");
+ EasyMock.replay(mMockDevice);
+ assertFalse(mPropertyUtil.isVendorApiLevelNewerThan(mMockDevice, 30));
+ EasyMock.verify(mMockDevice);
+ }
+
+ @Test
+ public void testIsVendorApiLevelAtLeast() throws DeviceNotAvailableException {
+ EasyMock.expect(mMockDevice.getProperty(VENDOR_API_LEVEL)).andReturn("30");
+ EasyMock.replay(mMockDevice);
+ assertTrue(mPropertyUtil.isVendorApiLevelAtLeast(mMockDevice, 30));
+ EasyMock.verify(mMockDevice);
+ }
+}