Merge "Fix textView id for NonExportedActivity" into rvc-dev
diff --git a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
index 67216ef..dcca509 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -33,6 +33,25 @@
THRESH_MIN_PIXEL = 4 # Crop test allowed offset
PREVIEW_SIZE = (1920, 1080) # preview size
+# Before API level 30, only resolutions with the following listed aspect ratio
+# are checked. Device launched after API level 30 will need to pass the test
+# for all advertised resolutions. Device launched before API level 30 just
+# needs to pass the test for all resolutions within these aspect ratios.
+AR_CHECKED_PRE_API_30 = ["4:3", "16:9", "18:9"]
+AR_DIFF_ATOL = 0.01
+
+
+def is_checked_aspect_ratio(first_api_level, w, h):
+ if first_api_level >= 30:
+ return True
+
+ for ar_check in AR_CHECKED_PRE_API_30:
+ match_ar_list = [float(x) for x in ar_check.split(":")]
+ match_ar = match_ar_list[0] / match_ar_list[1]
+ if np.isclose(float(w)/h, match_ar, atol=AR_DIFF_ATOL):
+ return True
+
+ return False
def calc_expected_circle_image_ratio(ref_fov, img_w, img_h):
"""Determine the circle image area ratio in percentage for a given image size.
@@ -536,8 +555,9 @@
fov_percent = calc_circle_image_ratio(
cc_w, cc_h, w_iter, h_iter)
chk_percent = calc_expected_circle_image_ratio(ref_fov, w_iter, h_iter)
- if not np.isclose(fov_percent, chk_percent,
- rtol=FOV_PERCENT_RTOL):
+ chk_enabled = is_checked_aspect_ratio(first_api, w_iter, h_iter)
+ if chk_enabled and not np.isclose(fov_percent, chk_percent,
+ rtol=FOV_PERCENT_RTOL):
msg = "FoV %%: %.2f, Ref FoV %%: %.2f, " % (
fov_percent, chk_percent)
msg += "TOL=%.f%%, img: %dx%d, ref: %dx%d" % (
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
index cd739b5..36a10f4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
@@ -375,7 +375,7 @@
CameraCharacteristics physicalChar =
manager.getCameraCharacteristics(physicalId);
- hwLevel = characteristics.get(
+ hwLevel = physicalChar.get(
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
if (hwLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY ||
hwLevel ==
@@ -384,6 +384,18 @@
continue;
}
+ int[] physicalActualCapabilities = physicalChar.get(
+ CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+ boolean physicalHaveBC = false;
+ for (int capability : physicalActualCapabilities) {
+ if (capability == BACKWARD_COMPAT) {
+ physicalHaveBC = true;
+ break;
+ }
+ }
+ if (!physicalHaveBC) {
+ continue;
+ }
// To reduce duplicate tests, only additionally test hidden physical cameras
// with different focal length compared to the default focal length of the
// logical camera.
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorTestActivity.java
old mode 100644
new mode 100755
index c4ad958..e2989ac
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/base/BaseSensorTestActivity.java
@@ -602,7 +602,12 @@
nextButtonText = R.string.next_button_text;
break;
}
- mNextButton.setText(nextButtonText);
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mNextButton.setText(nextButtonText);
+ }
+ });
}
/**
diff --git a/hostsidetests/adb/src/android/adb/cts/AdbHostTest.java b/hostsidetests/adb/src/android/adb/cts/AdbHostTest.java
index 29d718f..11a1ae0 100644
--- a/hostsidetests/adb/src/android/adb/cts/AdbHostTest.java
+++ b/hostsidetests/adb/src/android/adb/cts/AdbHostTest.java
@@ -43,6 +43,18 @@
return tf;
}
+ // *** READ THIS IF YOUR DEVICE IS FAILING THIS TEST ***
+ // This test checks to see that Microsoft OS Descriptors are enabled on the adb USB interface,
+ // so that users don't have to install a specific driver for their device in order to use adb
+ // with it (and OEMs don't have to sign and host that driver).
+ //
+ // adbd exports Microsoft OS descriptors when setting up its endpoint descriptors, but the
+ // kernel requires that the OS descriptor functionality be enabled separately by writing "1" to
+ // the gadget's configfs file at /config/usb_gadget/g<N>/os_desc/use (where <N> is probably 1).
+ // To pass this test, you need to modify your USB HAL implementation to do this.
+ //
+ // See https://android.googlesource.com/platform/hardware/google/pixel/+/5c7c6d5edcbe04454eb9a40f947ac0a3045f64eb
+ // for the patch that enabled this on Pixel devices.
public void testHasMsOsDescriptors() throws Exception {
File check_ms_os_desc = copyResourceToTempFile("/check_ms_os_desc");
check_ms_os_desc.setExecutable(true);
diff --git a/hostsidetests/appsecurity/Android.bp b/hostsidetests/appsecurity/Android.bp
index ae185c7..3a569db 100644
--- a/hostsidetests/appsecurity/Android.bp
+++ b/hostsidetests/appsecurity/Android.bp
@@ -17,7 +17,7 @@
defaults: ["cts_defaults"],
// Only compile source java files in this apk.
- srcs: ["src/**/*.java"],
+ srcs: ["src/**/*.java", "src/**/*.kt"],
libs: [
"cts-tradefed",
@@ -27,7 +27,11 @@
"hamcrest-library",
],
- static_libs: ["CompatChangeGatingTestBase"],
+ static_libs: [
+ "CompatChangeGatingTestBase",
+ "CtsPkgInstallerConstants",
+ "cts-host-utils",
+ ],
java_resource_dirs: ["res"],
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
index 24cc5ae..283d3cb 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
@@ -28,7 +28,7 @@
/**
* Base class.
*/
-abstract class BaseAppSecurityTest extends BaseHostJUnit4Test {
+public abstract class BaseAppSecurityTest extends BaseHostJUnit4Test {
/** Whether multi-user is supported. */
protected boolean mSupportsMultiUser;
@@ -92,7 +92,10 @@
this(false);
}
public InstallMultiple(boolean instant) {
- super(getDevice(), getBuild(), getAbi());
+ this(instant, true);
+ }
+ public InstallMultiple(boolean instant, boolean grantPermissions) {
+ super(getDevice(), getBuild(), getAbi(), grantPermissions);
addArg(instant ? "--instant" : "");
addArg("--force-queryable");
}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseInstallMultiple.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseInstallMultiple.java
index 54c00dc..4e43022 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseInstallMultiple.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseInstallMultiple.java
@@ -51,10 +51,17 @@
private boolean mUseNaturalAbi;
public BaseInstallMultiple(ITestDevice device, IBuildInfo buildInfo, IAbi abi) {
+ this(device, buildInfo, abi, true);
+ }
+
+ public BaseInstallMultiple(ITestDevice device, IBuildInfo buildInfo, IAbi abi,
+ boolean grantPermissions) {
mDevice = device;
mBuild = buildInfo;
mAbi = abi;
- addArg("-g");
+ if (grantPermissions) {
+ addArg("-g");
+ }
}
T addArg(String arg) {
@@ -114,6 +121,11 @@
return (T) this;
}
+ T restrictPermissions() {
+ addArg("--restrict-permissions");
+ return (T) this;
+ }
+
protected String deriveRemoteName(String originalName, int index) {
return index + "_" + originalName;
}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageSetInstallerTest.kt b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageSetInstallerTest.kt
new file mode 100644
index 0000000..f3c3420
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageSetInstallerTest.kt
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2020 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 android.appsecurity.cts
+
+import android.appsecurity.cts.PackageSetInstallerConstants.CHANGE_ID
+import android.appsecurity.cts.PackageSetInstallerConstants.PERMISSION_HARD_RESTRICTED
+import android.appsecurity.cts.PackageSetInstallerConstants.PERMISSION_IMMUTABLY_SOFT_RESTRICTED
+import android.appsecurity.cts.PackageSetInstallerConstants.PERMISSION_KEY
+import android.appsecurity.cts.PackageSetInstallerConstants.PERMISSION_NOT_RESTRICTED
+import android.appsecurity.cts.PackageSetInstallerConstants.SHOULD_SUCCEED_KEY
+import android.appsecurity.cts.PackageSetInstallerConstants.SHOULD_THROW_EXCEPTION_KEY
+import android.appsecurity.cts.PackageSetInstallerConstants.TARGET_APK
+import android.appsecurity.cts.PackageSetInstallerConstants.TARGET_PKG
+import android.appsecurity.cts.PackageSetInstallerConstants.WHITELIST_APK
+import android.appsecurity.cts.PackageSetInstallerConstants.WHITELIST_PKG
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters
+import android.cts.host.utils.DeviceJUnit4Parameterized
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+/**
+ * This test verifies protection for an exploit where any app could set the installer package
+ * name for another app if the installer was uninstalled or never set.
+ *
+ * It mimics both the set installer logic and checks for a permission bypass caused by this exploit,
+ * where an app could take installer for itself and whitelist itself to receive protected
+ * permissions.
+ */
+@RunWith(DeviceJUnit4Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(
+ DeviceJUnit4ClassRunnerWithParameters.RunnerFactory::class)
+class PackageSetInstallerTest : BaseAppSecurityTest() {
+
+ companion object {
+
+ @JvmStatic
+ @Parameterized.Parameters(name = "{1}")
+ fun parameters() = arrayOf(
+ arrayOf(true, "throwException"),
+ arrayOf(false, "failSilently")
+ )
+ }
+
+ @JvmField
+ @Parameterized.Parameter(0)
+ var failSilently = false
+
+ @Parameterized.Parameter(1)
+ lateinit var testName: String
+
+ @Before
+ @After
+ fun uninstallTestPackages() {
+ device.uninstallPackage(TARGET_PKG)
+ device.uninstallPackage(WHITELIST_PKG)
+ }
+
+ @After
+ fun resetChanges() {
+ device.executeShellCommand("am compat reset $CHANGE_ID $TARGET_PKG")
+ device.executeShellCommand("am compat reset $CHANGE_ID $WHITELIST_PKG")
+ }
+
+ @Before
+ fun initializeChangeState() {
+ if (failSilently) {
+ device.executeShellCommand("am compat disable $CHANGE_ID $TARGET_PKG")
+ device.executeShellCommand("am compat disable $CHANGE_ID $WHITELIST_PKG")
+ } else {
+ resetChanges()
+ }
+ }
+
+ @Test
+ fun notRestricted() {
+ runTest(removeWhitelistShouldSucceed = false,
+ permission = PERMISSION_NOT_RESTRICTED,
+ finalState = GrantState.TRUE)
+ }
+
+ @Test
+ fun hardRestricted() {
+ runTest(removeWhitelistShouldSucceed = true,
+ permission = PERMISSION_HARD_RESTRICTED,
+ finalState = GrantState.FALSE)
+ }
+
+ @Test
+ fun immutablySoftRestrictedGranted() {
+ runTest(removeWhitelistShouldSucceed = null,
+ permission = PERMISSION_IMMUTABLY_SOFT_RESTRICTED,
+ finalState = GrantState.TRUE_EXEMPT)
+ }
+
+ @Test
+ fun immutablySoftRestrictedRevoked() {
+ runTest(removeWhitelistShouldSucceed = null,
+ permission = PERMISSION_IMMUTABLY_SOFT_RESTRICTED,
+ restrictPermissions = true,
+ finalState = GrantState.TRUE_RESTRICTED)
+ }
+
+ private fun runTest(
+ removeWhitelistShouldSucceed: Boolean?,
+ permission: String,
+ restrictPermissions: Boolean = false,
+ finalState: GrantState
+ ) {
+ // Verifies throwing a SecurityException or failing silently for backwards compatibility
+ val testArgs: Map<String, String?> = mapOf(
+ PERMISSION_KEY to permission
+ )
+
+ // First, install both packages and ensure no installer is set
+ InstallMultiple(false, false)
+ .addFile(TARGET_APK)
+ .allowTest()
+ .forUser(mPrimaryUserId)
+ .apply {
+ if (restrictPermissions) {
+ restrictPermissions()
+ }
+ }
+ .run()
+
+ InstallMultiple(false, false)
+ .addFile(WHITELIST_APK)
+ .allowTest()
+ .forUser(mPrimaryUserId)
+ .run()
+
+ assertPermission(false, permission)
+ assertTargetInstaller(null)
+
+ // Install the installer whitelist app and take over the installer package. This methods
+ // adopts the INSTALL_PACKAGES permission and verifies that the new behavior of checking
+ // this permission is applied.
+ Utils.runDeviceTests(device, WHITELIST_PKG, ".PermissionWhitelistTest",
+ "setTargetInstallerPackage", mPrimaryUserId,
+ testArgs.plus(SHOULD_THROW_EXCEPTION_KEY to (!failSilently).toString()))
+ assertTargetInstaller(WHITELIST_PKG)
+
+ // Verify that without whitelist restriction, the target app can be granted the permission
+ grantPermission(permission)
+ assertPermission(true, permission)
+ revokePermission(permission)
+ assertPermission(false, permission)
+
+ val whitelistArgs = testArgs
+ .plus(SHOULD_SUCCEED_KEY to removeWhitelistShouldSucceed?.toString())
+ .filterValues { it != null }
+
+ // Now restrict the permission from the target app using the whitelist app
+ Utils.runDeviceTests(device, WHITELIST_PKG, ".PermissionWhitelistTest",
+ "removeWhitelistRestrictedPermission", mPrimaryUserId, whitelistArgs)
+
+ // Now remove the installer and verify the installer is wiped
+ device.uninstallPackage(WHITELIST_PKG)
+ assertTargetInstaller(null)
+
+ // Verify whitelist restriction retained by attempting and failing to grant permission
+ assertPermission(false, permission)
+ grantPermission(permission)
+ assertGrantState(finalState, permission)
+ revokePermission(permission)
+
+ // Attempt exploit to take over installer package and have target whitelist itself
+ Utils.runDeviceTests(device, TARGET_PKG, ".PermissionRequestTest",
+ "setSelfAsInstallerAndWhitelistPermission", mPrimaryUserId,
+ testArgs.plus(SHOULD_THROW_EXCEPTION_KEY to (!failSilently).toString()))
+
+ // Assert nothing changed about whitelist restriction
+ assertTargetInstaller(null)
+ grantPermission(permission)
+ assertGrantState(finalState, permission)
+ }
+
+ private fun assertTargetInstaller(installer: String?) {
+ assertThat(device.executeShellCommand("pm list packages -i | grep $TARGET_PKG").trim())
+ .isEqualTo("package:$TARGET_PKG installer=$installer")
+ }
+
+ private fun assertPermission(granted: Boolean, permission: String) {
+ assertThat(device.executeShellCommand("dumpsys package $TARGET_PKG | grep $permission"))
+ .contains("$permission: granted=$granted")
+ }
+
+ private fun grantPermission(permission: String) {
+ device.executeShellCommand("pm grant $TARGET_PKG $permission")
+ }
+
+ private fun revokePermission(permission: String) {
+ device.executeShellCommand("pm revoke $TARGET_PKG $permission")
+ }
+
+ private fun assertGrantState(state: GrantState, permission: String) {
+ val output = device.executeShellCommand(
+ "dumpsys package $TARGET_PKG | grep \"$permission: granted\"").trim()
+
+ // Make sure only the expected output line is returned
+ assertWithMessage(output).that(output.lines().size).isEqualTo(1)
+
+ when (state) {
+ GrantState.TRUE -> {
+ assertThat(output).contains("granted=true")
+ assertThat(output).doesNotContain("RESTRICTION")
+ assertThat(output).doesNotContain("EXEMPT")
+ }
+ GrantState.TRUE_EXEMPT -> {
+ assertThat(output).contains("granted=true")
+ assertThat(output).contains("RESTRICTION_INSTALLER_EXEMPT")
+ }
+ GrantState.TRUE_RESTRICTED -> {
+ assertThat(output).contains("granted=true")
+ assertThat(output).contains("APPLY_RESTRICTION")
+ assertThat(output).doesNotContain("EXEMPT")
+ }
+ GrantState.FALSE -> {
+ assertThat(output).contains("granted=false")
+ }
+ }
+ }
+
+ enum class GrantState {
+ // Granted in full, unrestricted
+ TRUE,
+
+ // Granted in full by exemption
+ TRUE_EXEMPT,
+
+ // Granted in part
+ TRUE_RESTRICTED,
+
+ // Not granted at all
+ FALSE
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
index 0886269..987efde 100644
--- a/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
@@ -78,6 +78,9 @@
private ContentResolver mContentResolver;
private int mUserId;
+ private static int currentAttempt = 0;
+ private static final int MAX_NUMBER_OF_ATTEMPT = 10;
+
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
@@ -545,9 +548,19 @@
runShellCommand(InstrumentationRegistry.getInstrumentation(), cmd);
}
- static File stageFile(File file) throws IOException {
- file.getParentFile().mkdirs();
- file.createNewFile();
+ static File stageFile(File file) throws Exception {
+ // Sometimes file creation fails due to slow permission update, try more times
+ while(currentAttempt < MAX_NUMBER_OF_ATTEMPT) {
+ try {
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ return file;
+ } catch(IOException e) {
+ currentAttempt++;
+ // wait 500ms
+ Thread.sleep(500);
+ }
+ }
return file;
}
}
diff --git a/hostsidetests/appsecurity/test-apps/PackageInstallerPermissionRequestApp/Android.bp b/hostsidetests/appsecurity/test-apps/PackageInstallerPermissionRequestApp/Android.bp
new file mode 100644
index 0000000..990ef49
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PackageInstallerPermissionRequestApp/Android.bp
@@ -0,0 +1,40 @@
+// Copyright (C) 2020 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.
+
+android_test_helper_app {
+ name: "CtsPkgInstallerPermRequestApp",
+ defaults: ["cts_defaults"],
+ static_libs: [
+ "androidx.test.rules",
+ "truth-prebuilt",
+ "CtsPkgInstallerConstants",
+ ],
+ srcs: ["src/**/*.kt"],
+ // tag this module as a cts test artifact
+ test_suites: [
+ "cts",
+ "vts10",
+ "general-tests",
+ ],
+ sdk_version: "test_current",
+ target_sdk_version: "30",
+ // sign this app with a different cert than CtsPkgInstallerPermWhitelistApp
+ certificate: ":cts-testkey2",
+}
+
+java_library {
+ name: "CtsPkgInstallerConstants",
+ srcs: ["utils/src/**/PackageSetInstallerConstants.kt"],
+ host_supported: true,
+}
diff --git a/hostsidetests/appsecurity/test-apps/PackageInstallerPermissionRequestApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/PackageInstallerPermissionRequestApp/AndroidManifest.xml
new file mode 100644
index 0000000..7d0ab56
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PackageInstallerPermissionRequestApp/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.packageinstallerpermissionrequestapp">
+
+ <uses-permission android:name="android.permission.SEND_SMS" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.cts.packageinstallerpermissionrequestapp"
+ android:label="Test for unset package installer permission exploit."/>
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/PackageInstallerPermissionRequestApp/src/com/android/cts/packageinstallerpermissionrequestapp/PermissionRequestTest.kt b/hostsidetests/appsecurity/test-apps/PackageInstallerPermissionRequestApp/src/com/android/cts/packageinstallerpermissionrequestapp/PermissionRequestTest.kt
new file mode 100644
index 0000000..1ca6a7f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PackageInstallerPermissionRequestApp/src/com/android/cts/packageinstallerpermissionrequestapp/PermissionRequestTest.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 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.cts.packageinstallerpermissionrequestapp
+
+import android.Manifest
+import android.appsecurity.cts.PackageSetInstallerConstants
+import android.appsecurity.cts.PackageSetInstallerConstants.SHOULD_THROW_EXCEPTION_KEY
+import android.content.Context
+import android.content.pm.PackageManager
+import android.os.Bundle
+import androidx.test.InstrumentationRegistry
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.ExpectedException
+
+class PermissionRequestTest {
+
+ @get:Rule
+ val expectedException = ExpectedException.none()
+
+ private val arguments: Bundle = InstrumentationRegistry.getArguments()
+ private val permission = arguments.getString(PackageSetInstallerConstants.PERMISSION_KEY)!!
+ private val context: Context = InstrumentationRegistry.getContext()
+ private val packageName = context.packageName
+ private val packageManager = context.packageManager
+
+ @Before
+ @After
+ fun verifyPermissionsDeniedAndInstallerUnchanged() {
+ assertThat(context.checkSelfPermission(permission))
+ .isEqualTo(PackageManager.PERMISSION_DENIED)
+ assertThat(context.checkSelfPermission(Manifest.permission.INSTALL_PACKAGES))
+ .isEqualTo(PackageManager.PERMISSION_DENIED)
+ assertThat(packageManager.getInstallerPackageName(packageName))
+ .isEqualTo(null)
+ }
+
+ @Test
+ fun setSelfAsInstallerAndWhitelistPermission() {
+ val shouldThrowException = arguments.getString(SHOULD_THROW_EXCEPTION_KEY)!!.toBoolean()
+ if (shouldThrowException) {
+ expectedException.expect(SecurityException::class.java)
+ }
+
+ try {
+ // This set call should fail
+ packageManager.setInstallerPackageName(packageName, packageName)
+ } finally {
+ // But also call the whitelist method to attempt to take the permission regardless.
+ // If this fails, which it should, it should also be a SecurityException.
+ try {
+ packageManager.addWhitelistedRestrictedPermission(packageName,
+ permission, PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)
+ Assert.fail("addWhitelistedRestrictedPermission did not throw SecurityException")
+ } catch (ignored: SecurityException) {
+ // Ignore this to defer to shouldThrowException from above call
+ }
+ }
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/PackageInstallerPermissionRequestApp/utils/src/android/appsecurity/cts/PackageSetInstallerConstants.kt b/hostsidetests/appsecurity/test-apps/PackageInstallerPermissionRequestApp/utils/src/android/appsecurity/cts/PackageSetInstallerConstants.kt
new file mode 100644
index 0000000..723cb94
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PackageInstallerPermissionRequestApp/utils/src/android/appsecurity/cts/PackageSetInstallerConstants.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 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 android.appsecurity.cts
+
+// Placed in CtsPkgInstallerPermRequestApp sources as its manifest declares what permissions to test
+object PackageSetInstallerConstants {
+
+ // The app that will be attempting to take over as installer and grant itself permissions
+ const val TARGET_APK = "CtsPkgInstallerPermRequestApp.apk"
+ const val TARGET_PKG = "com.android.cts.packageinstallerpermissionrequestapp"
+
+ // The app acting as the original installer who can restrict permissions
+ const val WHITELIST_APK = "CtsPkgInstallerPermWhitelistApp.apk"
+ const val WHITELIST_PKG = "com.android.cts.packageinstallerpermissionwhitelistapp"
+
+ const val PERMISSION_HARD_RESTRICTED = "android.permission.SEND_SMS"
+ const val PERMISSION_NOT_RESTRICTED = "android.permission.ACCESS_COARSE_LOCATION"
+ const val PERMISSION_IMMUTABLY_SOFT_RESTRICTED = "android.permission.READ_EXTERNAL_STORAGE"
+ const val PERMISSION_KEY = "permission"
+
+ // Whether setInstallerPackageName should throw
+ const val SHOULD_THROW_EXCEPTION_KEY = "shouldThrowException"
+
+ // Whether or not some boolean return method call should succeed
+ const val SHOULD_SUCCEED_KEY = "shouldSucceed"
+
+ // PackageManagerService.THROW_EXCEPTION_ON_REQUIRE_INSTALL_PACKAGES_TO_ADD_INSTALLER_PACKAGE
+ const val CHANGE_ID = 150857253
+}
diff --git a/hostsidetests/appsecurity/test-apps/PackageInstallerWhitelistApp/Android.bp b/hostsidetests/appsecurity/test-apps/PackageInstallerWhitelistApp/Android.bp
new file mode 100644
index 0000000..b731a05
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PackageInstallerWhitelistApp/Android.bp
@@ -0,0 +1,35 @@
+// Copyright (C) 2020 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.
+
+android_test_helper_app {
+ name: "CtsPkgInstallerPermWhitelistApp",
+ defaults: ["cts_defaults"],
+ static_libs: [
+ "androidx.test.rules",
+ "compatibility-device-util-axt",
+ "CtsPkgInstallerConstants",
+ "testng",
+ ],
+ srcs: ["src/**/*.kt"],
+ // tag this module as a cts test artifact
+ test_suites: [
+ "cts",
+ "vts10",
+ "general-tests",
+ ],
+ sdk_version: "test_current",
+ target_sdk_version: "30",
+ // sign this app with a different cert than CtsPkgInstallerPermRequestApp
+ certificate: ":cts-testkey1",
+}
diff --git a/hostsidetests/appsecurity/test-apps/PackageInstallerWhitelistApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/PackageInstallerWhitelistApp/AndroidManifest.xml
new file mode 100644
index 0000000..d54b9c5
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PackageInstallerWhitelistApp/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.packageinstallerpermissionwhitelistapp">
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.cts.packageinstallerpermissionwhitelistapp"
+ android:label="Test for unset package installer permission exploit."/>
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/PackageInstallerWhitelistApp/src/com/android/cts/packageinstallerpermissionwhitelistapp/PermissionWhitelistTest.kt b/hostsidetests/appsecurity/test-apps/PackageInstallerWhitelistApp/src/com/android/cts/packageinstallerpermissionwhitelistapp/PermissionWhitelistTest.kt
new file mode 100644
index 0000000..464047e
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PackageInstallerWhitelistApp/src/com/android/cts/packageinstallerpermissionwhitelistapp/PermissionWhitelistTest.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2020 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.cts.packageinstallerpermissionwhitelistapp
+
+import android.Manifest
+import android.appsecurity.cts.PackageSetInstallerConstants
+import android.appsecurity.cts.PackageSetInstallerConstants.PERMISSION_KEY
+import android.appsecurity.cts.PackageSetInstallerConstants.SHOULD_THROW_EXCEPTION_KEY
+import android.appsecurity.cts.PackageSetInstallerConstants.TARGET_PKG
+import android.content.Context
+import android.content.pm.PackageManager
+import android.os.Bundle
+import androidx.test.InstrumentationRegistry
+import com.android.compatibility.common.util.ShellIdentityUtils
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.testng.Assert.assertThrows
+
+class PermissionWhitelistTest {
+
+ private val arguments: Bundle = InstrumentationRegistry.getArguments()
+ private val shouldThrowException = arguments.getString(SHOULD_THROW_EXCEPTION_KEY)
+ ?.toBoolean() ?: false
+ private val permission = arguments.getString(PERMISSION_KEY)!!
+ private val context: Context = InstrumentationRegistry.getContext()
+ private val packageName = context.packageName
+ private val packageManager = context.packageManager
+
+ @Before
+ fun verifyNoInstallPackagesPermissions() {
+ // This test adopts shell permissions to get INSTALL_PACKAGES. That ensures that the
+ // whitelist package having INSTALL_PACKAGES doesn't bypass any checks. In a realistic
+ // scenario, this whitelisting app would request install, not directly install the target
+ // package.
+ assertThat(context.checkSelfPermission(Manifest.permission.INSTALL_PACKAGES))
+ .isEqualTo(PackageManager.PERMISSION_DENIED)
+ }
+
+ @Test
+ fun setTargetInstallerPackage() {
+ assertTargetInstaller(null)
+
+ val block = {
+ packageManager.setInstallerPackageName(TARGET_PKG, packageName)
+ }
+
+ if (shouldThrowException) {
+ assertThrows(SecurityException::class.java) { block() }
+ } else {
+ block()
+ }
+
+ assertTargetInstaller(null)
+
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(packageManager,
+ ShellIdentityUtils.ShellPermissionMethodHelperNoReturn {
+ it.setInstallerPackageName(TARGET_PKG, packageName)
+ }, Manifest.permission.INSTALL_PACKAGES)
+ assertTargetInstaller(packageName)
+ }
+
+ @Test
+ fun removeWhitelistRestrictedPermission() {
+ val block = {
+ packageManager.removeWhitelistedRestrictedPermission(TARGET_PKG, permission,
+ PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)
+ }
+
+ val shouldSucceed = arguments.getString(
+ PackageSetInstallerConstants.SHOULD_SUCCEED_KEY)
+ if (shouldSucceed == null) {
+ assertThrows(SecurityException::class.java) { block() }
+ } else {
+ assertThat(block()).isEqualTo(shouldSucceed.toBoolean())
+ }
+
+ assertThat(packageManager.checkPermission(permission, TARGET_PKG))
+ .isEqualTo(PackageManager.PERMISSION_DENIED)
+ }
+
+ private fun assertTargetInstaller(installer: String?) {
+ assertThat(packageManager.getInstallerPackageName(TARGET_PKG))
+ .isEqualTo(installer)
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteExternalStorageTest.java b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteExternalStorageTest.java
index 6a7aa7e..c16d7f3 100644
--- a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteExternalStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteExternalStorageTest.java
@@ -115,7 +115,13 @@
assertFalse(probe.exists());
assertTrue(probe.mkdirs());
- assertDirReadWriteAccess(probe);
+ try {
+ assertDirReadWriteAccess(probe);
+ }
+ finally {
+ probe.delete();
+ assertFalse(probe.exists());
+ }
}
/**
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 9c46c5f..d9fc9eb 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -913,7 +913,7 @@
@Test
public void testDefaultSmsApplication() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasTelephony) {
return;
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 6a9eed4..fb4c5e9 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -57,17 +57,6 @@
DEVICE_OWNER_PKG + ".BaseDeviceOwnerTest$BasicAdminReceiver";
@Test
- public void testManagedProfilesSupportedWithLockScreenOnly() throws Exception {
- if (!mHasFeature || hasDeviceFeature("android.software.leanback")) {
- return;
- }
- // Managed profiles should be only supported if the device supports the secure lock
- // screen feature.
- // Exception is Android TV which does not support lock screen feature.
- assertTrue(mHasSecureLockScreen);
- }
-
- @Test
public void testManagedProfileSetup() throws Exception {
if (!mHasFeature) {
return;
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
index 98e1c59..e3cbad8 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
@@ -253,10 +253,13 @@
try {
runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DeviceFeatureUtils",
"testHasFactoryResetProtectionPolicy", mUserId);
- } catch (Exception e) {
+ } catch (AssertionError e) {
// Unable to continue running tests because factory reset protection policy is not
// supported on the device
return;
+ } catch (Exception e) {
+ // Also skip test in case of other exceptions
+ return;
}
assertMetricsLogged(getDevice(), () -> {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
index acb524b..f575fc7 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
@@ -474,7 +474,7 @@
@Test
public void testPersonalAppsSuspensionSms() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasTelephony) {
return;
}
diff --git a/hostsidetests/media/Android.bp b/hostsidetests/media/Android.bp
index 3e85112..635c5c2 100644
--- a/hostsidetests/media/Android.bp
+++ b/hostsidetests/media/Android.bp
@@ -33,6 +33,10 @@
"tradefed",
"compatibility-host-util",
],
+
+ static_libs: [
+ "cts-host-utils",
+ ],
}
filegroup {
diff --git a/hostsidetests/media/bitstreams/Android.bp b/hostsidetests/media/bitstreams/Android.bp
index 9c17208..f13984e 100644
--- a/hostsidetests/media/bitstreams/Android.bp
+++ b/hostsidetests/media/bitstreams/Android.bp
@@ -22,6 +22,9 @@
"cts-tradefed",
"tradefed",
],
+ static_libs: [
+ "cts-host-utils",
+ ],
// Tag this module as a cts test artifact
test_suites: [
"cts",
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitBpBitstreamsFullTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitBpBitstreamsFullTest.java
index 72bb15a..0c18703 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitBpBitstreamsFullTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitBpBitstreamsFullTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitBpBitstreamsTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitBpBitstreamsTest.java
index 5bcfe7e..6ca00d8 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitBpBitstreamsTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitBpBitstreamsTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.Parameterized.UseParametersRunnerFactory;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitHpBitstreamsFullTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitHpBitstreamsFullTest.java
index 7db0198f..3dd9b35 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitHpBitstreamsFullTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitHpBitstreamsFullTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitHpBitstreamsTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitHpBitstreamsTest.java
index 6ba3822..7c06151 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitHpBitstreamsTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitHpBitstreamsTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.Parameterized.UseParametersRunnerFactory;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitMpBitstreamsFullTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitMpBitstreamsFullTest.java
index 4811150..1634856 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitMpBitstreamsFullTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitMpBitstreamsFullTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitMpBitstreamsTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitMpBitstreamsTest.java
index b7f2c67..90e9bdf 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitMpBitstreamsTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/H264Yuv420_8bitMpBitstreamsTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.Parameterized.UseParametersRunnerFactory;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv400BitstreamsFullTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv400BitstreamsFullTest.java
index e00283f..50e9924 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv400BitstreamsFullTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv400BitstreamsFullTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv420BitstreamsFullTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv420BitstreamsFullTest.java
index eb0fda7..b7a752d 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv420BitstreamsFullTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv420BitstreamsFullTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv420BitstreamsTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv420BitstreamsTest.java
index 1334c82..7d8b289 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv420BitstreamsTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv420BitstreamsTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.Parameterized.UseParametersRunnerFactory;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv422BitstreamsFullTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv422BitstreamsFullTest.java
index 0efdad2..528eefb 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv422BitstreamsFullTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv422BitstreamsFullTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv444BitstreamsFullTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv444BitstreamsFullTest.java
index 0f564ea..94bad70 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv444BitstreamsFullTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/HevcYuv444BitstreamsFullTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp8BitstreamsFullTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp8BitstreamsFullTest.java
index bbfc2eb..7146d94 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp8BitstreamsFullTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp8BitstreamsFullTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp8BitstreamsTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp8BitstreamsTest.java
index 8587abd..679850a 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp8BitstreamsTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp8BitstreamsTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.Parameterized.UseParametersRunnerFactory;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv420BitstreamsFullTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv420BitstreamsFullTest.java
index d209011..656ea21 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv420BitstreamsFullTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv420BitstreamsFullTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv420BitstreamsTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv420BitstreamsTest.java
index 9b048bb..b80ff7f 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv420BitstreamsTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv420BitstreamsTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.Parameterized.UseParametersRunnerFactory;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv422BitstreamsFullTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv422BitstreamsFullTest.java
index a03f1c4..3dda21a 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv422BitstreamsFullTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv422BitstreamsFullTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv444BitstreamsFullTest.java b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv444BitstreamsFullTest.java
index 22786fc..bf6b095 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv444BitstreamsFullTest.java
+++ b/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/Vp9Yuv444BitstreamsFullTest.java
@@ -15,6 +15,9 @@
*/
package android.media.cts.bitstreams;
+import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters;
+import android.cts.host.utils.DeviceJUnit4Parameterized;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
diff --git a/hostsidetests/rollback/app/AndroidManifest.xml b/hostsidetests/rollback/app/AndroidManifest.xml
index 9d4d5d2..71cf5c1 100644
--- a/hostsidetests/rollback/app/AndroidManifest.xml
+++ b/hostsidetests/rollback/app/AndroidManifest.xml
@@ -17,7 +17,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.rollback.host.app" >
- <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+ <queries>
+ <package android:name="com.android.cts.ctsshim" />
+ <package android:name="com.android.cts.priv.ctsshim" />
+ </queries>
+
<application>
<receiver android:name="com.android.cts.install.lib.LocalIntentSender"
android:exported="true" />
diff --git a/hostsidetests/rollback/app2/AndroidManifest.xml b/hostsidetests/rollback/app2/AndroidManifest.xml
index 3105857..be6d483 100644
--- a/hostsidetests/rollback/app2/AndroidManifest.xml
+++ b/hostsidetests/rollback/app2/AndroidManifest.xml
@@ -17,7 +17,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.rollback.host.app2" >
- <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application>
<receiver android:name="com.android.cts.install.lib.LocalIntentSender"
android:exported="true" />
diff --git a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java
index 7c2bf54..4ca2e12 100644
--- a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java
@@ -176,4 +176,9 @@
public void testCanRenameAFileWithNoDBRow_hasRW() throws Exception {
runDeviceTest("testCanRenameAFileWithNoDBRow_hasRW");
}
+
+ @Test
+ public void testCaseInsensitivity() throws Exception {
+ runDeviceTest("testAndroidDataObbCannotBeDeleted");
+ }
}
diff --git a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
index c380d1a..d0f2b16 100644
--- a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
@@ -165,6 +165,7 @@
runDeviceTest("testCreateLowerCaseDeleteUpperCase");
runDeviceTest("testCreateUpperCaseDeleteLowerCase");
runDeviceTest("testCreateMixedCaseDeleteDifferentMixedCase");
+ runDeviceTest("testAndroidDataObbDoesNotForgetMount");
}
@Test
diff --git a/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/LegacyStorageTest.java b/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/LegacyStorageTest.java
index 67a8fec..251f65a 100644
--- a/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/LegacyStorageTest.java
+++ b/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/LegacyStorageTest.java
@@ -617,6 +617,25 @@
}
}
+ @Test
+ public void testAndroidDataObbCannotBeDeleted() throws Exception {
+ File canDeleteDir = new File("/sdcard/canDelete");
+ canDeleteDir.mkdirs();
+
+ File dataDir = new File("/sdcard/Android/data");
+ File obbDir = new File("/sdcard/Android/obb");
+ File androidDir = new File("/sdcard/Android");
+
+ assertThat(dataDir.exists()).isTrue();
+ assertThat(obbDir.exists()).isTrue();
+ assertThat(androidDir.exists()).isTrue();
+
+ assertThat(dataDir.delete()).isFalse();
+ assertThat(obbDir.delete()).isFalse();
+ assertThat(androidDir.delete()).isFalse();
+ assertThat(canDeleteDir.delete()).isTrue();
+ }
+
private static void assertCanCreateFile(File file) throws IOException {
if (file.exists()) {
file.delete();
diff --git a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
index 4022fb5..bd75bcf 100644
--- a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
+++ b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
@@ -121,6 +121,7 @@
import android.provider.MediaStore;
import android.system.ErrnoException;
import android.system.Os;
+import android.system.StructStat;
import android.util.Log;
import androidx.annotation.Nullable;
@@ -1000,6 +1001,30 @@
createDeleteCreate(mixedCase1, mixedCase2);
}
+ @Test
+ public void testAndroidDataObbDoesNotForgetMount() throws Exception {
+ File dataDir = getContext().getExternalFilesDir(null);
+ File upperCaseDataDir = new File(dataDir.getPath().replace("Android/data", "ANDROID/DATA"));
+
+ File obbDir = getContext().getObbDir();
+ File upperCaseObbDir = new File(obbDir.getPath().replace("Android/obb", "ANDROID/OBB"));
+
+
+ StructStat beforeDataStruct = Os.stat(dataDir.getPath());
+ StructStat beforeObbStruct = Os.stat(obbDir.getPath());
+
+ assertThat(dataDir.exists()).isTrue();
+ assertThat(upperCaseDataDir.exists()).isTrue();
+ assertThat(obbDir.exists()).isTrue();
+ assertThat(upperCaseObbDir.exists()).isTrue();
+
+ StructStat afterDataStruct = Os.stat(upperCaseDataDir.getPath());
+ StructStat afterObbStruct = Os.stat(upperCaseObbDir.getPath());
+
+ assertThat(beforeDataStruct.st_dev).isEqualTo(afterDataStruct.st_dev);
+ assertThat(beforeObbStruct.st_dev).isEqualTo(afterObbStruct.st_dev);
+ }
+
private void createDeleteCreate(File create, File delete) throws Exception {
try {
assertThat(create.createNewFile()).isTrue();
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
index 1d4981b..6d9454f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
@@ -144,7 +144,7 @@
*/
public static void runPoc(String pocName, ITestDevice device, int timeout,
String arguments, IShellOutputReceiver receiver) throws Exception {
- device.executeShellCommand("chmod +x " + TMP_PATH + pocName);
+ assertPocExecutable(pocName, device);
if (receiver == null) {
receiver = new NullOutputReceiver();
}
@@ -156,6 +156,22 @@
}
/**
+ * Assert the poc is executable
+ * @param pocName name of the poc binary
+ * @param device device to be ran on
+ */
+ private static void assertPocExecutable(String pocName, ITestDevice device) throws Exception {
+ String fullPocPath = TMP_PATH + pocName;
+ device.executeShellCommand("chmod 777 " + fullPocPath);
+ assertEquals("'" + pocName + "' must exist and be readable.", 0,
+ runCommandGetExitCode("test -r " + fullPocPath, device));
+ assertEquals("'" + pocName + "'poc must exist and be writable.", 0,
+ runCommandGetExitCode("test -w " + fullPocPath, device));
+ assertEquals("'" + pocName + "'poc must exist and be executable.", 0,
+ runCommandGetExitCode("test -x " + fullPocPath, device));
+ }
+
+ /**
* Enables malloc debug on a given process.
*
* @param processName the name of the process to run with libc malloc debug
@@ -340,7 +356,7 @@
*/
public static int runPocGetExitStatus(String pocName, String arguments, ITestDevice device,
int timeout) throws Exception {
- device.executeShellCommand("chmod +x " + TMP_PATH + pocName);
+ assertPocExecutable(pocName, device);
CollectingOutputReceiver receiver = new CollectingOutputReceiver();
String cmd = TMP_PATH + pocName + " " + arguments + " > /dev/null 2>&1; echo $?";
long time = System.currentTimeMillis();
@@ -391,7 +407,7 @@
String targetPath = TMP_PATH + pacName;
AdbUtils.pushResource("/" + pacName, targetPath, device);
runPocAssertNoCrashes(
- TMP_PATH + "pacrunner", device, targetPath,
+ "pacrunner", device, targetPath,
new CrashUtils.Config().setProcessPatterns("pacrunner"));
runCommandLine("rm " + targetPath, device);
return 0; // b/157172329 fix tests that manually check the result; remove return statement
diff --git a/hostsidetests/stagedinstall/app/AndroidManifest.xml b/hostsidetests/stagedinstall/app/AndroidManifest.xml
index bc8bb0b..ebe83e6 100644
--- a/hostsidetests/stagedinstall/app/AndroidManifest.xml
+++ b/hostsidetests/stagedinstall/app/AndroidManifest.xml
@@ -17,7 +17,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tests.stagedinstall" >
- <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+ <queries>
+ <package android:name="com.android.cts.ctsshim" />
+ </queries>
+
<application>
<receiver android:name="com.android.cts.install.lib.LocalIntentSender"
android:exported="true" />
diff --git a/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java b/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java
index 1ce2daf..a7922db 100644
--- a/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java
+++ b/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java
@@ -969,6 +969,47 @@
assertThat(getInstalledVersion(TestApp.B)).isEqualTo(-1);
}
+ // Failure reason of staged install should be be persisted for single sessions
+ @Test
+ public void testFailureReasonPersists_SingleSession_Commit() throws Exception {
+ int sessionId = Install.single(TestApp.A1).setStaged().commit();
+ // Install TestApp.A2 so that after reboot TestApp.A1 fails to install as it is downgrade
+ Install.single(TestApp.A2).commit();
+ assertThat(getInstalledVersion(TestApp.A)).isEqualTo(2);
+ storeSessionId(sessionId);
+ }
+
+ @Test
+ public void testFailureReasonPersists_SingleSession_VerifyPostReboot() throws Exception {
+ int sessionId = retrieveLastSessionId();
+ assertSessionFailedWithMessage(sessionId, "Failed to install sessionId: " + sessionId);
+ assertThat(getInstalledVersion(TestApp.A)).isEqualTo(2);
+ }
+
+ // If apk installation fails in one staged session, then all staged session should fail.
+ @Test
+ public void testFailureReasonPersists_MultipleSession_Commit() throws Exception {
+ int firstSessionId = Install.single(TestApp.A1).setStaged().commit();
+ int secondSessionId = Install.single(TestApp.B1).setStaged().commit();
+ // Install TestApp.A2 so that after reboot TestApp.A1 fails to install as it is downgrade
+ Install.single(TestApp.A2).commit();
+ assertThat(getInstalledVersion(TestApp.A)).isEqualTo(2);
+ assertThat(getInstalledVersion(TestApp.B)).isEqualTo(-1);
+ storeSessionIds(Arrays.asList(firstSessionId, secondSessionId));
+ }
+
+ @Test
+ public void testFailureReasonPersists_MultipleSession_VerifyPostReboot() throws Exception {
+ List<Integer> sessionIds = retrieveLastSessionIds();
+ int failingSessionId = sessionIds.get(0);
+ for (int sessionId: sessionIds) {
+ assertSessionFailedWithMessage(sessionId, "Failed to install sessionId: "
+ + failingSessionId);
+ }
+ assertThat(getInstalledVersion(TestApp.A)).isEqualTo(2);
+ assertThat(getInstalledVersion(TestApp.B)).isEqualTo(-1);
+ }
+
@Test
public void testSamegradeSystemApex_Commit() throws Exception {
final PackageInfo shim = InstrumentationRegistry.getInstrumentation().getContext()
@@ -1206,6 +1247,13 @@
(session) -> assertThat(session).isStagedSessionFailed());
}
+ private static void assertSessionFailedWithMessage(int sessionId, String msg) {
+ assertSessionState(sessionId, (session) -> {
+ assertThat(session).isStagedSessionFailed();
+ assertThat(session.getStagedSessionErrorMessage()).contains(msg);
+ });
+ }
+
private static void assertSessionState(
int sessionId, Consumer<PackageInstaller.SessionInfo> assertion) {
PackageInstaller packageInstaller = getPackageInstaller();
diff --git a/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java b/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
index 06bbed8..54d735c 100644
--- a/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
+++ b/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
@@ -520,6 +520,25 @@
runPhase("testInstallMultipleStagedSession_PartialFail_ApkOnly_VerifyPostReboot");
}
+ // Failure reason of staged install should be be persisted for single sessions
+ @Test
+ @LargeTest
+ public void testFailureReasonPersists_SingleSession() throws Exception {
+ runPhase("testFailureReasonPersists_SingleSession_Commit");
+ getDevice().reboot();
+ runPhase("testFailureReasonPersists_SingleSession_VerifyPostReboot");
+ }
+
+ // Failure reason of staged install should be be persisted for multi session staged install
+ @Test
+ @LargeTest
+ public void testFailureReasonPersists_MultiSession() throws Exception {
+ assumeTrue(isCheckpointSupported());
+ runPhase("testFailureReasonPersists_MultipleSession_Commit");
+ getDevice().reboot();
+ runPhase("testFailureReasonPersists_MultipleSession_VerifyPostReboot");
+ }
+
@Test
@LargeTest
public void testSamegradeSystemApex() throws Exception {
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index d02dcfd..1fde1b6 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -326,13 +326,15 @@
getDevice().executeShellCommand(
"device_config put app_compat hidden_api_access_statslog_sampling_rate 65536");
+
+ Thread.sleep(WAIT_TIME_SHORT);
+
try {
final int atomTag = Atom.HIDDEN_API_USED_FIELD_NUMBER;
createAndUploadConfig(atomTag, false);
- runActivity("HiddenApiUsedActivity", null, null);
-
+ runActivity("HiddenApiUsedActivity", null, null, 2_500);
List<EventMetricData> data = getEventMetricDataList();
assertThat(data).hasSize(1);
diff --git a/hostsidetests/tagging/src/com/android/cts/tagging/TaggingDefaultTest.java b/hostsidetests/tagging/src/com/android/cts/tagging/TaggingDefaultTest.java
index 6e99c4e..266c60b 100644
--- a/hostsidetests/tagging/src/com/android/cts/tagging/TaggingDefaultTest.java
+++ b/hostsidetests/tagging/src/com/android/cts/tagging/TaggingDefaultTest.java
@@ -31,6 +31,11 @@
installPackage(TEST_APK, true);
}
+ @Override
+ protected void tearDown() throws Exception {
+ uninstallPackage(TEST_PKG, true);
+ }
+
public void testCompatFeatureEnabled() throws Exception {
if (supportsTaggedPointers) {
runDeviceCompatTest(TEST_PKG, ".TaggingTest", "testHeapTaggingEnabled",
diff --git a/hostsidetests/tagging/src/com/android/cts/tagging/TaggingDisabledTest.java b/hostsidetests/tagging/src/com/android/cts/tagging/TaggingDisabledTest.java
index 50d6df3..fcbd905 100644
--- a/hostsidetests/tagging/src/com/android/cts/tagging/TaggingDisabledTest.java
+++ b/hostsidetests/tagging/src/com/android/cts/tagging/TaggingDisabledTest.java
@@ -31,6 +31,11 @@
installPackage(TEST_APK, true);
}
+ @Override
+ protected void tearDown() throws Exception {
+ uninstallPackage(TEST_PKG, true);
+ }
+
public void testCompatFeatureEnabled() throws Exception {
// Checking for supportsTaggedPointers is unnecessary here, as we don't
// validate against reportDisabledChanges.
diff --git a/hostsidetests/tagging/src/com/android/cts/tagging/TaggingEnabledTest.java b/hostsidetests/tagging/src/com/android/cts/tagging/TaggingEnabledTest.java
index 6b31626..a578e50 100644
--- a/hostsidetests/tagging/src/com/android/cts/tagging/TaggingEnabledTest.java
+++ b/hostsidetests/tagging/src/com/android/cts/tagging/TaggingEnabledTest.java
@@ -31,6 +31,11 @@
installPackage(TEST_APK, true);
}
+ @Override
+ protected void tearDown() throws Exception {
+ uninstallPackage(TEST_PKG, true);
+ }
+
public void testCompatFeatureEnabled() throws Exception {
if (!supportsTaggedPointers) {
return;
diff --git a/hostsidetests/utils/Android.bp b/hostsidetests/utils/Android.bp
new file mode 100644
index 0000000..0930f91
--- /dev/null
+++ b/hostsidetests/utils/Android.bp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+java_library_host {
+ name: "cts-host-utils",
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.kt",
+ ],
+ libs: [
+ "cts-tradefed",
+ "tradefed",
+ ],
+}
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4ClassRunnerWithParameters.java b/hostsidetests/utils/src/android/cts/host/utils/DeviceJUnit4ClassRunnerWithParameters.java
similarity index 97%
rename from hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4ClassRunnerWithParameters.java
rename to hostsidetests/utils/src/android/cts/host/utils/DeviceJUnit4ClassRunnerWithParameters.java
index 944e258..7f8e07e 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4ClassRunnerWithParameters.java
+++ b/hostsidetests/utils/src/android/cts/host/utils/DeviceJUnit4ClassRunnerWithParameters.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.media.cts.bitstreams;
+package android.cts.host.utils;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.Option;
diff --git a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4Parameterized.java b/hostsidetests/utils/src/android/cts/host/utils/DeviceJUnit4Parameterized.java
similarity index 97%
rename from hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4Parameterized.java
rename to hostsidetests/utils/src/android/cts/host/utils/DeviceJUnit4Parameterized.java
index ea7ce7f..114678d 100644
--- a/hostsidetests/media/bitstreams/src/android/media/cts/bitstreams/DeviceJUnit4Parameterized.java
+++ b/hostsidetests/utils/src/android/cts/host/utils/DeviceJUnit4Parameterized.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.media.cts.bitstreams;
+package android.cts.host.utils;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.ConfigurationException;
diff --git a/libs/install/testapp/ACrashingV2.xml b/libs/install/testapp/ACrashingV2.xml
index 338a5b9..0ec90cf 100644
--- a/libs/install/testapp/ACrashingV2.xml
+++ b/libs/install/testapp/ACrashingV2.xml
@@ -22,7 +22,7 @@
<uses-sdk android:minSdkVersion="19" />
- <application android:label="Test App A v2">
+ <application android:label="Test App A v2" android:forceQueryable="true">
<receiver android:name="com.android.cts.install.lib.testapp.ProcessUserData"
android:exported="true" />
<activity android:name="com.android.cts.install.lib.testapp.CrashingMainActivity">
diff --git a/libs/install/testapp/Av1.xml b/libs/install/testapp/Av1.xml
index e9714fc..5b47699 100644
--- a/libs/install/testapp/Av1.xml
+++ b/libs/install/testapp/Av1.xml
@@ -22,7 +22,7 @@
<uses-sdk android:minSdkVersion="19" />
- <application android:label="Test App A1">
+ <application android:label="Test App A1" android:forceQueryable="true">
<receiver android:name="com.android.cts.install.lib.testapp.ProcessUserData"
android:exported="true" />
<activity android:name="com.android.cts.install.lib.testapp.MainActivity">
diff --git a/libs/install/testapp/Av2.xml b/libs/install/testapp/Av2.xml
index fd8afa0..9f2c21a 100644
--- a/libs/install/testapp/Av2.xml
+++ b/libs/install/testapp/Av2.xml
@@ -22,7 +22,7 @@
<uses-sdk android:minSdkVersion="19" />
- <application android:label="Test App A2">
+ <application android:label="Test App A2" android:forceQueryable="true">
<receiver android:name="com.android.cts.install.lib.testapp.ProcessUserData"
android:exported="true" />
<activity android:name="com.android.cts.install.lib.testapp.MainActivity">
diff --git a/libs/install/testapp/Av3.xml b/libs/install/testapp/Av3.xml
index a7839e3..d86aebd 100644
--- a/libs/install/testapp/Av3.xml
+++ b/libs/install/testapp/Av3.xml
@@ -22,7 +22,7 @@
<uses-sdk android:minSdkVersion="19" />
- <application android:label="Test App A3">
+ <application android:label="Test App A3" android:forceQueryable="true">
<receiver android:name="com.android.cts.install.lib.testapp.ProcessUserData"
android:exported="true" />
<activity android:name="com.android.cts.install.lib.testapp.MainActivity">
diff --git a/libs/install/testapp/Bv1.xml b/libs/install/testapp/Bv1.xml
index 403e7e2..f990713 100644
--- a/libs/install/testapp/Bv1.xml
+++ b/libs/install/testapp/Bv1.xml
@@ -22,7 +22,7 @@
<uses-sdk android:minSdkVersion="19" />
- <application android:label="Test App B1">
+ <application android:label="Test App B1" android:forceQueryable="true">
<receiver android:name="com.android.cts.install.lib.testapp.ProcessUserData"
android:exported="true" />
<activity android:name="com.android.cts.install.lib.testapp.MainActivity">
diff --git a/libs/install/testapp/Bv2.xml b/libs/install/testapp/Bv2.xml
index f030c3f..3bd7292 100644
--- a/libs/install/testapp/Bv2.xml
+++ b/libs/install/testapp/Bv2.xml
@@ -22,7 +22,7 @@
<uses-sdk android:minSdkVersion="19" />
- <application android:label="Test App B2">
+ <application android:label="Test App B2" android:forceQueryable="true">
<receiver android:name="com.android.cts.install.lib.testapp.ProcessUserData"
android:exported="true" />
<activity android:name="com.android.cts.install.lib.testapp.MainActivity">
diff --git a/libs/install/testapp/Cv1.xml b/libs/install/testapp/Cv1.xml
index edb69f9..32f6989 100644
--- a/libs/install/testapp/Cv1.xml
+++ b/libs/install/testapp/Cv1.xml
@@ -23,7 +23,7 @@
<uses-sdk android:minSdkVersion="19" />
- <application android:label="Test App C1">
+ <application android:label="Test App C1" android:forceQueryable="true">
<receiver android:name="com.android.cts.install.lib.testapp.ProcessUserData"
android:exported="true" />
<activity android:name="com.android.cts.install.lib.testapp.MainActivity">
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index 255001a..6091924 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -2860,6 +2860,7 @@
}
@Test
+ @AppModeFull(reason = "WRITE_SECURE_SETTING permission can't be grant to instant apps")
public void testSwitchInputMethod_noNewFillRequest() throws Exception {
// Set service
enableService();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedLoginActivityTest.java
index 47664de..75c1042 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedLoginActivityTest.java
@@ -34,6 +34,7 @@
import android.autofillservice.cts.augmented.CannedAugmentedFillResponse;
import android.autofillservice.cts.augmented.CtsAugmentedAutofillService;
import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.AugmentedFillRequest;
+import android.platform.test.annotations.AppModeFull;
import android.service.autofill.FillEventHistory;
import android.service.autofill.FillEventHistory.Event;
import android.view.autofill.AutofillId;
@@ -284,6 +285,7 @@
}
@Test
+ @AppModeFull(reason = "WRITE_SECURE_SETTING permission can't be grant to instant apps")
public void testSwitchInputMethod() throws Exception {
// Set services
enableService();
@@ -333,6 +335,7 @@
}
@Test
+ @AppModeFull(reason = "WRITE_SECURE_SETTING permission can't be grant to instant apps")
public void testSwitchInputMethod_mainServiceDisabled() throws Exception {
// Set services
Helper.disableAutofillService(sContext);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
index cc0d074..74a7d3a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
@@ -40,6 +40,7 @@
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
+import android.platform.test.annotations.AppModeFull;
import android.service.autofill.FillContext;
import android.support.test.uiautomator.Direction;
@@ -305,6 +306,7 @@
}
@Test
+ @AppModeFull(reason = "WRITE_SECURE_SETTING permission can't be grant to instant apps")
public void testSwitchInputMethod() throws Exception {
// Set service
enableService();
diff --git a/tests/framework/base/windowmanager/AndroidManifest.xml b/tests/framework/base/windowmanager/AndroidManifest.xml
index fe642c3..5f60ea4 100644
--- a/tests/framework/base/windowmanager/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/AndroidManifest.xml
@@ -307,6 +307,8 @@
<activity android:name="android.server.wm.CloseOnOutsideTestActivity" />
<activity android:name="android.server.wm.DialogFrameTestActivity" />
<activity android:name="android.server.wm.DisplayCutoutTests$TestActivity"
+ android:configChanges="orientation|screenSize"
+ android:screenOrientation="nosensor"
android:turnScreenOn="true"
android:showWhenLocked="true"/>
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
index f1423f0..d3b5621 100644
--- a/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
@@ -299,6 +299,7 @@
/** Extra key constants for {@link android.server.wm.app.LandscapeOrientationActivity}. */
public static class LandscapeOrientationActivity {
+ public static final String EXTRA_APP_CONFIG_INFO = "app_config_info";
public static final String EXTRA_CONFIG_INFO_IN_ON_CREATE = "config_info_in_on_create";
public static final String EXTRA_DISPLAY_REAL_SIZE = "display_real_size";
}
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/LandscapeOrientationActivity.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/LandscapeOrientationActivity.java
index 00984fa..dd1ad87 100644
--- a/tests/framework/base/windowmanager/app/src/android/server/wm/app/LandscapeOrientationActivity.java
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/LandscapeOrientationActivity.java
@@ -16,11 +16,14 @@
package android.server.wm.app;
+import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_APP_CONFIG_INFO;
import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_CONFIG_INFO_IN_ON_CREATE;
import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_DISPLAY_REAL_SIZE;
+import android.app.Application;
import android.content.res.Configuration;
import android.graphics.Point;
+import android.hardware.display.DisplayManager;
import android.os.Bundle;
import android.server.wm.CommandSession.ConfigInfo;
import android.view.Display;
@@ -40,6 +43,13 @@
display.getRealSize(size);
extras.putParcelable(EXTRA_CONFIG_INFO_IN_ON_CREATE, new ConfigInfo(this, display));
extras.putParcelable(EXTRA_DISPLAY_REAL_SIZE, size);
+
+ final Application app = getApplication();
+ extras.putParcelable(EXTRA_APP_CONFIG_INFO, new ConfigInfo(app,
+ // The display object is associated with application resources that it has its
+ // own display adjustments.
+ app.getSystemService(DisplayManager.class)
+ .getDisplay(Display.DEFAULT_DISPLAY)));
client.putExtras(extras);
});
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
index c898ef6..e005059 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
@@ -37,6 +37,7 @@
import static android.server.wm.app.Components.PORTRAIT_ORIENTATION_ACTIVITY;
import static android.server.wm.app.Components.RESIZEABLE_ACTIVITY;
import static android.server.wm.app.Components.TEST_ACTIVITY;
+import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_APP_CONFIG_INFO;
import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_CONFIG_INFO_IN_ON_CREATE;
import static android.server.wm.app.Components.LandscapeOrientationActivity.EXTRA_DISPLAY_REAL_SIZE;
import static android.server.wm.translucentapp26.Components.SDK26_TRANSLUCENT_LANDSCAPE_ACTIVITY;
@@ -467,6 +468,7 @@
final SizeInfo reportedSizes = getActivityDisplaySize(LANDSCAPE_ORIENTATION_ACTIVITY);
final Bundle extras = TestJournalContainer.get(LANDSCAPE_ORIENTATION_ACTIVITY).extras;
+ final ConfigInfo appConfigInfo = extras.getParcelable(EXTRA_APP_CONFIG_INFO);
final Point onCreateRealDisplaySize = extras.getParcelable(EXTRA_DISPLAY_REAL_SIZE);
final ConfigInfo onCreateConfigInfo = extras.getParcelable(EXTRA_CONFIG_INFO_IN_ON_CREATE);
final SizeInfo onCreateSize = onCreateConfigInfo.sizeInfo;
@@ -478,13 +480,19 @@
final Point expectedRealDisplaySize = new Point();
display.getRealSize(expectedRealDisplaySize);
+ final int expectedRotation = display.getRotation();
assertEquals("The activity should get the final display rotation in onCreate",
- display.getRotation(), onCreateConfigInfo.rotation);
+ expectedRotation, onCreateConfigInfo.rotation);
+ assertEquals("The application should get the final display rotation in onCreate",
+ expectedRotation, appConfigInfo.rotation);
assertEquals("The activity should get the final display size in onCreate",
expectedRealDisplaySize, onCreateRealDisplaySize);
- assertEquals("The app size of activity should have the same orientation",
- expectedRealDisplaySize.x > expectedRealDisplaySize.y,
+
+ final boolean isLandscape = expectedRealDisplaySize.x > expectedRealDisplaySize.y;
+ assertEquals("The app size of activity should have the same orientation", isLandscape,
onCreateSize.displayWidth > onCreateSize.displayHeight);
+ assertEquals("The application should get the same orientation", isLandscape,
+ appConfigInfo.sizeInfo.displayWidth > appConfigInfo.sizeInfo.displayHeight);
}
@Test
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java
index 142b8ac..e4dc868 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java
@@ -218,6 +218,8 @@
@Test
public void testSplitScreenBelowPip() throws Exception {
+ assumeTrue(supportsSplitScreenMultiWindow());
+
// TODO(b/149338177): Fix test to pass with organizer API.
mUseTaskOrganizer = false;
// Launch Pip-capable activity and enter Pip immediately
@@ -255,6 +257,8 @@
@Test
public void testPipAboveSplitScreen() throws Exception {
+ assumeTrue(supportsSplitScreenMultiWindow());
+
// TODO(b/149338177): Fix test to pass with organizer API.
mUseTaskOrganizer = false;
// Launch first activity
diff --git a/tests/location/location_gnss/src/android/location/cts/gnss/GnssLocationUpdateIntervalTest.java b/tests/location/location_gnss/src/android/location/cts/gnss/GnssLocationUpdateIntervalTest.java
index 0733c0d..a908057 100644
--- a/tests/location/location_gnss/src/android/location/cts/gnss/GnssLocationUpdateIntervalTest.java
+++ b/tests/location/location_gnss/src/android/location/cts/gnss/GnssLocationUpdateIntervalTest.java
@@ -43,6 +43,7 @@
private static final String TAG = "GnssLocationUpdateIntervalTest";
private static final int LOCATION_TO_COLLECT_COUNT = 8;
+ private static final int PASSIVE_LOCATION_TO_COLLECT_COUNT = 100;
private static final int TIMEOUT_IN_SEC = 120;
// Minimum time interval between fixes in milliseconds.
@@ -97,10 +98,9 @@
TestLocationListener activeLocationListener = new TestLocationListener(
LOCATION_TO_COLLECT_COUNT);
TestLocationListener passiveLocationListener = new TestLocationListener(
- LOCATION_TO_COLLECT_COUNT);
+ PASSIVE_LOCATION_TO_COLLECT_COUNT);
mTestLocationManager.requestLocationUpdates(activeLocationListener, fixIntervalMillis);
- mTestLocationManager.requestPassiveLocationUpdates(passiveLocationListener,
- fixIntervalMillis);
+ mTestLocationManager.requestPassiveLocationUpdates(passiveLocationListener, 0);
try {
boolean success = activeLocationListener.await(
(fixIntervalMillis * LOCATION_TO_COLLECT_COUNT) + TIMEOUT_IN_SEC);
diff --git a/tests/rollback/AndroidManifest.xml b/tests/rollback/AndroidManifest.xml
index ab1ec0f..3203f25 100644
--- a/tests/rollback/AndroidManifest.xml
+++ b/tests/rollback/AndroidManifest.xml
@@ -18,7 +18,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.rollback" >
- <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application>
<receiver android:name="com.android.cts.install.lib.LocalIntentSender"
android:exported="true" />
diff --git a/tests/sensor/src/android/hardware/cts/SensorSupportTest.java b/tests/sensor/src/android/hardware/cts/SensorSupportTest.java
index 6942094..2cab0c9 100644
--- a/tests/sensor/src/android/hardware/cts/SensorSupportTest.java
+++ b/tests/sensor/src/android/hardware/cts/SensorSupportTest.java
@@ -51,15 +51,13 @@
@Override
public void setUp() {
PackageManager pm = getContext().getPackageManager();
- // Tests will only run if either HIFI_SENSORS or VR high performance mode is supported.
+ // Some tests will only run if either HIFI_SENSORS or VR high performance mode is supported.
mAreHifiSensorsSupported = pm.hasSystemFeature(PackageManager.FEATURE_HIFI_SENSORS);
mVrHighPerformanceModeSupported = pm.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE);
mIsVrHeadset = (getContext().getResources().getConfiguration().uiMode
& Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_VR_HEADSET;
- if (mAreHifiSensorsSupported || mVrHighPerformanceModeSupported) {
- mSensorManager =
- (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
- }
+ mSensorManager =
+ (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
mHasAccel = hasSensorType(Sensor.TYPE_ACCELEROMETER);
mHasGyro = hasSensorType(Sensor.TYPE_GYROSCOPE);
@@ -171,6 +169,6 @@
}
private boolean hasSensorType(int sensorType) {
- return (mSensorManager.getDefaultSensor(sensorType) != null);
+ return (mSensorManager != null && mSensorManager.getDefaultSensor(sensorType) != null);
}
}
diff --git a/tests/signature/api-check/android-test-base-28-api/Android.bp b/tests/signature/api-check/android-test-base-28-api/Android.bp
index 2b24bc1..31263b4 100644
--- a/tests/signature/api-check/android-test-base-28-api/Android.bp
+++ b/tests/signature/api-check/android-test-base-28-api/Android.bp
@@ -18,7 +18,7 @@
"signature-api-check-defaults",
],
java_resources: [
- ":cts-android-test-base-current-txt",
+ ":cts-android-test-base-current-api-gz",
],
min_sdk_version: "27",
diff --git a/tests/signature/api-check/android-test-base-28-api/AndroidTest.xml b/tests/signature/api-check/android-test-base-28-api/AndroidTest.xml
index ef43237..e048dc3 100644
--- a/tests/signature/api-check/android-test-base-28-api/AndroidTest.xml
+++ b/tests/signature/api-check/android-test-base-28-api/AndroidTest.xml
@@ -27,7 +27,7 @@
<option name="package" value="android.signature.cts.api.android_test_base_28" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.api28.test.SignatureTest" />
- <option name="instrumentation-arg" key="expected-api-files" value="android-test-base-current.txt" />
+ <option name="instrumentation-arg" key="expected-api-files" value="android-test-base-current.api.gz" />
<option name="runtime-hint" value="5s" />
</test>
</configuration>
diff --git a/tests/signature/api-check/android-test-base-current-api/Android.bp b/tests/signature/api-check/android-test-base-current-api/Android.bp
index ead699b..8ef01a1 100644
--- a/tests/signature/api-check/android-test-base-current-api/Android.bp
+++ b/tests/signature/api-check/android-test-base-current-api/Android.bp
@@ -18,7 +18,7 @@
"signature-api-check-defaults",
],
java_resources: [
- ":cts-android-test-base-current-txt",
+ ":cts-android-test-base-current-api-gz",
],
use_embedded_native_libs: false,
diff --git a/tests/signature/api-check/android-test-base-current-api/AndroidTest.xml b/tests/signature/api-check/android-test-base-current-api/AndroidTest.xml
index bbf942e..30da659 100644
--- a/tests/signature/api-check/android-test-base-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/android-test-base-current-api/AndroidTest.xml
@@ -27,7 +27,7 @@
<option name="package" value="android.signature.cts.api.android_test_base_current" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.current.test.SignatureTest" />
- <option name="instrumentation-arg" key="expected-api-files" value="android-test-base-current.txt" />
+ <option name="instrumentation-arg" key="expected-api-files" value="android-test-base-current.api.gz" />
<option name="runtime-hint" value="5s" />
</test>
</configuration>
diff --git a/tests/signature/api-check/android-test-mock-current-api/Android.bp b/tests/signature/api-check/android-test-mock-current-api/Android.bp
index 9f3ccbf..44c7a8a 100644
--- a/tests/signature/api-check/android-test-mock-current-api/Android.bp
+++ b/tests/signature/api-check/android-test-mock-current-api/Android.bp
@@ -18,7 +18,7 @@
"signature-api-check-defaults",
],
java_resources: [
- ":cts-android-test-mock-current-txt",
+ ":cts-android-test-mock-current-api-gz",
],
use_embedded_native_libs: false,
diff --git a/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml b/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml
index 19dbe7b..f8ab351 100644
--- a/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml
@@ -27,7 +27,7 @@
<option name="package" value="android.signature.cts.api.android_test_mock_current" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.current.mock.SignatureTest" />
- <option name="instrumentation-arg" key="expected-api-files" value="android-test-mock-current.txt" />
+ <option name="instrumentation-arg" key="expected-api-files" value="android-test-mock-current.api.gz" />
<option name="runtime-hint" value="5s" />
</test>
</configuration>
diff --git a/tests/signature/api-check/android-test-runner-current-api/Android.bp b/tests/signature/api-check/android-test-runner-current-api/Android.bp
index 84ba5e9..80d2803 100644
--- a/tests/signature/api-check/android-test-runner-current-api/Android.bp
+++ b/tests/signature/api-check/android-test-runner-current-api/Android.bp
@@ -18,9 +18,9 @@
"signature-api-check-defaults",
],
java_resources: [
- ":cts-android-test-base-current-txt",
- ":cts-android-test-mock-current-txt",
- ":cts-android-test-runner-current-txt",
+ ":cts-android-test-base-current-api-gz",
+ ":cts-android-test-mock-current-api-gz",
+ ":cts-android-test-runner-current-api-gz",
],
use_embedded_native_libs: false,
diff --git a/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml b/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml
index 1c6ed19..5c18209 100644
--- a/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml
@@ -27,7 +27,7 @@
<option name="package" value="android.signature.cts.api.android_test_runner_current" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.current.runner.SignatureTest" />
- <option name="instrumentation-arg" key="expected-api-files" value="android-test-base-current.txt,android-test-mock-current.txt,android-test-runner-current.txt" />
+ <option name="instrumentation-arg" key="expected-api-files" value="android-test-base-current.api.gz,android-test-mock-current.api.gz,android-test-runner-current.api.gz" />
<option name="runtime-hint" value="5s" />
</test>
</configuration>
diff --git a/tests/signature/api-check/apache-http-legacy-27-api/Android.bp b/tests/signature/api-check/apache-http-legacy-27-api/Android.bp
index 13e99d0..d649145 100644
--- a/tests/signature/api-check/apache-http-legacy-27-api/Android.bp
+++ b/tests/signature/api-check/apache-http-legacy-27-api/Android.bp
@@ -18,8 +18,8 @@
"signature-api-check-defaults",
],
java_resources: [
- ":cts-current-txt",
- ":cts-apache-http-legacy-current-txt",
+ ":cts-current-api-gz",
+ ":cts-apache-http-legacy-current-api-gz",
],
min_sdk_version: "27",
diff --git a/tests/signature/api-check/apache-http-legacy-27-api/AndroidTest.xml b/tests/signature/api-check/apache-http-legacy-27-api/AndroidTest.xml
index f308253..ff5cff8 100644
--- a/tests/signature/api-check/apache-http-legacy-27-api/AndroidTest.xml
+++ b/tests/signature/api-check/apache-http-legacy-27-api/AndroidTest.xml
@@ -27,8 +27,8 @@
<option name="package" value="android.signature.cts.api.apache_http_legacy_27" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.api27.http.SignatureTest" />
- <option name="instrumentation-arg" key="base-api-files" value="current.txt" />
- <option name="instrumentation-arg" key="expected-api-files" value="apache-http-legacy-current.txt" />
+ <option name="instrumentation-arg" key="base-api-files" value="current.api.gz" />
+ <option name="instrumentation-arg" key="expected-api-files" value="apache-http-legacy-current.api.gz" />
<option name="runtime-hint" value="5s" />
</test>
</configuration>
diff --git a/tests/signature/api-check/apache-http-legacy-current-api/Android.bp b/tests/signature/api-check/apache-http-legacy-current-api/Android.bp
index bf778fc..ffda5cc 100644
--- a/tests/signature/api-check/apache-http-legacy-current-api/Android.bp
+++ b/tests/signature/api-check/apache-http-legacy-current-api/Android.bp
@@ -18,7 +18,7 @@
"signature-api-check-defaults",
],
java_resources: [
- ":cts-apache-http-legacy-current-txt",
+ ":cts-apache-http-legacy-current-api-gz",
],
use_embedded_native_libs: false,
diff --git a/tests/signature/api-check/apache-http-legacy-current-api/AndroidTest.xml b/tests/signature/api-check/apache-http-legacy-current-api/AndroidTest.xml
index 3fa2220..5b15e41 100644
--- a/tests/signature/api-check/apache-http-legacy-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/apache-http-legacy-current-api/AndroidTest.xml
@@ -27,7 +27,7 @@
<option name="package" value="android.signature.cts.api.apache_http_legacy_current" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.current.http.SignatureTest" />
- <option name="instrumentation-arg" key="unexpected-api-files" value="apache-http-legacy-current.txt" />
+ <option name="instrumentation-arg" key="unexpected-api-files" value="apache-http-legacy-current.api.gz" />
<option name="runtime-hint" value="5s" />
</test>
</configuration>
diff --git a/tests/signature/api-check/apache-http-legacy-uses-library-api/Android.bp b/tests/signature/api-check/apache-http-legacy-uses-library-api/Android.bp
index 5d7a473..f811f85 100644
--- a/tests/signature/api-check/apache-http-legacy-uses-library-api/Android.bp
+++ b/tests/signature/api-check/apache-http-legacy-uses-library-api/Android.bp
@@ -18,8 +18,8 @@
"signature-api-check-defaults",
],
java_resources: [
- ":cts-current-txt",
- ":cts-apache-http-legacy-current-txt",
+ ":cts-current-api-gz",
+ ":cts-apache-http-legacy-current-api-gz",
],
use_embedded_native_libs: false,
diff --git a/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidTest.xml b/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidTest.xml
index 0c75fa6..7216d25 100644
--- a/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidTest.xml
+++ b/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidTest.xml
@@ -27,8 +27,8 @@
<option name="package" value="android.signature.cts.api.apache_http_legacy_uses_library" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.http_uses_library.SignatureTest" />
- <option name="instrumentation-arg" key="base-api-files" value="current.txt" />
- <option name="instrumentation-arg" key="expected-api-files" value="apache-http-legacy-current.txt" />
+ <option name="instrumentation-arg" key="base-api-files" value="current.api.gz" />
+ <option name="instrumentation-arg" key="expected-api-files" value="apache-http-legacy-current.api.gz" />
<option name="runtime-hint" value="5s" />
</test>
</configuration>
diff --git a/tests/signature/api-check/current-api/Android.bp b/tests/signature/api-check/current-api/Android.bp
index 1e867d9..61656c3 100644
--- a/tests/signature/api-check/current-api/Android.bp
+++ b/tests/signature/api-check/current-api/Android.bp
@@ -18,10 +18,10 @@
"signature-api-check-defaults",
],
java_resources: [
- ":cts-current-txt",
- ":cts-android-test-base-current-txt",
- ":cts-android-test-mock-current-txt",
- ":cts-android-test-runner-current-txt",
+ ":cts-current-api-gz",
+ ":cts-android-test-base-current-api-gz",
+ ":cts-android-test-mock-current-api-gz",
+ ":cts-android-test-runner-current-api-gz",
],
use_embedded_native_libs: false,
diff --git a/tests/signature/api-check/current-api/AndroidTest.xml b/tests/signature/api-check/current-api/AndroidTest.xml
index 421306f..f14a503 100644
--- a/tests/signature/api-check/current-api/AndroidTest.xml
+++ b/tests/signature/api-check/current-api/AndroidTest.xml
@@ -28,8 +28,8 @@
<option name="package" value="android.signature.cts.api.current" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.current.SignatureTest" />
- <option name="instrumentation-arg" key="expected-api-files" value="current.txt" />
- <option name="instrumentation-arg" key="unexpected-api-files" value="android-test-base-current.txt,android-test-mock-current.txt,android-test-runner-current.txt" />
+ <option name="instrumentation-arg" key="expected-api-files" value="current.api.gz" />
+ <option name="instrumentation-arg" key="unexpected-api-files" value="android-test-base-current.api.gz,android-test-mock-current.api.gz,android-test-runner-current.api.gz" />
<option name="runtime-hint" value="30s" />
</test>
</configuration>
diff --git a/tests/signature/api-check/shared-libs-api/Android.mk b/tests/signature/api-check/shared-libs-api/Android.mk
index d921e6b..92c66d1 100644
--- a/tests/signature/api-check/shared-libs-api/Android.mk
+++ b/tests/signature/api-check/shared-libs-api/Android.mk
@@ -22,13 +22,13 @@
$(foreach api_level,public system,\
$(foreach lib,$(filter-out android,$(filter-out %removed,$(filter-out incompatibilities,\
$(basename $(notdir $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/$(ver)/$(api_level)/api/*.txt)))))),\
- $(eval all_shared_libs_modules += $(lib)-$(ver)-$(api_level).txt))))
+ $(eval all_shared_libs_modules += $(lib)-$(ver)-$(api_level).api))))
all_shared_libs_files := $(addprefix $(COMPATIBILITY_TESTCASES_OUT_cts)/,$(all_shared_libs_modules))
include $(CLEAR_VARS)
-LOCAL_MODULE := cts-shared-libs-all.txt
-LOCAL_MODULE_STEM := shared-libs-all.txt.zip
+LOCAL_MODULE := cts-shared-libs-all.api
+LOCAL_MODULE_STEM := shared-libs-all.api.zip
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH = $(TARGET_OUT_DATA_ETC)
include $(BUILD_SYSTEM)/base_rules.mk
diff --git a/tests/signature/api-check/shared-libs-api/AndroidTest.xml b/tests/signature/api-check/shared-libs-api/AndroidTest.xml
index d6cc7fc..a679079 100644
--- a/tests/signature/api-check/shared-libs-api/AndroidTest.xml
+++ b/tests/signature/api-check/shared-libs-api/AndroidTest.xml
@@ -27,7 +27,7 @@
<option name="package" value="android.signature.cts.api.shared_libs" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.SignatureMultiLibsTest" />
- <option name="instrumentation-arg" key="expected-api-files" value="shared-libs-all.txt.zip" />
+ <option name="instrumentation-arg" key="expected-api-files" value="shared-libs-all.api.zip" />
<option name="runtime-hint" value="30s" />
</test>
</configuration>
diff --git a/tests/signature/api-check/system-annotation/Android.bp b/tests/signature/api-check/system-annotation/Android.bp
index d328107..6b63792 100644
--- a/tests/signature/api-check/system-annotation/Android.bp
+++ b/tests/signature/api-check/system-annotation/Android.bp
@@ -21,10 +21,10 @@
"compatibility-device-util-axt",
],
java_resources: [
- ":cts-system-current-txt",
- ":cts-system-removed-txt",
- ":cts-car-system-current-txt",
- ":cts-car-system-removed-txt",
+ ":cts-system-current-api-gz",
+ ":cts-system-removed-api-gz",
+ ":cts-car-system-current-api-gz",
+ ":cts-car-system-removed-api-gz",
],
min_sdk_version: "27",
diff --git a/tests/signature/api-check/system-annotation/AndroidTest.xml b/tests/signature/api-check/system-annotation/AndroidTest.xml
index 816ff81..4a61a40 100644
--- a/tests/signature/api-check/system-annotation/AndroidTest.xml
+++ b/tests/signature/api-check/system-annotation/AndroidTest.xml
@@ -27,7 +27,7 @@
<option name="package" value="android.signature.cts.api.system_annotation" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.AnnotationTest" />
- <option name="instrumentation-arg" key="expected-api-files" value="system-current.txt,system-removed.txt,car-system-current.txt,car-system-removed.txt" />
+ <option name="instrumentation-arg" key="expected-api-files" value="system-current.api.gz,system-removed.api.gz,car-system-current.api.gz,car-system-removed.api.gz" />
<option name="instrumentation-arg" key="annotation-for-exact-match" value="@android.annotation.SystemApi\(client=PRIVILEGED_APPS\)" />
<option name="runtime-hint" value="30s" />
</test>
diff --git a/tests/signature/api-check/system-api/Android.mk b/tests/signature/api-check/system-api/Android.mk
index 2c577ca..b633daa 100644
--- a/tests/signature/api-check/system-api/Android.mk
+++ b/tests/signature/api-check/system-api/Android.mk
@@ -18,15 +18,15 @@
$(foreach ver,$(PLATFORM_SYSTEMSDK_VERSIONS),\
$(if $(call math_is_number,$(ver)),\
$(if $(wildcard prebuilts/sdk/$(ver)/system/api/android.txt),\
- $(eval all_system_api_modules += system-$(ver).txt)\
+ $(eval all_system_api_modules += system-$(ver).api)\
)\
)\
)
all_system_api_files := $(addprefix $(COMPATIBILITY_TESTCASES_OUT_cts)/,$(all_system_api_modules))
include $(CLEAR_VARS)
-LOCAL_MODULE := cts-system-all.txt
-LOCAL_MODULE_STEM := system-all.txt.zip
+LOCAL_MODULE := cts-system-all.api
+LOCAL_MODULE_STEM := system-all.api.zip
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH = $(TARGET_OUT_DATA_ETC)
LOCAL_COMPATIBILITY_SUITE := arcts cts vts10 general-tests
@@ -48,11 +48,11 @@
LOCAL_JAVA_RESOURCE_FILES := $(all_system_api_zip_file)
LOCAL_SIGNATURE_API_FILES := \
- current.txt \
- android-test-mock-current.txt \
- android-test-runner-current.txt \
- system-current.txt \
- system-removed.txt \
+ current.api.gz \
+ android-test-mock-current.api.gz \
+ android-test-runner-current.api.gz \
+ system-current.api.gz \
+ system-removed.api.gz \
include $(LOCAL_PATH)/../build_signature_apk.mk
diff --git a/tests/signature/api-check/system-api/AndroidTest.xml b/tests/signature/api-check/system-api/AndroidTest.xml
index 646338e..904dce1 100644
--- a/tests/signature/api-check/system-api/AndroidTest.xml
+++ b/tests/signature/api-check/system-api/AndroidTest.xml
@@ -27,9 +27,9 @@
<option name="package" value="android.signature.cts.api.system" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.system.SignatureTest" />
- <option name="instrumentation-arg" key="base-api-files" value="current.txt" />
- <option name="instrumentation-arg" key="expected-api-files" value="system-current.txt,system-removed.txt,system-all.txt.zip" />
- <option name="instrumentation-arg" key="unexpected-api-files" value="android-test-mock-current.txt,android-test-runner-current.txt" />
+ <option name="instrumentation-arg" key="base-api-files" value="current.api.gz" />
+ <option name="instrumentation-arg" key="expected-api-files" value="system-current.api.gz,system-removed.api.gz,system-all.api.zip" />
+ <option name="instrumentation-arg" key="unexpected-api-files" value="android-test-mock-current.api.gz,android-test-runner-current.api.gz" />
<option name="runtime-hint" value="30s" />
</test>
</configuration>
diff --git a/tests/signature/api/Android.bp b/tests/signature/api/Android.bp
index 8c3e12a..424c881 100644
--- a/tests/signature/api/Android.bp
+++ b/tests/signature/api/Android.bp
@@ -12,115 +12,111 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-default_visibility = [
- "//cts/tests/signature/api-check:__subpackages__",
- "//cts/tests/signature/intent-check",
-]
+genrule_defaults {
+ name: "signature-cts-api-api-gz",
+ cmd: "$(location metalava) --no-banner -convert2xmlnostrip $(in) $(genDir)/api.xml && gzip -c $(genDir)/api.xml > $(out)",
+ tools: ["metalava"],
+ visibility: [
+ "//cts/tests/signature/api-check:__subpackages__",
+ "//cts/tests/signature/intent-check",
+ ],
+}
genrule {
- name: "cts-current-txt",
- visibility: default_visibility,
+ name: "cts-current-api-gz",
+ defaults: ["signature-cts-api-api-gz"],
srcs: [
":frameworks-base-api-current.txt",
],
out: [
- "current.txt",
+ "current.api.gz",
],
- cmd: "cp $(in) $(out)",
}
genrule {
- name: "cts-system-current-txt",
- visibility: default_visibility,
+ name: "cts-system-current-api-gz",
+ defaults: ["signature-cts-api-api-gz"],
srcs: [
":frameworks-base-api-system-current.txt",
],
out: [
- "system-current.txt",
+ "system-current.api.gz",
],
- cmd: "cp $(in) $(out)",
}
genrule {
- name: "cts-system-removed-txt",
- visibility: default_visibility,
+ name: "cts-system-removed-api-gz",
+ defaults: ["signature-cts-api-api-gz"],
srcs: [
":frameworks-base-api-system-removed.txt",
],
out: [
- "system-removed.txt",
+ "system-removed.api.gz",
],
- cmd: "cp $(in) $(out)",
}
genrule {
- name: "cts-android-test-base-current-txt",
- visibility: default_visibility,
+ name: "cts-android-test-base-current-api-gz",
+ defaults: ["signature-cts-api-api-gz"],
srcs: [
":android-test-base-current.txt",
],
out: [
- "android-test-base-current.txt",
+ "android-test-base-current.api.gz",
],
- cmd: "cp $(in) $(out)",
}
genrule {
- name: "cts-android-test-mock-current-txt",
- visibility: default_visibility,
+ name: "cts-android-test-mock-current-api-gz",
+ defaults: ["signature-cts-api-api-gz"],
srcs: [
":android-test-mock-current.txt",
],
out: [
- "android-test-mock-current.txt",
+ "android-test-mock-current.api.gz",
],
- cmd: "cp $(in) $(out)",
}
genrule {
- name: "cts-android-test-runner-current-txt",
- visibility: default_visibility,
+ name: "cts-android-test-runner-current-api-gz",
+ defaults: ["signature-cts-api-api-gz"],
srcs: [
":android-test-runner-current.txt",
],
out: [
- "android-test-runner-current.txt",
+ "android-test-runner-current.api.gz",
],
- cmd: "cp $(in) $(out)",
}
genrule {
- name: "cts-apache-http-legacy-current-txt",
- visibility: default_visibility,
+ name: "cts-apache-http-legacy-current-api-gz",
+ defaults: ["signature-cts-api-api-gz"],
srcs: [
":apache-http-legacy-current.txt",
],
out: [
- "apache-http-legacy-current.txt",
+ "apache-http-legacy-current.api.gz",
],
- cmd: "cp $(in) $(out)",
}
genrule {
- name: "cts-car-system-current-txt",
- visibility: default_visibility,
+ name: "cts-car-system-current-api-gz",
+ defaults: ["signature-cts-api-api-gz"],
srcs: [
":car-api-system-current.txt",
],
out: [
- "car-system-current.txt",
+ "car-system-current.api.gz",
],
- cmd: "cp $(in) $(out)",
}
genrule {
- name: "cts-car-system-removed-txt",
- visibility: default_visibility,
+ name: "cts-car-system-removed-api-gz",
+ defaults: ["signature-cts-api-api-gz"],
srcs: [
":car-api-system-removed.txt",
],
out: [
- "car-system-removed.txt",
+ "car-system-removed.api.gz",
],
- cmd: "cp $(in) $(out)",
}
diff --git a/tests/signature/api/Android.mk b/tests/signature/api/Android.mk
index e832b8f..d736c71 100644
--- a/tests/signature/api/Android.mk
+++ b/tests/signature/api/Android.mk
@@ -16,24 +16,25 @@
LOCAL_PATH := $(call my-dir)
-# $(1) name of the txt file to be created
+# $(1) name of the xml file to be created
# $(2) path to the api text file
-define copy_api_txt_file
+define build_xml_api_file
include $(CLEAR_VARS)
LOCAL_MODULE := cts-$(subst .,-,$(1))
LOCAL_MODULE_STEM := $(1)
LOCAL_MODULE_CLASS := ETC
-LOCAL_COMPATIBILITY_SUITE := arcts cts vts10 general-tests
+LOCAL_COMPATIBILITY_SUITE := arcts cts vts general-tests
include $(BUILD_SYSTEM)/base_rules.mk
$$(LOCAL_BUILT_MODULE): $(2) | $(APICHECK)
- @echo "Copying API file $$< -> $$@"
- $$(copy-file-to-target)
+ @echo "Convert API file $$< -> $$@"
+ @mkdir -p $$(dir $$@)
+ $(hide) $(APICHECK_COMMAND) -convert2xmlnostrip $$< $$@
endef
$(foreach ver,$(PLATFORM_SYSTEMSDK_VERSIONS),\
$(if $(call math_is_number,$(ver)),\
$(if $(wildcard prebuilts/sdk/$(ver)/system/api/android.txt),\
- $(eval $(call copy_api_txt_file,system-$(ver).txt,prebuilts/sdk/$(ver)/system/api/android.txt))\
+ $(eval $(call build_xml_api_file,system-$(ver).api,prebuilts/sdk/$(ver)/system/api/android.txt))\
)\
)\
)
@@ -42,4 +43,7 @@
$(foreach api_level,public system,\
$(foreach lib,$(filter-out android,$(filter-out %removed,$(filter-out incompatibilities,\
$(basename $(notdir $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/$(ver)/$(api_level)/api/*.txt)))))),\
- $(eval $(call copy_api_txt_file,$(lib)-$(ver)-$(api_level).txt,prebuilts/sdk/$(ver)/$(api_level)/api/$(lib).txt)))))
+ $(eval $(call build_xml_api_file,$(lib)-$(ver)-$(api_level).api,prebuilts/sdk/$(ver)/$(api_level)/api/$(lib).txt)) \
+ )\
+ )\
+)
diff --git a/tests/signature/intent-check/Android.bp b/tests/signature/intent-check/Android.bp
index f6ec58c..82fb79e 100644
--- a/tests/signature/intent-check/Android.bp
+++ b/tests/signature/intent-check/Android.bp
@@ -18,9 +18,9 @@
srcs: ["src/**/*.java"],
java_resources: [
- ":cts-current-txt",
- ":cts-system-current-txt",
- ":cts-system-removed-txt",
+ ":cts-current-api-gz",
+ ":cts-system-current-api-gz",
+ ":cts-system-removed-api-gz",
],
// Tag this module as a cts test artifact
diff --git a/tests/signature/intent-check/DynamicConfig.xml b/tests/signature/intent-check/DynamicConfig.xml
index 6c7aace..b0cc4dc 100644
--- a/tests/signature/intent-check/DynamicConfig.xml
+++ b/tests/signature/intent-check/DynamicConfig.xml
@@ -23,6 +23,7 @@
Bug: 78574873 android.intent.action.INSTALL_EPHEMERAL_PACKAGE
Bug: 78574873 android.intent.action.RESOLVE_EPHEMERAL_PACKAGE
Bug: 78574873 android.intent.action.EPHEMERAL_RESOLVER_SETTINGS
+ Bug: 150153196 android.intent.action.LOAD_DATA (system in API 30)
-->
<dynamicConfig>
<entry key ="intent_whitelist">
@@ -34,5 +35,6 @@
<value>android.intent.action.INSTALL_EPHEMERAL_PACKAGE</value>
<value>android.intent.action.RESOLVE_EPHEMERAL_PACKAGE</value>
<value>android.intent.action.EPHEMERAL_RESOLVER_SETTINGS</value>
+ <value>android.intent.action.LOAD_DATA</value>
</entry>
</dynamicConfig>
diff --git a/tests/signature/intent-check/src/android/signature/cts/intent/IntentTest.java b/tests/signature/intent-check/src/android/signature/cts/intent/IntentTest.java
index 0195dc4..efd574e 100644
--- a/tests/signature/intent-check/src/android/signature/cts/intent/IntentTest.java
+++ b/tests/signature/intent-check/src/android/signature/cts/intent/IntentTest.java
@@ -48,11 +48,11 @@
@RunWith(AndroidJUnit4.class)
public class IntentTest {
- private static final String CURRENT_API_RESOURCE = "current.txt";
+ private static final String CURRENT_API_RESOURCE = "current.api.gz";
- private static final String SYSTEM_CURRENT_API_RESOURCE = "system-current.txt";
+ private static final String SYSTEM_CURRENT_API_RESOURCE = "system-current.api.gz";
- private static final String SYSTEM_REMOVED_API_RESOURCE = "system-removed.txt";
+ private static final String SYSTEM_REMOVED_API_RESOURCE = "system-removed.api.gz";
private static final String TAG = IntentTest.class.getSimpleName();
diff --git a/tests/signature/lib/android/Android.bp b/tests/signature/lib/android/Android.bp
index 7b0e679..546190a 100644
--- a/tests/signature/lib/android/Android.bp
+++ b/tests/signature/lib/android/Android.bp
@@ -24,7 +24,6 @@
],
static_libs: [
"signature-common-javalib",
- "metalava",
],
sdk_version: "current",
}
diff --git a/tests/signature/lib/android/src/android/signature/cts/ApiDocumentParser.java b/tests/signature/lib/android/src/android/signature/cts/ApiDocumentParser.java
index 78027d4..70e3665 100644
--- a/tests/signature/lib/android/src/android/signature/cts/ApiDocumentParser.java
+++ b/tests/signature/lib/android/src/android/signature/cts/ApiDocumentParser.java
@@ -34,9 +34,14 @@
private ApiParser getApiParser(VirtualPath path) {
if (path.toString().endsWith(".txt")) {
- return new TextApiParser();
+ // At one point we used the "text" signature format in this test, but we stopped doing
+ // it because we don't want metalava to be used as a library, especially
+ // on the device side.
+ throw new RuntimeException("Signature format not supported");
} else if (path.toString().endsWith(".api")) {
- return new XmlApiParser(tag);
+ return new XmlApiParser(tag, /*gzipped=*/ false);
+ } else if (path.toString().endsWith(".api.gz")) {
+ return new XmlApiParser(tag, /*gzipped=*/ true);
} else {
throw new IllegalStateException("Unrecognized file type: " + path);
}
diff --git a/tests/signature/lib/android/src/android/signature/cts/KtHelper.kt b/tests/signature/lib/android/src/android/signature/cts/KtHelper.kt
deleted file mode 100644
index 4d2fade..0000000
--- a/tests/signature/lib/android/src/android/signature/cts/KtHelper.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-@file:JvmName("KtHelper")
-package android.signature.cts
-
-import com.android.tools.metalava.model.TypeItem
-
-/**
- * Allows Java to call the TypeItem.toTypeString() without having to explicitly specify each named
- * parameter to its default. This allows additional parameters to be added to the method without
- * breaking the Java code.
- */
-fun toDefaultTypeString(item: TypeItem): String {
- // Normalize the strings to contain , without a following space. This is needed because
- // different versions of the txt specification used different separators in generic types, some
- // used "," and some used ", " and metalava does not normalize them. e.g. some files will format
- // a Map from String to Integer as "java.util.Map<java.lang.String,java.lang.Integer>" and some
- // will format it as "java.util.Map<java.lang.String, java.lang.Integer>".
- //
- // Must match separator used in android.signature.cts.ReflectionHelper.typeToString.
- return item.toTypeString().replace(", ", ",")
-}
diff --git a/tests/signature/lib/android/src/android/signature/cts/TextApiParser.java b/tests/signature/lib/android/src/android/signature/cts/TextApiParser.java
deleted file mode 100644
index 26ac862..0000000
--- a/tests/signature/lib/android/src/android/signature/cts/TextApiParser.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2019 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 android.signature.cts;
-
-import android.signature.cts.JDiffClassDescription.JDiffConstructor;
-import android.signature.cts.JDiffClassDescription.JDiffField;
-import android.signature.cts.JDiffClassDescription.JDiffMethod;
-import com.android.tools.metalava.doclava1.ApiFile;
-import com.android.tools.metalava.doclava1.ApiParseException;
-import com.android.tools.metalava.doclava1.TextCodebase;
-import com.android.tools.metalava.model.ClassItem;
-import com.android.tools.metalava.model.ConstructorItem;
-import com.android.tools.metalava.model.FieldItem;
-import com.android.tools.metalava.model.Item;
-import com.android.tools.metalava.model.MethodItem;
-import com.android.tools.metalava.model.ModifierList;
-import com.android.tools.metalava.model.PackageItem;
-import com.android.tools.metalava.model.ParameterItem;
-import com.android.tools.metalava.model.TypeItem;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.reflect.Modifier;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import kotlin.streams.jdk8.StreamsKt;
-
-/**
- * Parser for the text representation of an API specification.
- */
-public class TextApiParser extends ApiParser {
-
- @Override
- public Stream<JDiffClassDescription> parseAsStream(VirtualPath path) {
- try {
- String content = new BufferedReader(new InputStreamReader(path.newInputStream()))
- .lines()
- .parallel()
- .collect(Collectors.joining("\n"));
- TextCodebase codebase = ApiFile.parseApi(path.toString(), content, false);
- List<PackageItem> packages = codebase.getPackages().getPackages();
- return packages.stream()
- // Map each package to the Sequence of ClassItems that it contains
- .map(PackageItem::allClasses)
- // Flatten the Sequences of ClassItems into one stream.
- .flatMap(StreamsKt::asStream)
- // Filter out TextClassItems that are used from but not defined in the source.
- .filter(ClassItem::isDefined)
- .map(TextApiParser::convertClass);
- } catch (IOException | ApiParseException e) {
- throw new RuntimeException("Could not parse " + path, e);
- }
- }
-
- private static JDiffClassDescription convertClass(ClassItem item) {
- String pkg = item.containingPackage().qualifiedName();
-
- JDiffClassDescription currentClass = new JDiffClassDescription(pkg, item.fullName());
-
- int modifiers = getModifiers(item);
-
- currentClass.setModifier(modifiers);
- currentClass.setType(item.isInterface() ? JDiffClassDescription.JDiffType.INTERFACE :
- JDiffClassDescription.JDiffType.CLASS);
-
- // Map the super class.
- ClassItem superClass = item.superClass();
- if (superClass != null) {
- String extendsClass = superClass.qualifiedName();
- if (item.isInterface()) {
- // TextCodebase treats an interface as if it extends java.lang.Object.
- if (!superClass.isJavaLangObject()) {
- currentClass.addImplInterface(extendsClass);
- }
- } else {
- currentClass.setExtendsClass(extendsClass);
- }
- }
-
- // Map the interfaces.
- item.interfaceTypes().stream()
- .map(TypeItem::asClass)
- .filter(Objects::nonNull)
- .map(ClassItem::qualifiedName)
- .forEach(currentClass::addImplInterface);
-
- item.fields().stream().map(TextApiParser::convertField).forEach(currentClass::addField);
-
- item.constructors().stream()
- .map(TextApiParser::convertConstructor)
- .forEach(currentClass::addConstructor);
-
- item.methods().stream()
- .map(TextApiParser::convertMethod)
- .forEach(currentClass::addMethod);
-
- return currentClass;
- }
-
- private static int getModifiers(Item item) {
- ModifierList modifierList = item.getModifiers();
- int modifiers = 0;
- if (modifierList.isAbstract()) {
- modifiers |= Modifier.ABSTRACT;
- }
- if (modifierList.isFinal()) {
- modifiers |= Modifier.FINAL;
- }
- if (modifierList.isNative()) {
- modifiers |= Modifier.NATIVE;
- }
- if (modifierList.isStatic()) {
- modifiers |= Modifier.STATIC;
- }
- if (modifierList.isSynchronized()) {
- modifiers |= Modifier.SYNCHRONIZED;
- }
- if (modifierList.isTransient()) {
- modifiers |= Modifier.TRANSIENT;
- }
- if (modifierList.isVolatile()) {
- modifiers |= Modifier.VOLATILE;
- }
- if (modifierList.isPrivate()) {
- modifiers |= Modifier.PRIVATE;
- } else if (modifierList.isProtected()) {
- modifiers |= Modifier.PROTECTED;
- } else if (modifierList.isPublic()) {
- modifiers |= Modifier.PUBLIC;
- }
- return modifiers;
- }
-
- private static JDiffField convertField(FieldItem item) {
- int modifiers = getModifiers(item);
- Object value = item.initialValue(true);
-
- if (item.isEnumConstant()) {
- // Set the enum bit on the enum constant to match the modifiers returned by reflection.
- modifiers |= 0x00004000;
- }
-
- return new JDiffField(item.name(),
- KtHelper.toDefaultTypeString(item.type()), modifiers,
- value == null ? null : value.toString());
- }
-
- private static JDiffConstructor convertConstructor(ConstructorItem item) {
- JDiffConstructor constructor = new JDiffConstructor(item.name(), getModifiers(item));
-
- convertParameters(item, constructor);
-
- return constructor;
- }
-
- private static void convertParameters(MethodItem item, JDiffMethod method) {
- item.parameters().stream()
- .map(TextApiParser::convertParameter)
- .forEach(method::addParam);
- }
-
- private static JDiffMethod convertMethod(MethodItem item) {
- TypeItem returnType = item.returnType();
- String returnTypeAsString = returnType == null ? null
- : KtHelper.toDefaultTypeString(returnType);
- JDiffMethod method = new JDiffMethod(item.name(), getModifiers(item), returnTypeAsString);
-
- convertParameters(item, method);
-
- return method;
- }
-
- private static String convertParameter(ParameterItem item) {
- return KtHelper.toDefaultTypeString(item.type());
- }
-}
diff --git a/tests/signature/lib/android/src/android/signature/cts/XmlApiParser.java b/tests/signature/lib/android/src/android/signature/cts/XmlApiParser.java
index 8e5d0bb..e77d7e0 100644
--- a/tests/signature/lib/android/src/android/signature/cts/XmlApiParser.java
+++ b/tests/signature/lib/android/src/android/signature/cts/XmlApiParser.java
@@ -20,6 +20,7 @@
import android.signature.cts.JDiffClassDescription.JDiffMethod;
import android.util.Log;
import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.HashSet;
@@ -28,6 +29,8 @@
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
+import java.util.zip.GZIPInputStream;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
@@ -106,11 +109,13 @@
}
private final String tag;
+ private final boolean gzipped;
private final XmlPullParserFactory factory;
- XmlApiParser(String tag) {
+ XmlApiParser(String tag, boolean gzipped) {
this.tag = tag;
+ this.gzipped = gzipped;
try {
factory = XmlPullParserFactory.newInstance();
} catch (XmlPullParserException e) {
@@ -121,18 +126,25 @@
/**
* Load field information from xml to memory.
*
- * @param className
+ * @param currentClass
* of the class being examined which will be shown in error messages
* @param parser
* The XmlPullParser which carries the xml information.
* @return the new field
*/
- private static JDiffField loadFieldInfo(String className, XmlPullParser parser) {
+ private static JDiffField loadFieldInfo(
+ JDiffClassDescription currentClass, XmlPullParser parser) {
String fieldName = parser.getAttributeValue(null, ATTRIBUTE_NAME);
String fieldType = canonicalizeType(parser.getAttributeValue(null, ATTRIBUTE_TYPE));
- int modifier = jdiffModifierToReflectionFormat(className, parser);
+ int modifier = jdiffModifierToReflectionFormat(currentClass.getClassName(), parser);
String value = parser.getAttributeValue(null, ATTRIBUTE_VALUE);
+ if (currentClass.isEnumType() && fieldType.equals(currentClass.getAbsoluteClassName())
+ && (value != null && value.startsWith("PsiEnumConstant:"))) {
+ // We don't need to check the value.
+ value = null;
+ }
+
// Canonicalize the expected value to ensure that it is consistent with the values obtained
// using reflection by ApiComplianceChecker.getFieldValueAsString(...).
if (value != null) {
@@ -148,10 +160,24 @@
break;
case "char":
- // A character is encoded in XML as its numeric value. Convert it to a
+ // A character may be encoded in XML as its numeric value. Convert it to a
// string containing the single character.
- char c = (char) Integer.parseInt(value);
- value = String.valueOf(c);
+ try {
+ char c = (char) Integer.parseInt(value);
+ value = String.valueOf(c);
+ } catch (NumberFormatException e) {
+ // If not, it must be a string "'?'". Extract the second character,
+ // but we need to unescape it.
+ int len = value.length();
+ if (value.charAt(0) == '\'' && value.charAt(len - 1) == '\'') {
+ String sub = value.substring(1, len - 1);
+ value = unescapeFieldStringValue(sub);
+ } else {
+ throw new NumberFormatException(String.format(
+ "Cannot parse the value of field '%s': invalid number '%s'",
+ fieldName, value));
+ }
+ }
break;
case "double":
@@ -248,10 +274,25 @@
String className = parser.getAttributeValue(null, ATTRIBUTE_NAME);
JDiffClassDescription currentClass = new JDiffClassDescription(pkg, className);
- currentClass.setModifier(jdiffModifierToReflectionFormat(className, parser));
currentClass.setType(isInterface ? JDiffClassDescription.JDiffType.INTERFACE :
JDiffClassDescription.JDiffType.CLASS);
- currentClass.setExtendsClass(parser.getAttributeValue(null, ATTRIBUTE_EXTENDS));
+
+ String superClass = stripGenericsArgs(parser.getAttributeValue(null, ATTRIBUTE_EXTENDS));
+ int modifiers = jdiffModifierToReflectionFormat(className, parser);
+ if (isInterface) {
+ if (superClass != null) {
+ currentClass.addImplInterface(superClass);
+ }
+ } else {
+ if ("java.lang.annotation.Annotation".equals(superClass)) {
+ // ApiComplianceChecker expects "java.lang.annotation.Annotation" to be in
+ // the "impl interfaces".
+ currentClass.addImplInterface(superClass);
+ } else {
+ currentClass.setExtendsClass(superClass);
+ }
+ }
+ currentClass.setModifier(modifiers);
return currentClass;
}
@@ -324,7 +365,11 @@
XmlPullParser parser;
try {
parser = factory.newPullParser();
- parser.setInput(path.newInputStream(), null);
+ InputStream input = path.newInputStream();
+ if (gzipped) {
+ input = new GZIPInputStream(input);
+ }
+ parser.setInput(input, null);
return StreamSupport
.stream(new ClassDescriptionSpliterator(parser), false);
} catch (XmlPullParserException | IOException e) {
@@ -332,6 +377,10 @@
}
}
+ private static String stripGenericsArgs(String typeName) {
+ return typeName == null ? null : typeName.replaceFirst("<.*", "");
+ }
+
private class ClassDescriptionSpliterator implements Spliterator<JDiffClassDescription> {
private final XmlPullParser parser;
@@ -444,8 +493,8 @@
break;
case TAG_IMPLEMENTS:
- currentClass
- .addImplInterface(parser.getAttributeValue(null, ATTRIBUTE_NAME));
+ currentClass.addImplInterface(stripGenericsArgs(
+ parser.getAttributeValue(null, ATTRIBUTE_NAME)));
break;
case TAG_CONSTRUCTOR:
@@ -470,7 +519,7 @@
break;
case TAG_FIELD:
- JDiffField field = loadFieldInfo(currentClass.getClassName(), parser);
+ JDiffField field = loadFieldInfo(currentClass, parser);
currentClass.addField(field);
break;
diff --git a/tests/tests/content/pm/SecureFrp/AndroidManifest.xml b/tests/tests/content/pm/SecureFrp/AndroidManifest.xml
index 9e45d4a..f1b5184 100644
--- a/tests/tests/content/pm/SecureFrp/AndroidManifest.xml
+++ b/tests/tests/content/pm/SecureFrp/AndroidManifest.xml
@@ -18,7 +18,6 @@
package="com.android.tests.securefrpinstall" >
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
- <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application>
<receiver android:name="com.android.cts.install.lib.LocalIntentSender"
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecBlockModelTest.java b/tests/tests/media/src/android/media/cts/MediaCodecBlockModelTest.java
index 7f60d5f..9ffba5f 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecBlockModelTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecBlockModelTest.java
@@ -30,6 +30,7 @@
import android.media.MediaFormat;
import android.media.cts.R;
import android.net.Uri;
+import android.os.Build;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.RequiresDevice;
import android.test.AndroidTestCase;
@@ -38,6 +39,7 @@
import androidx.test.filters.SmallTest;
+import com.android.compatibility.common.util.ApiLevelUtil;
import com.android.compatibility.common.util.MediaUtils;
import java.io.IOException;
@@ -76,6 +78,7 @@
// Time out processing, as we have no way to query whether the decoder will produce output.
private static final int TIMEOUT_MS = 60000; // 1 minute
+ private boolean mIsAtLeastR = ApiLevelUtil.isAtLeast(Build.VERSION_CODES.R);
/**
* Tests whether decoding a short group-of-pictures succeeds. The test queues a few video frames
* then signals end-of-stream. The test fails if the decoder doesn't output the queued frames.
@@ -84,6 +87,7 @@
@SmallTest
@RequiresDevice
public void testDecodeShortVideo() throws InterruptedException {
+ if (!MediaUtils.check(mIsAtLeastR, "test needs Android 11")) return;
runThread(() -> runDecodeShortVideo(
INPUT_RESOURCE_ID,
LAST_BUFFER_TIMESTAMP_US,
@@ -100,6 +104,7 @@
* then signals end-of-stream. The test fails if the decoder doesn't output the queued frames.
*/
public void testDecodeShortEncryptedVideo() throws InterruptedException {
+ if (!MediaUtils.check(mIsAtLeastR, "test needs Android 11")) return;
runThread(() -> runDecodeShortEncryptedVideo(
true /* obtainBlockForEachBuffer */));
runThread(() -> runDecodeShortEncryptedVideo(
@@ -114,6 +119,7 @@
@SmallTest
@RequiresDevice
public void testDecodeShortAudio() throws InterruptedException {
+ if (!MediaUtils.check(mIsAtLeastR, "test needs Android 11")) return;
runThread(() -> runDecodeShortAudio(
INPUT_RESOURCE_ID,
LAST_BUFFER_TIMESTAMP_US,
@@ -132,6 +138,7 @@
@SmallTest
@RequiresDevice
public void testEncodeShortAudio() throws InterruptedException {
+ if (!MediaUtils.check(mIsAtLeastR, "test needs Android 11")) return;
runThread(() -> runEncodeShortAudio());
}
@@ -143,6 +150,7 @@
@SmallTest
@RequiresDevice
public void testEncodeShortVideo() throws InterruptedException {
+ if (!MediaUtils.check(mIsAtLeastR, "test needs Android 11")) return;
runThread(() -> runEncodeShortVideo());
}
@@ -153,6 +161,7 @@
@SmallTest
@RequiresDevice
public void testFormatChange() throws InterruptedException {
+ if (!MediaUtils.check(mIsAtLeastR, "test needs Android 11")) return;
List<FormatChangeEvent> events = new ArrayList<>();
runThread(() -> runDecodeShortVideo(
getMediaExtractorForMimeType(INPUT_RESOURCE_ID, "video/"),
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index a20e39f..d41716e 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -41,6 +41,7 @@
import android.media.MediaFormat;
import android.media.cts.R;
import android.opengl.GLES20;
+import android.os.Build;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
@@ -55,6 +56,7 @@
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
+import com.android.compatibility.common.util.ApiLevelUtil;
import com.android.compatibility.common.util.MediaUtils;
import java.io.BufferedInputStream;
@@ -118,6 +120,7 @@
// Time out decoding, as we have no way to query whether the decoder will produce output.
private static final int DECODING_TIMEOUT_MS = 10000;
+ private static boolean mIsAtLeastR = ApiLevelUtil.isAtLeast(Build.VERSION_CODES.R);
/**
* Tests:
* <br> Exceptions for MediaCodec factory methods
@@ -315,25 +318,27 @@
fail("configure should not return MediaCodec.CodecException on wrong state");
} catch (IllegalStateException e) { // expected
}
- try {
- codec.getQueueRequest(0);
- fail("getQueueRequest should throw IllegalStateException when not configured with " +
- "CONFIGURE_FLAG_USE_BLOCK_MODEL");
- } catch (MediaCodec.CodecException e) {
- logMediaCodecException(e);
- fail("getQueueRequest should not return " +
- "MediaCodec.CodecException on wrong configuration");
- } catch (IllegalStateException e) { // expected
- }
- try {
- codec.getOutputFrame(0);
- fail("getOutputFrame should throw IllegalStateException when not configured with " +
- "CONFIGURE_FLAG_USE_BLOCK_MODEL");
- } catch (MediaCodec.CodecException e) {
- logMediaCodecException(e);
- fail("getOutputFrame should not return MediaCodec.CodecException on wrong " +
- "configuration");
- } catch (IllegalStateException e) { // expected
+ if (mIsAtLeastR) {
+ try {
+ codec.getQueueRequest(0);
+ fail("getQueueRequest should throw IllegalStateException when not configured with " +
+ "CONFIGURE_FLAG_USE_BLOCK_MODEL");
+ } catch (MediaCodec.CodecException e) {
+ logMediaCodecException(e);
+ fail("getQueueRequest should not return " +
+ "MediaCodec.CodecException on wrong configuration");
+ } catch (IllegalStateException e) { // expected
+ }
+ try {
+ codec.getOutputFrame(0);
+ fail("getOutputFrame should throw IllegalStateException when not configured with " +
+ "CONFIGURE_FLAG_USE_BLOCK_MODEL");
+ } catch (MediaCodec.CodecException e) {
+ logMediaCodecException(e);
+ fail("getOutputFrame should not return MediaCodec.CodecException on wrong " +
+ "configuration");
+ } catch (IllegalStateException e) { // expected
+ }
}
// two flushes should be fine.
@@ -368,100 +373,102 @@
} catch (IllegalStateException e) { // expected
}
- // recreate
- codec = createCodecByType(format.getString(MediaFormat.KEY_MIME), isEncoder);
+ if (mIsAtLeastR) {
+ // recreate
+ codec = createCodecByType(format.getString(MediaFormat.KEY_MIME), isEncoder);
- // configure improperly
- try {
+ // configure improperly
+ try {
+ codec.configure(format, null /* surface */, null /* crypto */,
+ MediaCodec.CONFIGURE_FLAG_USE_BLOCK_MODEL |
+ (isEncoder ? MediaCodec.CONFIGURE_FLAG_ENCODE : 0) /* flags */);
+ fail("configure with detached buffer mode should be done after setCallback");
+ } catch (MediaCodec.CodecException e) {
+ logMediaCodecException(e);
+ fail("configure should not return IllegalStateException when improperly configured");
+ } catch (IllegalStateException e) { // expected
+ }
+
+ final LinkedBlockingQueue<Integer> inputQueue = new LinkedBlockingQueue<>();
+ codec.setCallback(new MediaCodec.Callback() {
+ @Override
+ public void onInputBufferAvailable(MediaCodec codec, int index) {
+ inputQueue.offer(index);
+ }
+ @Override
+ public void onOutputBufferAvailable(
+ MediaCodec codec, int index, MediaCodec.BufferInfo info) { }
+ @Override
+ public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) { }
+ @Override
+ public void onError(MediaCodec codec, CodecException e) { }
+ });
+
+ // configure with CONFIGURE_FLAG_USE_BLOCK_MODEL (enter Configured State)
codec.configure(format, null /* surface */, null /* crypto */,
MediaCodec.CONFIGURE_FLAG_USE_BLOCK_MODEL |
(isEncoder ? MediaCodec.CONFIGURE_FLAG_ENCODE : 0) /* flags */);
- fail("configure with detached buffer mode should be done after setCallback");
- } catch (MediaCodec.CodecException e) {
- logMediaCodecException(e);
- fail("configure should not return IllegalStateException when improperly configured");
- } catch (IllegalStateException e) { // expected
- }
- final LinkedBlockingQueue<Integer> inputQueue = new LinkedBlockingQueue<>();
- codec.setCallback(new MediaCodec.Callback() {
- @Override
- public void onInputBufferAvailable(MediaCodec codec, int index) {
- inputQueue.offer(index);
+ // start codec (enter Executing state)
+ codec.start();
+
+ // grab input index (this should happen immediately)
+ Integer index = null;
+ try {
+ index = inputQueue.poll(2, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
}
- @Override
- public void onOutputBufferAvailable(
- MediaCodec codec, int index, MediaCodec.BufferInfo info) { }
- @Override
- public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) { }
- @Override
- public void onError(MediaCodec codec, CodecException e) { }
- });
+ assertNotNull(index);
- // configure with CONFIGURE_FLAG_USE_BLOCK_MODEL (enter Configured State)
- codec.configure(format, null /* surface */, null /* crypto */,
- MediaCodec.CONFIGURE_FLAG_USE_BLOCK_MODEL |
- (isEncoder ? MediaCodec.CONFIGURE_FLAG_ENCODE : 0) /* flags */);
+ // test a few commands
+ try {
+ codec.getInputBuffers();
+ fail("getInputBuffers called in detached buffer mode should throw exception");
+ } catch (MediaCodec.IncompatibleWithBlockModelException e) { // expected
+ }
+ try {
+ codec.getOutputBuffers();
+ fail("getOutputBuffers called in detached buffer mode should throw exception");
+ } catch (MediaCodec.IncompatibleWithBlockModelException e) { // expected
+ }
+ try {
+ codec.getInputBuffer(index);
+ fail("getInputBuffer called in detached buffer mode should throw exception");
+ } catch (MediaCodec.IncompatibleWithBlockModelException e) { // expected
+ }
+ try {
+ codec.dequeueInputBuffer(0);
+ fail("dequeueInputBuffer called in detached buffer mode should throw exception");
+ } catch (MediaCodec.IncompatibleWithBlockModelException e) { // expected
+ }
+ MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+ try {
+ codec.dequeueOutputBuffer(info, 0);
+ fail("dequeueOutputBuffer called in detached buffer mode should throw exception");
+ } catch (MediaCodec.IncompatibleWithBlockModelException e) { // expected
+ }
- // start codec (enter Executing state)
- codec.start();
-
- // grab input index (this should happen immediately)
- Integer index = null;
- try {
- index = inputQueue.poll(2, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- }
- assertNotNull(index);
-
- // test a few commands
- try {
- codec.getInputBuffers();
- fail("getInputBuffers called in detached buffer mode should throw exception");
- } catch (MediaCodec.IncompatibleWithBlockModelException e) { // expected
- }
- try {
- codec.getOutputBuffers();
- fail("getOutputBuffers called in detached buffer mode should throw exception");
- } catch (MediaCodec.IncompatibleWithBlockModelException e) { // expected
- }
- try {
- codec.getInputBuffer(index);
- fail("getInputBuffer called in detached buffer mode should throw exception");
- } catch (MediaCodec.IncompatibleWithBlockModelException e) { // expected
- }
- try {
- codec.dequeueInputBuffer(0);
- fail("dequeueInputBuffer called in detached buffer mode should throw exception");
- } catch (MediaCodec.IncompatibleWithBlockModelException e) { // expected
- }
- MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
- try {
- codec.dequeueOutputBuffer(info, 0);
- fail("dequeueOutputBuffer called in detached buffer mode should throw exception");
- } catch (MediaCodec.IncompatibleWithBlockModelException e) { // expected
- }
-
- // test getQueueRequest
- MediaCodec.QueueRequest request = codec.getQueueRequest(index);
- try {
- request.queue();
- fail("QueueRequest should throw IllegalStateException when no buffer is set");
- } catch (IllegalStateException e) { // expected
- }
- // setting a block
- String[] names = new String[]{ codec.getName() };
- request.setLinearBlock(MediaCodec.LinearBlock.obtain(1, names), 0, 0);
- // setting additional block should fail
- try (HardwareBuffer buffer = HardwareBuffer.create(
- 16 /* width */,
- 16 /* height */,
- HardwareBuffer.YCBCR_420_888,
- 1 /* layers */,
- HardwareBuffer.USAGE_CPU_READ_OFTEN | HardwareBuffer.USAGE_CPU_WRITE_OFTEN)) {
- request.setHardwareBuffer(buffer);
- fail("QueueRequest should throw IllegalStateException multiple blocks are set.");
- } catch (IllegalStateException e) { // expected
+ // test getQueueRequest
+ MediaCodec.QueueRequest request = codec.getQueueRequest(index);
+ try {
+ request.queue();
+ fail("QueueRequest should throw IllegalStateException when no buffer is set");
+ } catch (IllegalStateException e) { // expected
+ }
+ // setting a block
+ String[] names = new String[]{ codec.getName() };
+ request.setLinearBlock(MediaCodec.LinearBlock.obtain(1, names), 0, 0);
+ // setting additional block should fail
+ try (HardwareBuffer buffer = HardwareBuffer.create(
+ 16 /* width */,
+ 16 /* height */,
+ HardwareBuffer.YCBCR_420_888,
+ 1 /* layers */,
+ HardwareBuffer.USAGE_CPU_READ_OFTEN | HardwareBuffer.USAGE_CPU_WRITE_OFTEN)) {
+ request.setHardwareBuffer(buffer);
+ fail("QueueRequest should throw IllegalStateException multiple blocks are set.");
+ } catch (IllegalStateException e) { // expected
+ }
}
// release codec
@@ -2662,8 +2669,10 @@
* through the scenario.
*/
public void testFlushAfterFirstBuffer() throws Exception {
- for (int i = 0; i < 100; ++i) {
- doFlushAfterFirstBuffer();
+ if (MediaUtils.check(mIsAtLeastR, "test needs Android 11")) {
+ for (int i = 0; i < 100; ++i) {
+ doFlushAfterFirstBuffer();
+ }
}
}
diff --git a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
index 66f65a1..1407f79 100644
--- a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
@@ -31,6 +31,7 @@
import android.media.MediaFormat;
import static android.media.MediaFormat.MIMETYPE_VIDEO_DOLBY_VISION;
import android.media.cts.R;
+import android.os.Build;
import android.os.PersistableBundle;
import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
@@ -39,6 +40,7 @@
import androidx.test.filters.SmallTest;
+import com.android.compatibility.common.util.ApiLevelUtil;
import com.android.compatibility.common.util.MediaUtils;
import java.io.BufferedReader;
@@ -61,6 +63,7 @@
private static final String TAG = "MediaExtractorTest";
private static final UUID UUID_WIDEVINE = new UUID(0xEDEF8BA979D64ACEL, 0xA3C827DCD51D21EDL);
private static final UUID UUID_PLAYREADY = new UUID(0x9A04F07998404286L, 0xAB92E65BE0885F95L);
+ private static boolean mIsAtLeastR = ApiLevelUtil.isAtLeast(Build.VERSION_CODES.R);
protected Resources mResources;
protected MediaExtractor mExtractor;
@@ -376,6 +379,7 @@
}
public void testGetDrmInitData() throws Exception {
+ if (!MediaUtils.check(mIsAtLeastR, "test needs Android 11")) return;
setDataSource(R.raw.psshtest);
DrmInitData drmInitData = mExtractor.getDrmInitData();
assertEquals(drmInitData.getSchemeInitDataCount(), 2);
diff --git a/tests/tests/mediaparser/Android.bp b/tests/tests/mediaparser/Android.bp
index 3a65698..6a13d24 100644
--- a/tests/tests/mediaparser/Android.bp
+++ b/tests/tests/mediaparser/Android.bp
@@ -23,6 +23,7 @@
],
srcs: ["src/**/*.java"],
sdk_version: "test_current",
+ min_sdk_version: "29",
libs: [
"android.test.base.stubs",
"android.test.runner.stubs",
diff --git a/tests/tests/net/api23Test/AndroidManifest.xml b/tests/tests/net/api23Test/AndroidManifest.xml
index 8af87f6..4889660 100644
--- a/tests/tests/net/api23Test/AndroidManifest.xml
+++ b/tests/tests/net/api23Test/AndroidManifest.xml
@@ -18,8 +18,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.net.cts.api23test">
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:usesCleartextTraffic="true">
diff --git a/tests/tests/net/src/android/net/cts/CaptivePortalApiTest.kt b/tests/tests/net/src/android/net/cts/CaptivePortalApiTest.kt
index 40d0ca6..68d5281 100644
--- a/tests/tests/net/src/android/net/cts/CaptivePortalApiTest.kt
+++ b/tests/tests/net/src/android/net/cts/CaptivePortalApiTest.kt
@@ -61,7 +61,6 @@
import java.net.Inet4Address
import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.TimeUnit
-import kotlin.reflect.KClass
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
@@ -90,7 +89,7 @@
private val eth by lazy { context.assertHasService(EthernetManager::class.java) }
private val cm by lazy { context.assertHasService(ConnectivityManager::class.java) }
- private val handlerThread = HandlerThread(CaptivePortalApiTest::class.simpleName)
+ private val handlerThread = HandlerThread(CaptivePortalApiTest::class.java.simpleName)
private val serverIpAddr = InetAddresses.parseNumericAddress("192.0.2.222") as Inet4Address
private val clientIpAddr = InetAddresses.parseNumericAddress("192.0.2.111") as Inet4Address
private val httpServer = HttpServer()
@@ -155,11 +154,11 @@
fun testApiCallbacks() {
// Handle the DHCP handshake that includes the capport API URL
val discover = reader.assertDhcpPacketReceived(
- DhcpDiscoverPacket::class, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_DISCOVER)
+ DhcpDiscoverPacket::class.java, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_DISCOVER)
reader.sendResponse(makeOfferPacket(discover.clientMac, discover.transactionId))
val request = reader.assertDhcpPacketReceived(
- DhcpRequestPacket::class, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_REQUEST)
+ DhcpRequestPacket::class.java, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_REQUEST)
assertEquals(discover.transactionId, request.transactionId)
assertEquals(clientIpAddr, request.mRequestedIp)
reader.sendResponse(makeAckPacket(request.clientMac, request.transactionId))
@@ -244,7 +243,7 @@
}
private fun <T : DhcpPacket> TapPacketReader.assertDhcpPacketReceived(
- packetType: KClass<T>,
+ packetType: Class<T>,
timeoutMs: Long,
type: Byte
): T {
@@ -254,7 +253,7 @@
val packet = DhcpPacket.decodeFullPacket(packetBytes, packetBytes.size, DhcpPacket.ENCAP_L2)
assertTrue(packetType.isInstance(packet),
"Expected ${packetType.simpleName} but got ${packet.javaClass.simpleName}")
- return packetType.java.cast(packet)
+ return packetType.cast(packet)
}
private fun <T> Context.assertHasService(manager: Class<T>): T {
diff --git a/tests/tests/net/src/android/net/cts/Ikev2VpnTest.java b/tests/tests/net/src/android/net/cts/Ikev2VpnTest.java
index 5cc0cb4..dff2581 100644
--- a/tests/tests/net/src/android/net/cts/Ikev2VpnTest.java
+++ b/tests/tests/net/src/android/net/cts/Ikev2VpnTest.java
@@ -46,13 +46,15 @@
import android.net.TestNetworkManager;
import android.net.VpnManager;
import android.net.cts.util.CtsNetUtils;
+import android.os.Build;
import android.platform.test.annotations.AppModeFull;
import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.HexDump;
import com.android.org.bouncycastle.x509.X509V1CertificateGenerator;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -70,7 +72,8 @@
import javax.security.auth.x500.X500Principal;
-@RunWith(AndroidJUnit4.class)
+@RunWith(DevSdkIgnoreRunner.class)
+@IgnoreUpTo(Build.VERSION_CODES.Q)
@AppModeFull(reason = "Appops state changes disallowed for instant apps (OP_ACTIVATE_PLATFORM_VPN)")
public class Ikev2VpnTest {
private static final String TAG = Ikev2VpnTest.class.getSimpleName();
diff --git a/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java
index 32cdf92..b1f3602 100644
--- a/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java
+++ b/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java
@@ -30,8 +30,8 @@
import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.content.BroadcastReceiver;
-import android.content.Context;
import android.content.ContentResolver;
+import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
@@ -44,6 +44,8 @@
import android.net.NetworkInfo.State;
import android.net.NetworkRequest;
import android.net.TestNetworkManager;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Build;
@@ -169,6 +171,7 @@
boolean connected = false;
try {
+ clearWifiBlacklist();
SystemUtil.runShellCommand("svc wifi enable");
SystemUtil.runWithShellPermissionIdentity(() -> mWifiManager.reconnect(),
NETWORK_SETTINGS);
@@ -188,11 +191,23 @@
return wifiNetwork;
}
+ /**
+ * Re-enable wifi networks that were blacklisted, typically because no internet connection was
+ * detected the last time they were connected. This is necessary to make sure wifi can reconnect
+ * to them.
+ */
+ private void clearWifiBlacklist() {
+ SystemUtil.runWithShellPermissionIdentity(() -> {
+ for (WifiConfiguration config : mWifiManager.getConfiguredNetworks()) {
+ mWifiManager.enableNetwork(config.networkId, false /* attemptConnect */);
+ }
+ });
+ }
+
/** Disable WiFi and wait for it to become disconnected from the network. */
public void disconnectFromWifi(Network wifiNetworkToCheck) {
final TestNetworkCallback callback = new TestNetworkCallback();
mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
- Network lostWifiNetwork = null;
ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
mCm, ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED);
@@ -200,9 +215,15 @@
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
mContext.registerReceiver(receiver, filter);
+ final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
+ final boolean wasWifiConnected = wifiInfo != null && wifiInfo.getNetworkId() != -1;
// Assert that we can establish a TCP connection on wifi.
Socket wifiBoundSocket = null;
if (wifiNetworkToCheck != null) {
+ assertTrue("Cannot check network " + wifiNetworkToCheck + ": wifi is not connected",
+ wasWifiConnected);
+ final NetworkCapabilities nc = mCm.getNetworkCapabilities(wifiNetworkToCheck);
+ assertNotNull("Network " + wifiNetworkToCheck + " is not connected", nc);
try {
wifiBoundSocket = getBoundSocket(wifiNetworkToCheck, TEST_HOST, HTTP_PORT);
testHttpRequest(wifiBoundSocket);
@@ -211,13 +232,14 @@
}
}
- boolean disconnected = false;
try {
SystemUtil.runShellCommand("svc wifi disable");
- // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION.
- lostWifiNetwork = callback.waitForLost();
- assertNotNull(lostWifiNetwork);
- disconnected = receiver.waitForState();
+ if (wasWifiConnected) {
+ // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION.
+ assertNotNull("Did not receive onLost callback after disabling wifi",
+ callback.waitForLost());
+ assertTrue("Wifi failed to reach DISCONNECTED state.", receiver.waitForState());
+ }
} catch (InterruptedException ex) {
fail("disconnectFromWifi was interrupted");
} finally {
@@ -225,8 +247,6 @@
mContext.unregisterReceiver(receiver);
}
- assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected);
-
// Check that the socket is closed when wifi disconnects.
if (wifiBoundSocket != null) {
try {
diff --git a/tests/tests/os/src/android/os/cts/FileObserverTest.java b/tests/tests/os/src/android/os/cts/FileObserverTest.java
index b853f89..9e61066 100644
--- a/tests/tests/os/src/android/os/cts/FileObserverTest.java
+++ b/tests/tests/os/src/android/os/cts/FileObserverTest.java
@@ -255,7 +255,7 @@
@AppModeFull(reason = "Instant apps cannot access external storage")
public void testFileObserverExternalStorageDirectory() throws Exception {
- helpTestFileObserver(Environment.getExternalStorageDirectory(), false);
+ helpTestFileObserver(Environment.getExternalStorageDirectory(), true);
}
@AppModeFull(reason = "Instant apps cannot access external storage")
@@ -264,7 +264,7 @@
Pair.create(getContext().getCacheDir(), false),
Pair.create(getContext().getFilesDir(), false),
Pair.create(getContext().getExternalFilesDir(null), true),
- Pair.create(Environment.getExternalStorageDirectory(), false)
+ Pair.create(Environment.getExternalStorageDirectory(), true)
);
}
diff --git a/tests/tests/packageinstaller/atomicinstall/AndroidManifest.xml b/tests/tests/packageinstaller/atomicinstall/AndroidManifest.xml
index 54d4260..1f8f283 100644
--- a/tests/tests/packageinstaller/atomicinstall/AndroidManifest.xml
+++ b/tests/tests/packageinstaller/atomicinstall/AndroidManifest.xml
@@ -17,7 +17,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tests.atomicinstall" >
- <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application>
<receiver android:name="com.android.cts.install.lib.LocalIntentSender"
android:exported="true" />
diff --git a/tests/tests/permission/src/android/permission/cts/BackgroundPermissionButtonLabelTest.java b/tests/tests/permission/src/android/permission/cts/BackgroundPermissionButtonLabelTest.java
index d4e1530..004f8bc 100644
--- a/tests/tests/permission/src/android/permission/cts/BackgroundPermissionButtonLabelTest.java
+++ b/tests/tests/permission/src/android/permission/cts/BackgroundPermissionButtonLabelTest.java
@@ -43,7 +43,6 @@
int stringId = permissionControllerContext.getResources().getIdentifier(
APP_PERMISSION_BUTTON_ALLOW_ALWAYS, "string",
"com.android.permissioncontroller");
-// mPermissionController); STOPSHIP b/147434671
Assert.assertEquals(mContext.getPackageManager().getBackgroundPermissionOptionLabel(),
permissionControllerContext.getString(stringId));
diff --git a/tests/tests/provider/src/android/provider/cts/media/MediaStore_FilesTest.java b/tests/tests/provider/src/android/provider/cts/media/MediaStore_FilesTest.java
index fde4b91..aa5b1be 100644
--- a/tests/tests/provider/src/android/provider/cts/media/MediaStore_FilesTest.java
+++ b/tests/tests/provider/src/android/provider/cts/media/MediaStore_FilesTest.java
@@ -63,6 +63,7 @@
private Context mContext;
private ContentResolver mResolver;
+ private Uri mExternalAudio;
private Uri mExternalImages;
private Uri mExternalFiles;
@@ -80,6 +81,7 @@
mResolver = mContext.getContentResolver();
Log.d(TAG, "Using volume " + mVolumeName);
+ mExternalAudio = MediaStore.Audio.Media.getContentUri(mVolumeName);
mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
mExternalFiles = MediaStore.Files.getContentUri(mVolumeName);
}
@@ -329,9 +331,9 @@
@Test
public void testInPlaceUpdate_mediaFileWithInvalidRelativePath() throws Exception {
final File file = new File(ProviderTestUtils.stageDownloadDir(mVolumeName),
- "test" + System.nanoTime() + ".jpg");
- ProviderTestUtils.stageFile(R.raw.scenery, file);
- Log.d(TAG, "Staged image file at " + file.getAbsolutePath());
+ "test" + System.nanoTime() + ".mp3");
+ ProviderTestUtils.stageFile(R.raw.testmp3, file);
+ Log.d(TAG, "Staged audio file at " + file.getAbsolutePath());
// Since file is created by shell, package name in MediaStore database row for this file
// will not be test app's package name. To treat the insert as upsert, package name in
@@ -342,19 +344,14 @@
final ContentValues insertValues = new ContentValues();
insertValues.put(MediaColumns.DATA, file.getAbsolutePath());
- insertValues.put(MediaStore.Images.ImageColumns.DESCRIPTION, "Not a cat photo");
- final Uri uri = mResolver.insert(mExternalImages, insertValues);
- assertEquals(0, queryLong(uri, MediaStore.Images.ImageColumns.IS_PRIVATE));
- assertStringColumn(uri, MediaStore.Images.ImageColumns.DESCRIPTION, "Not a cat photo");
+ insertValues.put(MediaStore.Audio.AudioColumns.BOOKMARK, 42L);
+ final Uri uri = mResolver.insert(mExternalAudio, insertValues);
+ assertEquals(42L, queryLong(uri, MediaStore.Audio.AudioColumns.BOOKMARK));
final ContentValues updateValues = new ContentValues();
- updateValues.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_IMAGE);
- updateValues.put(FileColumns.MIME_TYPE, "image/jpeg");
- updateValues.put(MediaStore.Images.ImageColumns.IS_PRIVATE, 1);
- int updateRows = mResolver.update(uri, updateValues, null, null);
- assertEquals(1, updateRows);
- // Only interested in update not throwing exception. No need in checking whenever values
- // were actually updates, as it is not in the scope of this test.
+ updateValues.put(MediaStore.Audio.AudioColumns.BOOKMARK, 43L);
+ assertEquals(1, mResolver.update(uri, updateValues, null, null));
+ assertEquals(43L, queryLong(uri, MediaStore.Audio.AudioColumns.BOOKMARK));
}
@Test
diff --git a/tests/tests/telephony/current/LocationAccessingApp/src/android/telephony/cts/locationaccessingapp/CtsLocationAccessService.java b/tests/tests/telephony/current/LocationAccessingApp/src/android/telephony/cts/locationaccessingapp/CtsLocationAccessService.java
index 861de55..0b9d9c3 100644
--- a/tests/tests/telephony/current/LocationAccessingApp/src/android/telephony/cts/locationaccessingapp/CtsLocationAccessService.java
+++ b/tests/tests/telephony/current/LocationAccessingApp/src/android/telephony/cts/locationaccessingapp/CtsLocationAccessService.java
@@ -48,6 +48,7 @@
"get_service_state_from_listener";
public static final String COMMAND_LISTEN_CELL_LOCATION = "listen_cell_location";
public static final String COMMAND_LISTEN_CELL_INFO = "listen_cell_info";
+ public static final String COMMAND_REQUEST_CELL_INFO_UPDATE = "request_cell_info_update";
private static final long LISTENER_TIMEOUT = 1000;
@@ -84,6 +85,8 @@
case COMMAND_LISTEN_CELL_LOCATION:
result = listenForCellLocation();
break;
+ case COMMAND_REQUEST_CELL_INFO_UPDATE:
+ result = requestCellInfoUpdate();
}
return Collections.singletonList(result);
}
@@ -171,4 +174,31 @@
handlerThread.quit();
}
}
+
+ private List<CellInfo> requestCellInfoUpdate() {
+ LinkedBlockingQueue<List<CellInfo>> queue = new LinkedBlockingQueue<>();
+ HandlerThread handlerThread = new HandlerThread("Telephony location CTS");
+ handlerThread.start();
+ Executor executor = new Handler(handlerThread.getLooper())::post;
+ TelephonyManager.CellInfoCallback cb = new TelephonyManager.CellInfoCallback() {
+ @Override
+ public void onCellInfo(List<CellInfo> cellInfo) {
+ queue.offer(cellInfo);
+ }
+ };
+
+ mTelephonyManager.requestCellInfoUpdate(executor, cb);
+
+ try {
+ List<CellInfo> ci = queue.poll(LISTENER_TIMEOUT, TimeUnit.MILLISECONDS);
+ if (ci == null) {
+ throw new RuntimeException("Timed out waiting for cell info");
+ }
+ return ci;
+ } catch (InterruptedException e) {
+ throw new RuntimeException("interrupted");
+ } finally {
+ handlerThread.quit();
+ }
+ }
}
diff --git a/tests/tests/telephony/current/permissions/src/android/telephony/cts/telephonypermission/TelephonyManagerReadPhoneStatePermissionTest.java b/tests/tests/telephony/current/permissions/src/android/telephony/cts/telephonypermission/TelephonyManagerReadPhoneStatePermissionTest.java
index 1d234d7..6bfb156 100644
--- a/tests/tests/telephony/current/permissions/src/android/telephony/cts/telephonypermission/TelephonyManagerReadPhoneStatePermissionTest.java
+++ b/tests/tests/telephony/current/permissions/src/android/telephony/cts/telephonypermission/TelephonyManagerReadPhoneStatePermissionTest.java
@@ -19,6 +19,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
+import android.app.UiAutomation;
import android.content.Context;
import android.content.pm.PackageManager;
import android.telephony.TelephonyManager;
@@ -48,6 +49,12 @@
assertNotNull(mTelephonyManager);
}
+ public static void grantUserReadPhoneStatePermission() {
+ UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+ uiAutomation.grantRuntimePermission(getContext().getPackageName(),
+ android.Manifest.permission.READ_PHONE_STATE);
+ }
+
/**
* Verify that TelephonyManager APIs requiring READ_PHONE_STATE Permission must work.
* <p>
@@ -64,6 +71,8 @@
return;
}
+ grantUserReadPhoneStatePermission();
+
try {
mTelephonyManager.getNetworkType();
} catch (SecurityException e) {
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SmsCbMessageTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsCbMessageTest.java
index e038fef..8b9eaaf 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/SmsCbMessageTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SmsCbMessageTest.java
@@ -298,6 +298,9 @@
doReturn(-1).when(cursor).getColumnIndex(eq(
Telephony.CellBroadcasts.ETWS_WARNING_TYPE));
+ doReturn(0).when(cursor).getColumnIndex(eq(
+ Telephony.CellBroadcasts.ETWS_IS_PRIMARY));
+
doReturn(-1).when(cursor).getColumnIndex(eq(
Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS));
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java
index 1c8e0c5..7b522f7 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java
@@ -13,6 +13,7 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
+import android.telephony.CellInfo;
import android.telephony.CellLocation;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
@@ -193,8 +194,25 @@
}
}, Manifest.permission.ACCESS_COARSE_LOCATION);
}, Manifest.permission.ACCESS_FINE_LOCATION);
-
}
+
+ @Test
+ public void testSdk28CellInfoUpdate() {
+ if (!mShouldTest) return;
+
+ // Verify that a target-sdk 28 app still requires fine location access
+ // to call requestCellInfoUpdate
+ withRevokedPermission(LOCATION_ACCESS_APP_SDK28_PACKAGE, () -> {
+ try {
+ List<CellInfo> cis = (List<CellInfo>) performLocationAccessCommandSdk28(
+ CtsLocationAccessService.COMMAND_REQUEST_CELL_INFO_UPDATE);
+ assertTrue(cis == null || cis.isEmpty());
+ } catch (SecurityException e) {
+ // expected
+ }
+ }, Manifest.permission.ACCESS_FINE_LOCATION);
+ }
+
private ICtsLocationAccessControl getLocationAccessAppControl() {
Intent bindIntent = new Intent(CtsLocationAccessService.CONTROL_ACTION);
bindIntent.setComponent(new ComponentName(
diff --git a/tests/tests/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/tests/tethering/src/android/tethering/cts/TetheringManagerTest.java
index 1055531..f7160dd 100644
--- a/tests/tests/tethering/src/android/tethering/cts/TetheringManagerTest.java
+++ b/tests/tests/tethering/src/android/tethering/cts/TetheringManagerTest.java
@@ -286,8 +286,9 @@
assertTrue(tetheredIfaces.length == 0);
final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
- mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(),
- c -> c.run() /* executor */, startTetheringCallback);
+ final TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
+ .setShouldShowEntitlementUi(false).build();
+ mTM.startTethering(request, c -> c.run() /* executor */, startTetheringCallback);
startTetheringCallback.verifyTetheringStarted();
mTetherChangeReceiver.expectTethering(true /* active */, wifiRegexs);
@@ -529,8 +530,9 @@
assertFalse(isIfaceMatch(wifiRegexs, callback.getTetheredInterfaces()));
final StartTetheringCallback startTetheringCallback = new StartTetheringCallback();
- mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(),
- c -> c.run() /* executor */, startTetheringCallback);
+ final TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
+ .setShouldShowEntitlementUi(false).build();
+ mTM.startTethering(request, c -> c.run() /* executor */, startTetheringCallback);
startTetheringCallback.verifyTetheringStarted();
callback.expectTetheredInterfacesChanged(wifiRegexs);
diff --git a/tests/tests/util/AndroidManifest.xml b/tests/tests/util/AndroidManifest.xml
index 3d402d5..77ab380 100644
--- a/tests/tests/util/AndroidManifest.xml
+++ b/tests/tests/util/AndroidManifest.xml
@@ -18,12 +18,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.util.cts">
- <queries>
- <package android:name="com.android.cts.install.lib.testapp.A" />
- <package android:name="com.android.cts.install.lib.testapp.B" />
- <package android:name="com.android.cts.install.lib.testapp.C" />
- </queries>
-
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.READ_LOGS" />
<application>
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
index 7670a52..59aa5c0 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
@@ -21,6 +21,13 @@
import static com.google.common.truth.Truth.assertThat;
+import static junit.framework.TestCase.assertFalse;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
import android.app.UiAutomation;
import android.content.Context;
import android.net.ConnectivityManager;
@@ -40,15 +47,23 @@
import android.os.WorkSource;
import android.platform.test.annotations.AppModeFull;
import android.support.test.uiautomator.UiDevice;
-import android.test.AndroidTestCase;
import android.text.TextUtils;
+import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
import com.android.compatibility.common.util.PollingCheck;
import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.compatibility.common.util.SystemUtil;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.util.List;
import java.util.concurrent.Executors;
@@ -61,9 +76,15 @@
* TODO(b/150716005): Use assumeTrue for wifi support check.
*/
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-public class WifiNetworkSpecifierTest extends AndroidTestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class WifiNetworkSpecifierTest {
private static final String TAG = "WifiNetworkSpecifierTest";
+ private static boolean sWasVerboseLoggingEnabled;
+ private static boolean sWasScanThrottleEnabled;
+
+ private Context mContext;
private WifiManager mWifiManager;
private ConnectivityManager mConnectivityManager;
private UiDevice mUiDevice;
@@ -71,8 +92,6 @@
private final Object mUiLock = new Object();
private WifiConfiguration mTestNetwork;
private TestNetworkCallback mNetworkCallback;
- private boolean mWasVerboseLoggingEnabled;
- private boolean mWasScanThrottleEnabled;
private static final int DURATION = 10_000;
private static final int DURATION_UI_INTERACTION = 25_000;
@@ -80,77 +99,100 @@
private static final int DURATION_SCREEN_TOGGLE = 2000;
private static final int SCAN_RETRY_CNT_TO_FIND_MATCHING_BSSID = 3;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- if (!WifiFeature.isWifiSupported(getContext())) {
- // skip the test if WiFi is not supported
- return;
- }
- mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
- mConnectivityManager = getContext().getSystemService(ConnectivityManager.class);
- assertNotNull(mWifiManager);
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ // skip the test if WiFi is not supported
+ assumeTrue(WifiFeature.isWifiSupported(context));
+
+ WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ assertNotNull(wifiManager);
// turn on verbose logging for tests
- mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions(
- () -> mWifiManager.isVerboseLoggingEnabled());
+ sWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions(
+ () -> wifiManager.isVerboseLoggingEnabled());
ShellIdentityUtils.invokeWithShellPermissions(
- () -> mWifiManager.setVerboseLoggingEnabled(true));
+ () -> wifiManager.setVerboseLoggingEnabled(true));
// Disable scan throttling for tests.
- mWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions(
- () -> mWifiManager.isScanThrottleEnabled());
+ sWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions(
+ () -> wifiManager.isScanThrottleEnabled());
ShellIdentityUtils.invokeWithShellPermissions(
- () -> mWifiManager.setScanThrottleEnabled(false));
+ () -> wifiManager.setScanThrottleEnabled(false));
// enable Wifi
- if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true);
- PollingCheck.check("Wifi not enabled", DURATION, () -> mWifiManager.isWifiEnabled());
-
- // turn screen on
- mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
- turnScreenOn();
+ if (!wifiManager.isWifiEnabled()) setWifiEnabled(true);
+ PollingCheck.check("Wifi not enabled", DURATION, () -> wifiManager.isWifiEnabled());
// check we have >= 1 saved network
List<WifiConfiguration> savedNetworks = ShellIdentityUtils.invokeWithShellPermissions(
- () -> mWifiManager.getPrivilegedConfiguredNetworks());
+ () -> wifiManager.getPrivilegedConfiguredNetworks());
assertFalse("Need at least one saved network", savedNetworks.isEmpty());
- // Pick any one of the saved networks on the device (assumes that it is in range)
- mTestNetwork = savedNetworks.get(0);
// Disconnect & disable auto-join on the saved network to prevent auto-connect from
// interfering with the test.
ShellIdentityUtils.invokeWithShellPermissions(
- () -> mWifiManager.disableNetwork(mTestNetwork.networkId));
- // wait for Wifi to be disconnected
+ () -> {
+ for (WifiConfiguration savedNetwork : savedNetworks) {
+ wifiManager.disableNetwork(savedNetwork.networkId);
+ }
+ });
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ if (!WifiFeature.isWifiSupported(context)) return;
+
+ WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ assertNotNull(wifiManager);
+
+ if (!wifiManager.isWifiEnabled()) setWifiEnabled(true);
+
+ // Re-enable networks.
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> {
+ for (WifiConfiguration savedNetwork : wifiManager.getConfiguredNetworks()) {
+ wifiManager.enableNetwork(savedNetwork.networkId, false);
+ }
+ });
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> wifiManager.setScanThrottleEnabled(sWasScanThrottleEnabled));
+ ShellIdentityUtils.invokeWithShellPermissions(
+ () -> wifiManager.setVerboseLoggingEnabled(sWasVerboseLoggingEnabled));
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getInstrumentation().getContext();
+ mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+ mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
+ mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+
+ // turn screen on
+ turnScreenOn();
+
+ List<WifiConfiguration> savedNetworks = ShellIdentityUtils.invokeWithShellPermissions(
+ () -> mWifiManager.getPrivilegedConfiguredNetworks());
+ // Pick any one of the saved networks on the device (assumes that it is in range)
+ mTestNetwork = savedNetworks.get(0);
+
+ // Wait for Wifi to be disconnected.
PollingCheck.check(
"Wifi not disconnected",
20000,
() -> mWifiManager.getConnectionInfo().getNetworkId() == -1);
}
- @Override
- protected void tearDown() throws Exception {
- if (!WifiFeature.isWifiSupported(getContext())) {
- // skip the test if WiFi is not supported
- super.tearDown();
- return;
- }
- if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true);
- turnScreenOff();
+ @After
+ public void tearDown() throws Exception {
// If there is failure, ensure we unregister the previous request.
if (mNetworkCallback != null) {
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
}
- ShellIdentityUtils.invokeWithShellPermissions(
- () -> mWifiManager.enableNetwork(mTestNetwork.networkId, true));
- ShellIdentityUtils.invokeWithShellPermissions(
- () -> mWifiManager.setScanThrottleEnabled(mWasScanThrottleEnabled));
- ShellIdentityUtils.invokeWithShellPermissions(
- () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
- super.tearDown();
+ turnScreenOff();
}
- private void setWifiEnabled(boolean enable) throws Exception {
+ private static void setWifiEnabled(boolean enable) throws Exception {
// now trigger the change using shell commands.
SystemUtil.runShellCommand("svc wifi " + (enable ? "enable" : "disable"));
}
@@ -398,11 +440,8 @@
/**
* Tests the entire connection flow using a specific SSID in the specifier.
*/
+ @Test
public void testConnectionWithSpecificSsid() {
- if (!WifiFeature.isWifiSupported(getContext())) {
- // skip the test if WiFi is not supported
- return;
- }
WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork()
.setSsid(removeDoubleQuotes(mTestNetwork.SSID))
.build();
@@ -412,11 +451,8 @@
/**
* Tests the entire connection flow using a SSID pattern in the specifier.
*/
+ @Test
public void testConnectionWithSsidPattern() {
- if (!WifiFeature.isWifiSupported(getContext())) {
- // skip the test if WiFi is not supported
- return;
- }
// Creates a ssid pattern by dropping the last char in the saved network & pass that
// as a prefix match pattern in the request.
String ssidUnquoted = removeDoubleQuotes(mTestNetwork.SSID);
@@ -486,11 +522,8 @@
/**
* Tests the entire connection flow using a specific BSSID in the specifier.
*/
+ @Test
public void testConnectionWithSpecificBssid() {
- if (!WifiFeature.isWifiSupported(getContext())) {
- // skip the test if WiFi is not supported
- return;
- }
ScanResult scanResult = findScanResultMatchingSavedNetwork();
WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork()
.setBssid(MacAddress.fromString(scanResult.BSSID))
@@ -501,11 +534,8 @@
/**
* Tests the entire connection flow using a BSSID pattern in the specifier.
*/
+ @Test
public void testConnectionWithBssidPattern() {
- if (!WifiFeature.isWifiSupported(getContext())) {
- // skip the test if WiFi is not supported
- return;
- }
ScanResult scanResult = findScanResultMatchingSavedNetwork();
// Note: The match may return more than 1 network in this case since we use a prefix match,
// But, we will still ensure that the UI interactions in the test still selects the
@@ -520,11 +550,8 @@
/**
* Tests the entire connection flow using a BSSID pattern in the specifier.
*/
+ @Test
public void testUserRejectionWithSpecificSsid() {
- if (!WifiFeature.isWifiSupported(getContext())) {
- // skip the test if WiFi is not supported
- return;
- }
WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork()
.setSsid(removeDoubleQuotes(mTestNetwork.SSID))
.build();
@@ -535,11 +562,8 @@
* Tests the builder for WPA2 enterprise networks.
* Note: Can't do end to end tests for such networks in CTS environment.
*/
+ @Test
public void testBuilderForWpa2Enterprise() {
- if (!WifiFeature.isWifiSupported(getContext())) {
- // skip the test if WiFi is not supported
- return;
- }
WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder()
.setSsid(removeDoubleQuotes(mTestNetwork.SSID))
.setWpa2EnterpriseConfig(new WifiEnterpriseConfig())
@@ -555,11 +579,8 @@
* Tests the builder for WPA3 enterprise networks.
* Note: Can't do end to end tests for such networks in CTS environment.
*/
+ @Test
public void testBuilderForWpa3Enterprise() {
- if (!WifiFeature.isWifiSupported(getContext())) {
- // skip the test if WiFi is not supported
- return;
- }
WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder()
.setSsid(removeDoubleQuotes(mTestNetwork.SSID))
.setWpa3EnterpriseConfig(new WifiEnterpriseConfig())