summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-08-16 23:34:31 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-08-16 23:34:31 +0000
commit53ae555db9685bd90a2e874e0a4e8240d16696c7 (patch)
tree06369ee203c8692af2c702187bf3016dac5d6f01
parent5c33f8c6a50990cb4f6b20276d3982cac06225d5 (diff)
parent7efde2e8096d0bfaa978a212d0f6a84046492eab (diff)
downloadcts-53ae555db9685bd90a2e874e0a4e8240d16696c7.tar.gz
Snap for 7647318 from 7efde2e8096d0bfaa978a212d0f6a84046492eab to sc-mainline-release
Change-Id: I676e399cf137d542db983980ba32294b7c9b5c27
-rw-r--r--hostsidetests/security/src/android/security/cts/ProcessMustUseSeccompTest.java3
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2019-2178/Android.bp41
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2019-2178/poc.cpp92
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-0072/Android.bp1
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-0072/poc.cpp10
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-0420/Android.bp30
-rw-r--r--hostsidetests/securitybulletin/securityPatch/CVE-2020-0420/poc.cpp59
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java52
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2178.java41
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0072.java1
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0420.java38
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0478.java71
-rw-r--r--hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java43
-rw-r--r--hostsidetests/securitybulletin/test-apps/BUG-183963253/Android.bp31
-rw-r--r--hostsidetests/securitybulletin/test-apps/BUG-183963253/AndroidManifest.xml49
-rw-r--r--hostsidetests/securitybulletin/test-apps/BUG-183963253/res/layout/activity_main.xml27
-rw-r--r--hostsidetests/securitybulletin/test-apps/BUG-183963253/res/values/strings.xml21
-rw-r--r--hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/Constants.java25
-rw-r--r--hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/DeviceTest.java121
-rw-r--r--hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/MainActivity.java85
-rw-r--r--hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/OverlayService.java95
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0478/Android.bp33
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0478/AndroidManifest.xml44
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0478/res/layout/activity_main.xml26
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0478/res/raw/image.jpgbin0 -> 5579267 bytes
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0478/src/android/security/cts/CVE_2021_0478/PocActivity.java72
-rw-r--r--hostsidetests/securitybulletin/test-apps/CVE-2021-0478/src/android/security/cts/CVE_2021_0478/PocService.java64
-rw-r--r--hostsidetests/stagedinstall/Android.bp42
-rw-r--r--hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/ApexShimValidationTest.java58
-rw-r--r--hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java173
-rw-r--r--hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/ApexShimValidationTest.java25
-rw-r--r--hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java147
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/activities/SimpleSaveActivity.java10
-rw-r--r--tests/autofillservice/src/android/autofillservice/cts/inline/InlineSimpleSaveActivityTest.java12
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/CameraExtensionSessionTest.java18
-rw-r--r--tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java124
-rw-r--r--tests/framework/base/windowmanager/appProfileable/src/android/server/wm/profileable/ProfileableAppActivity.java9
-rw-r--r--tests/inputmethod/src/android/view/inputmethod/cts/InputMethodManagerTest.java9
-rw-r--r--tests/sensor/src/android/hardware/cts/helpers/SensorCtsHelper.java2
-rw-r--r--tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java6
-rw-r--r--tests/tests/graphics/src/android/graphics/cts/OpenGlEsDeqpLevelTest.java2
-rw-r--r--tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java2
-rw-r--r--tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTestImpl.java3
-rw-r--r--tests/tests/media/src/android/media/cts/MediaCodecTest.java11
-rw-r--r--tests/tests/security/res/raw/cve_2021_0635_1.flvbin0 -> 2272911 bytes
-rw-r--r--tests/tests/security/res/raw/cve_2021_0635_2.flvbin0 -> 510492 bytes
-rw-r--r--tests/tests/security/src/android/security/cts/CVE_2021_0521.java91
-rw-r--r--tests/tests/security/src/android/security/cts/StagefrightTest.java7
-rw-r--r--tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt3
49 files changed, 1854 insertions, 75 deletions
diff --git a/hostsidetests/security/src/android/security/cts/ProcessMustUseSeccompTest.java b/hostsidetests/security/src/android/security/cts/ProcessMustUseSeccompTest.java
index e6704267d9b..c6ea1b88fb2 100644
--- a/hostsidetests/security/src/android/security/cts/ProcessMustUseSeccompTest.java
+++ b/hostsidetests/security/src/android/security/cts/ProcessMustUseSeccompTest.java
@@ -136,6 +136,7 @@ public class ProcessMustUseSeccompTest extends DeviceTestCase {
}
public void testOmxHalHasSeccompFilter() throws DeviceNotAvailableException {
- assertSeccompFilter("media.codec", PS_CMD, false);
+ // 64bit only devices don't have 32bit only media.codec (omx)
+ assertSeccompFilter("media.codec", PS_CMD, false, false /* mustHaveProcess */);
}
}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2178/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2178/Android.bp
new file mode 100644
index 00000000000..a4d2d24ca51
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2178/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2178",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ "libchrome",
+ "libbase",
+ "liblog",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2178/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2178/poc.cpp
new file mode 100644
index 00000000000..dc057b856dc
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2178/poc.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+#include <log/log.h>
+#include <nfc_api.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <tags_defs.h>
+
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+void rw_init(void);
+tNFC_STATUS rw_t4t_select(void);
+void GKI_freebuf(void* x) { (void)x; }
+
+// borrowed from rw_t4t.cc
+/* main state */
+#define RW_T4T_STATE_READ_NDEF 0x03
+/* sub state */
+#define RW_T4T_SUBSTATE_WAIT_READ_RESP 0x05
+
+void GKI_start_timer(uint8_t, int32_t, bool) {}
+void GKI_stop_timer(uint8_t) {}
+
+void poc_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
+ (void)event;
+ (void)p_rw_data;
+}
+
+int main() {
+ tNFC_ACTIVATE_DEVT p_activate_params = {};
+ p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+ p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+ RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+ if (rw_cb.p_cback != &poc_cback) {
+ ALOGE("Structure tRW_CB mismatch rw_cb.p_cback=%p poc_cback=%p\n", rw_cb.p_cback,
+ poc_cback);
+ return EXIT_FAILURE;
+ }
+ tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+ GKI_init();
+ rw_init();
+
+ if ((rw_t4t_select()) != NFC_STATUS_OK) {
+ return EXIT_FAILURE;
+ }
+
+ tNFC_CONN* p_data = (tNFC_CONN*)malloc(sizeof(tNFC_CONN));
+ if (!p_data) {
+ return EXIT_FAILURE;
+ }
+ p_data->data.p_data = (NFC_HDR*)malloc(sizeof(uint8_t) * 16);
+ if (!(p_data->data.p_data)) {
+ free(p_data);
+ return EXIT_FAILURE;
+ }
+ p_data->status = NFC_STATUS_OK;
+
+ p_t4t->state = RW_T4T_STATE_READ_NDEF;
+ p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_READ_RESP;
+
+ NFC_HDR* p_r_apdu = (NFC_HDR*)p_data->data.p_data;
+ p_r_apdu->offset = 8;
+ p_r_apdu->len = 1;
+
+ tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ tNFC_CONN_EVT event = NFC_DATA_CEVT;
+
+ p_cb->p_cback(0, event, p_data);
+
+ free(p_data->data.p_data);
+ free(p_data);
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0072/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0072/Android.bp
index 65407ddc572..dad32cdbf2f 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0072/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0072/Android.bp
@@ -28,6 +28,7 @@ cc_test {
compile_multilib: "64",
shared_libs: [
"libnfc-nci",
+ "liblog",
],
include_dirs: [
"system/nfc/src/nfc/include",
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0072/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0072/poc.cpp
index 048c6c78cec..24f55610e74 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0072/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0072/poc.cpp
@@ -15,6 +15,7 @@
*/
#include "../includes/common.h"
+#include <log/log.h>
#include <stdlib.h>
#include <nfc_api.h>
@@ -32,6 +33,15 @@ void poc_cback(tRW_EVENT event, tRW_DATA *p_rw_data) {
}
int main() {
+ tNFC_ACTIVATE_DEVT p_activate_params = {};
+ p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
+ p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
+ RW_SetActivatedTagType(&p_activate_params, &poc_cback);
+ if (rw_cb.p_cback != &poc_cback) {
+ ALOGE("Structure tRW_CB mismatch rw_cb.p_cback=%p poc_cback=%p\n",
+ rw_cb.p_cback, poc_cback);
+ return EXIT_FAILURE;
+ }
tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
rw_init();
rw_cb.p_cback = &poc_cback;
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0420/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0420/Android.bp
new file mode 100644
index 00000000000..b4078aeda54
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0420/Android.bp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0420",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ shared_libs: [
+ "libutils",
+ "libbinder",
+ "libmedia",
+ "liblog",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0420/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0420/poc.cpp
new file mode 100644
index 00000000000..426c6d25e84
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0420/poc.cpp
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "../includes/common.h"
+#include <binder/IServiceManager.h>
+#include <binder/Parcel.h>
+#include <stdio.h>
+
+using namespace android;
+
+int main(void) {
+ status_t err;
+ sp<IServiceManager> sm = defaultServiceManager();
+ String16 name(String16("gpu"));
+ sp<IBinder> service = sm->checkService(name);
+ String16 interface_name = service->getInterfaceDescriptor();
+
+ Parcel data, reply;
+ std::string UpdatableDriverPath("CVE-2020-0420");
+ data.writeInterfaceToken(interface_name);
+ data.writeUtf8AsUtf16(UpdatableDriverPath);
+ err = service->transact(3 /*SET_UPDATABLE_DRIVER_PATH,*/, data, &reply, 0);
+ if (err != OK) {
+ return EXIT_FAILURE;
+ }
+
+ Parcel data1, reply1;
+ data1.writeInterfaceToken(interface_name);
+ err = service->transact(4 /*GET_UPDATABLE_DRIVER_PATH,*/, data1, &reply1, 0);
+ if (err != OK) {
+ return EXIT_FAILURE;
+ }
+ std::string driverPath;
+ err = reply1.readUtf8FromUtf16(&driverPath);
+ if (err != OK) {
+ return EXIT_FAILURE;
+ }
+
+ /** If the driver path returned is same as that was set, then there is no
+ * check in the API and the vulnerability is present.
+ */
+ if (0 == strcmp(driverPath.c_str(), UpdatableDriverPath.c_str())) {
+ return EXIT_VULNERABLE;
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java
new file mode 100644
index 00000000000..e31cb479c0e
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import static org.junit.Assert.assertTrue;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import org.junit.Test;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public final class Bug_183963253 extends BaseHostJUnit4Test {
+ private static final String TEST_PKG = "android.security.cts.BUG_183963253";
+ private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+ private static final String TEST_APP = "BUG-183963253.apk";
+
+ @Before
+ public void setUp() throws Exception {
+ uninstallPackage(getDevice(), TEST_PKG);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 183963253)
+ public void testRunDeviceTestsPassesFull() throws Exception {
+ installPackage(TEST_APP);
+
+ // Grant permission to draw overlays.
+ getDevice().executeShellCommand(
+ "pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW");
+
+ assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testTapjacking"));
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2178.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2178.java
new file mode 100644
index 00000000000..223e7684b1c
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2178.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+import android.platform.test.annotations.SecurityTest;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2178 extends SecurityTestCase {
+
+ /**
+ * b/124462242
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @AsbSecurityTest(cveBugId = 124462242)
+ @SecurityTest(minPatchLevel = "2019-09")
+ @Test
+ public void testPocCVE_2019_2178() throws Exception {
+ AdbUtils.assumeHasNfc(getDevice());
+ assumeIsSupportedNfcDevice(getDevice());
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2178", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0072.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0072.java
index 6133a871c74..7c00d842659 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0072.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0072.java
@@ -32,6 +32,7 @@ public class CVE_2020_0072 extends SecurityTestCase {
@AsbSecurityTest(cveBugId = 147310271)
public void testPocCVE_2020_0072() throws Exception {
AdbUtils.assumeHasNfc(getDevice());
+ assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig("CVE-2020-0072", getDevice());
testConfig.checkCrash = false;
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0420.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0420.java
new file mode 100644
index 00000000000..bff13f3d28e
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0420.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+import android.platform.test.annotations.SecurityTest;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0420 extends SecurityTestCase {
+
+ /**
+ * b/162383705
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @AsbSecurityTest(cveBugId = 162383705)
+ @SecurityTest(minPatchLevel = "2020-10")
+ @Test
+ public void testPocCVE_2020_0420() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0420", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0478.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0478.java
new file mode 100644
index 00000000000..a3b1eae7c67
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0478.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+import android.platform.test.annotations.SecurityTest;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0478 extends SecurityTestCase {
+
+ /**
+ * b/169255797
+ */
+ @AsbSecurityTest(cveBugId = 169255797)
+ @SecurityTest(minPatchLevel = "2021-06")
+ @Test
+ public void testPocCVE_2021_0478() throws Exception {
+ final int SLEEP_INTERVAL_MILLISEC = 30 * 1000;
+ String apkName = "CVE-2021-0478.apk";
+ String appPath = AdbUtils.TMP_PATH + apkName;
+ String packageName = "android.security.cts.cve_2021_0478";
+ String crashPattern = "Canvas: trying to draw too large";
+ ITestDevice device = getDevice();
+
+ try {
+ /* Push the app to /data/local/tmp */
+ pocPusher.appendBitness(false);
+ pocPusher.pushFile(apkName, appPath);
+
+ /* Wake up the screen */
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+ /* Install the application */
+ AdbUtils.runCommandLine("pm install " + appPath, device);
+
+ /* Start the application */
+ AdbUtils.runCommandLine("am start -n " + packageName + "/.PocActivity", getDevice());
+ Thread.sleep(SLEEP_INTERVAL_MILLISEC);
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ /* Un-install the app after the test */
+ AdbUtils.runCommandLine("pm uninstall " + packageName, device);
+
+ /* Check if System UI has crashed thereby indicating the presence */
+ /* of the vulnerability */
+ String logcat = AdbUtils.runCommandLine("logcat -d *:S AndroidRuntime:E", device);
+ assertNotMatches(crashPattern, logcat);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
index d6430844e4a..0353c3d6de6 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
@@ -47,6 +47,7 @@ import java.math.BigInteger;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
+import static org.hamcrest.core.Is.is;
public class SecurityTestCase extends BaseHostJUnit4Test {
@@ -226,9 +227,17 @@ public class SecurityTestCase extends BaseHostJUnit4Test {
}
/**
- * Check if a driver is present on a machine.
+ * Check if a driver is present and readable.
*/
protected boolean containsDriver(ITestDevice device, String driver) throws Exception {
+ return containsDriver(device, driver, true);
+ }
+
+ /**
+ * Check if a driver is present on a machine.
+ */
+ protected boolean containsDriver(ITestDevice device, String driver, boolean checkReadable)
+ throws Exception {
boolean containsDriver = false;
if (driver.contains("*")) {
// -A list all files but . and ..
@@ -239,11 +248,15 @@ public class SecurityTestCase extends BaseHostJUnit4Test {
if (AdbUtils.runCommandGetExitCode(ls, device) == 0) {
String[] expanded = device.executeShellCommand(ls).split("\\R");
for (String expandedDriver : expanded) {
- containsDriver |= containsDriver(device, expandedDriver);
+ containsDriver |= containsDriver(device, expandedDriver, checkReadable);
}
}
} else {
- containsDriver = AdbUtils.runCommandGetExitCode("test -r " + driver, device) == 0;
+ if(checkReadable) {
+ containsDriver = AdbUtils.runCommandGetExitCode("test -r " + driver, device) == 0;
+ } else {
+ containsDriver = AdbUtils.runCommandGetExitCode("test -e " + driver, device) == 0;
+ }
}
MetricsReportLog reportLog = buildMetricsReportLog(getDevice());
@@ -322,4 +335,28 @@ public class SecurityTestCase extends BaseHostJUnit4Test {
boolean moduleIsPlayManaged(String modulePackageName) throws Exception {
return mainlineModuleDetector.getPlayManagedModules().contains(modulePackageName);
}
+
+ public void assumeIsSupportedNfcDevice(ITestDevice device) throws Exception {
+ String supportedDrivers[] = { "/dev/nq-nci*", "/dev/pn54*", "/dev/pn551*", "/dev/pn553*",
+ "/dev/pn557*", "/dev/pn65*", "/dev/pn66*", "/dev/pn67*",
+ "/dev/pn80*", "/dev/pn81*", "/dev/sn100*", "/dev/sn220*",
+ "/dev/st54j*" };
+ boolean isDriverFound = false;
+ for(String supportedDriver : supportedDrivers) {
+ if(containsDriver(device, supportedDriver, false)) {
+ isDriverFound = true;
+ break;
+ }
+ }
+ String[] output = device.executeShellCommand("ls -la /dev | grep nfc").split("\\n");
+ String nfcDevice = null;
+ for (String line : output) {
+ if(line.contains("nfc")) {
+ String text[] = line.split("\\s+");
+ nfcDevice = text[text.length - 1];
+ }
+ }
+ assumeTrue("NFC device " + nfcDevice + " is not supported. Hence skipping the test",
+ isDriverFound);
+ }
}
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-183963253/Android.bp b/hostsidetests/securitybulletin/test-apps/BUG-183963253/Android.bp
new file mode 100644
index 00000000000..63ac1cae84e
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-183963253/Android.bp
@@ -0,0 +1,31 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test_helper_app {
+ name: "BUG-183963253",
+ defaults: ["cts_support_defaults"],
+ srcs: ["src/**/*.java"],
+ test_suites: [
+ "cts",
+ "vts10",
+ "sts",
+ ],
+ static_libs: [
+ "androidx.appcompat_appcompat",
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ "androidx.test.core",
+ ],
+ sdk_version: "current",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-183963253/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/BUG-183963253/AndroidManifest.xml
new file mode 100644
index 00000000000..148fc7eced5
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-183963253/AndroidManifest.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.BUG_183963253"
+ android:targetSandboxVersion="2">
+
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+ <application android:theme="@style/Theme.AppCompat.Light">
+ <uses-library android:name="android.test.runner" />
+ <service android:name=".OverlayService"
+ android:enabled="true"
+ android:exported="false" />
+
+ <activity
+ android:name=".MainActivity"
+ android:label="ST (Permission)"
+ android:exported="true"
+ android:taskAffinity="android.security.cts.BUG_183963253.MainActivity">
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.BUG_183963253" />
+
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-183963253/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/BUG-183963253/res/layout/activity_main.xml
new file mode 100644
index 00000000000..0ac0cf489f4
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-183963253/res/layout/activity_main.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="left"
+ tools:context=".MainActivity" >
+
+ <LinearLayout
+ android:id="@+id/linearLayout1"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/seekShowTimes"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="53dp"
+ android:orientation="horizontal" >
+
+ <Button
+ android:id="@+id/btnStart"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Start" />
+
+ </LinearLayout>
+
+</RelativeLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-183963253/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/BUG-183963253/res/values/strings.xml
new file mode 100644
index 00000000000..c36354599e3
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-183963253/res/values/strings.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<resources>
+ <string name="app_name">BUG_183963253</string>
+ <string name="app_description">This is an overlay-activity</string>
+ <string name="tapjacking_text">BUG_183963253 overlay text</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/Constants.java b/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/Constants.java
new file mode 100644
index 00000000000..6856fc45f8c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/Constants.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.BUG_183963253;
+
+final class Constants {
+
+ public static final String LOG_TAG = "BUG-183963253";
+ public static final String TEST_APP_PACKAGE = Constants.class.getPackage().getName();
+
+ public static final String ACTION_START_TAPJACKING = "BUG_183963253.start_tapjacking";
+}
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/DeviceTest.java
new file mode 100644
index 00000000000..108eaf88ccd
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/DeviceTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.BUG_183963253;
+
+import static android.security.cts.BUG_183963253.Constants.LOG_TAG;
+
+import org.junit.Before;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.util.Log;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+
+/** Basic sample for unbundled UiAutomator. */
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ private static final long WAIT_FOR_UI_TIMEOUT = 10_000;
+
+ private Context mContext;
+ private UiDevice mDevice;
+
+ @Before
+ public void setUp() throws Exception {
+ Log.d(LOG_TAG, "startMainActivityFromHomeScreen()");
+
+ mContext = getApplicationContext();
+
+ // If the permission is not granted, the app will show up in the Usage Access Settings.
+ // This is required for the test below.
+ // NOTE: The permission is granted by the HostJUnit4Test implementation and should not fail.
+ assertEquals("Permission PACKAGE_USAGE_STATS not granted!",
+ mContext.checkSelfPermission("android.permission.PACKAGE_USAGE_STATS"),
+ PackageManager.PERMISSION_GRANTED);
+
+ // Initialize UiDevice instance
+ mDevice = UiDevice.getInstance(getInstrumentation());
+ if (!mDevice.isScreenOn()) {
+ mDevice.wakeUp();
+ }
+ mDevice.pressHome();
+ }
+
+ @Test
+ public void testTapjacking() throws InterruptedException {
+ Log.d(LOG_TAG, "Starting tap-jacking test");
+
+ launchTestApp();
+
+ launchTapjackedActivity();
+
+ mContext.sendBroadcast(new Intent(Constants.ACTION_START_TAPJACKING));
+ Log.d(LOG_TAG, "Sent intent to start tap-jacking!");
+
+ UiObject2 overlay = waitForView(By.text("BUG_183963253 overlay text"));
+ assertNull("Tap-jacking successful. Overlay was displayed.!", overlay);
+ }
+
+ @After
+ public void tearDown() {
+ mDevice.pressHome();
+ }
+
+ private void launchTestApp() {
+ Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(
+ Constants.TEST_APP_PACKAGE);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ mContext.startActivity(intent);
+
+ // Wait for the app to appear
+ UiObject2 view = waitForView(By.pkg(Constants.TEST_APP_PACKAGE).depth(0));
+ assertNotNull("test-app did not appear!", view);
+ Log.d(LOG_TAG, "test-app appeared");
+ }
+
+ private void launchTapjackedActivity() {
+ Intent intent = new Intent();
+ intent.setAction("android.settings.USAGE_ACCESS_SETTINGS");
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+
+ UiObject2 view = waitForView(By.text(Constants.TEST_APP_PACKAGE));
+ assertNotNull("Activity under-test was not launched or found!", view);
+ Log.d(LOG_TAG, "Started Activity under-test.");
+ }
+
+ private UiObject2 waitForView(BySelector selector) {
+ return mDevice.wait(Until.findObject(selector), WAIT_FOR_UI_TIMEOUT);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/MainActivity.java b/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/MainActivity.java
new file mode 100644
index 00000000000..597423dc730
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/MainActivity.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.security.cts.BUG_183963253;
+
+import static android.security.cts.BUG_183963253.Constants.LOG_TAG;
+
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.WindowManager.LayoutParams;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+
+import java.util.ArrayList;
+
+/** Main activity for the test-app. */
+public final class MainActivity extends AppCompatActivity {
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ startTapjacking();
+ }
+ };
+
+ private Button btnStart;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ registerReceiver(mReceiver, new IntentFilter(Constants.ACTION_START_TAPJACKING));
+
+ btnStart = (Button) findViewById(R.id.btnStart);
+ btnStart.setOnClickListener(v -> startTapjacking());
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ unregisterReceiver(mReceiver);
+ stopOverlayService();
+ }
+
+ public void startTapjacking() {
+ Log.d(LOG_TAG, "Starting tap-jacking flow.");
+ stopOverlayService();
+
+ startOverlayService();
+ Log.d(LOG_TAG, "Started overlay-service.");
+ }
+
+ private void startOverlayService() {
+ startService(new Intent(getApplicationContext(), OverlayService.class));
+ }
+
+ private void stopOverlayService() {
+ stopService(new Intent(getApplicationContext(), OverlayService.class));
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/OverlayService.java b/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/OverlayService.java
new file mode 100644
index 00000000000..ec21f0bf4e9
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-183963253/src/android/security/cts/BUG_183963253/OverlayService.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.BUG_183963253;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.provider.Settings;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.WindowManager;
+import android.widget.Button;
+
+/** Service that starts the overlay for the test. */
+public final class OverlayService extends Service {
+ public Button mButton;
+ private WindowManager mWindowManager;
+ private WindowManager.LayoutParams mLayoutParams;
+
+ @Override
+ public void onCreate() {
+ Log.d(Constants.LOG_TAG, "onCreate() called");
+ super.onCreate();
+
+ DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
+ int scaledWidth = (int) (displayMetrics.widthPixels * 0.9);
+ int scaledHeight = (int) (displayMetrics.heightPixels * 0.9);
+
+ mWindowManager = getSystemService(WindowManager.class);
+ mLayoutParams = new WindowManager.LayoutParams();
+ mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+ mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+ mLayoutParams.format = PixelFormat.OPAQUE;
+ mLayoutParams.gravity = Gravity.CENTER;
+ mLayoutParams.width = scaledWidth;
+ mLayoutParams.height = scaledHeight;
+ mLayoutParams.x = scaledWidth / 2;
+ mLayoutParams.y = scaledHeight / 2;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Log.d(Constants.LOG_TAG, "onStartCommand() called");
+ showFloatingWindow();
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ @Override
+ public void onDestroy() {
+ Log.d(Constants.LOG_TAG, "onDestroy() called");
+ if (mWindowManager != null && mButton != null) {
+ mWindowManager.removeView(mButton);
+ }
+ super.onDestroy();
+ }
+
+ private void showFloatingWindow() {
+ if (!Settings.canDrawOverlays(this)) {
+ Log.w(Constants.LOG_TAG, "Cannot show overlay window. Permission denied");
+ }
+
+ mButton = new Button(getApplicationContext());
+ mButton.setText(getResources().getString(R.string.tapjacking_text));
+ mButton.setTag(mButton.getVisibility());
+ mWindowManager.addView(mButton, mLayoutParams);
+
+ new Handler(Looper.myLooper()).postDelayed(this::stopSelf, 60_000);
+ Log.d(Constants.LOG_TAG, "Floating window button created");
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/Android.bp
new file mode 100644
index 00000000000..16094cadf20
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+android_test_helper_app {
+ name: "CVE-2021-0478",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ srcs: [
+ "src/android/security/cts/CVE_2021_0478/PocActivity.java",
+ "src/android/security/cts/CVE_2021_0478/PocService.java",
+ ],
+ test_suites: [
+ "cts",
+ "vts10",
+ "sts",
+ ],
+ sdk_version: "current",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/AndroidManifest.xml
new file mode 100644
index 00000000000..d8ec56cbffe
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.cve_2021_0478"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+
+ <application
+ android:allowBackup="true"
+ android:label="CVE-2021-0478"
+ android:supportsRtl="true">
+ <service
+ android:name=".PocService"
+ android:enabled="true"
+ android:exported="false" />
+
+ <activity android:name=".PocActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/res/layout/activity_main.xml
new file mode 100644
index 00000000000..a85bec90a5a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/res/layout/activity_main.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <View
+ android:id="@+id/drawableview"
+ android:layout_width="match_parent"
+ android:layout_height="300dp" />
+</LinearLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/res/raw/image.jpg b/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/res/raw/image.jpg
new file mode 100644
index 00000000000..b829548be8c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/res/raw/image.jpg
Binary files differ
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/src/android/security/cts/CVE_2021_0478/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/src/android/security/cts/CVE_2021_0478/PocActivity.java
new file mode 100644
index 00000000000..65caacfca6f
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/src/android/security/cts/CVE_2021_0478/PocActivity.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.cve_2021_0478;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.Manifest;
+import android.os.Bundle;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+
+public class PocActivity extends Activity {
+ private WakeLock mScreenLock;
+ private Context mContext;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ try {
+ mContext = this.getApplicationContext();
+ PowerManager pm = mContext.getSystemService(PowerManager.class);
+ mScreenLock = pm.newWakeLock(
+ PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
+ "PocActivity");
+ mScreenLock.acquire();
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ startServices();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ void startServices() {
+ try {
+ startForegroundService(new Intent(this, PocService.class));
+ requestPermission();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ void requestPermission() {
+ try {
+ this.requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, 12);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mScreenLock.release();
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/src/android/security/cts/CVE_2021_0478/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/src/android/security/cts/CVE_2021_0478/PocService.java
new file mode 100644
index 00000000000..dfcedca4a6b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0478/src/android/security/cts/CVE_2021_0478/PocService.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.cve_2021_0478;
+
+import android.annotation.SuppressLint;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.os.IBinder;
+
+public class PocService extends Service {
+
+ private static long SCAN_DURATION_MILLIS = 60000;
+
+ public PocService() {}
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ try {
+ NotificationManager notificationManager =
+ getSystemService(NotificationManager.class);
+ String id = "channel";
+ NotificationChannel notificationChannel =
+ new NotificationChannel(id, " ", NotificationManager.IMPORTANCE_NONE);
+ notificationManager.createNotificationChannel(notificationChannel);
+ @SuppressLint("ResourceType")
+ Notification notification = new Notification.Builder(this, id)
+ .setSmallIcon(Icon.createWithResource(this, R.raw.image))
+ .setContentTitle("hello").build();
+ int notificationID = 31;
+ long startTime = System.currentTimeMillis();
+ long endTime = startTime + SCAN_DURATION_MILLIS;
+ while (System.currentTimeMillis() < endTime) {
+ startForeground(notificationID, notification);
+ stopForeground(true);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/hostsidetests/stagedinstall/Android.bp b/hostsidetests/stagedinstall/Android.bp
index 39618ffaf3c..2bab456ace5 100644
--- a/hostsidetests/stagedinstall/Android.bp
+++ b/hostsidetests/stagedinstall/Android.bp
@@ -70,6 +70,8 @@ android_test_helper_app {
":StagedInstallTestApexV2_NoApkSignature",
":StagedInstallTestApexV2_UnsignedPayload",
":StagedInstallTestApexV2_SignPayloadWithDifferentKey",
+ ":StagedInstallTestApexV2_Rebootless",
+ ":StagedInstallTestApexV3_Rebootless",
],
static_libs: [
"androidx.test.runner",
@@ -559,6 +561,46 @@ prebuilt_apex {
installable: false,
}
+prebuilt_apex {
+ name: "StagedInstallTestApexV2_Rebootless",
+ arch: {
+ arm: {
+ src: "testdata/apex/arm/com.android.apex.cts.shim.v2_rebootless.apex",
+ },
+ arm64: {
+ src: "testdata/apex/arm/com.android.apex.cts.shim.v2_rebootless.apex",
+ },
+ x86: {
+ src: "testdata/apex/x86/com.android.apex.cts.shim.v2_rebootless.apex",
+ },
+ x86_64: {
+ src: "testdata/apex/x86/com.android.apex.cts.shim.v2_rebootless.apex",
+ },
+ },
+ filename: "com.android.apex.cts.shim.v2_rebootless.apex",
+ installable: false,
+}
+
+prebuilt_apex {
+ name: "StagedInstallTestApexV3_Rebootless",
+ arch: {
+ arm: {
+ src: "testdata/apex/arm/com.android.apex.cts.shim.v3_rebootless.apex",
+ },
+ arm64: {
+ src: "testdata/apex/arm/com.android.apex.cts.shim.v3_rebootless.apex",
+ },
+ x86: {
+ src: "testdata/apex/x86/com.android.apex.cts.shim.v3_rebootless.apex",
+ },
+ x86_64: {
+ src: "testdata/apex/x86/com.android.apex.cts.shim.v3_rebootless.apex",
+ },
+ },
+ filename: "com.android.apex.cts.shim.v3_rebootless.apex",
+ installable: false,
+}
+
// collects deapexer and its dependency modules (libc++ and debugfs_static) to the zip file.
genrule {
name: "deapexer.zip",
diff --git a/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/ApexShimValidationTest.java b/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/ApexShimValidationTest.java
index f8eabdb29db..712c5636c16 100644
--- a/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/ApexShimValidationTest.java
+++ b/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/ApexShimValidationTest.java
@@ -105,6 +105,64 @@ public class ApexShimValidationTest {
assertThat(InstallUtils.getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
}
+ @Test
+ public void testRejectsApexWithAdditionalFile_rebootless() throws Exception {
+ assertThat(InstallUtils.getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ TestApp apex = new TestApp("ShimApex", SHIM_APEX_PACKAGE_NAME, 2,
+ true, "com.android.apex.cts.shim.v2_additional_file.apex");
+ InstallUtils.commitExpectingFailure(
+ AssertionError.class,
+ "is an unexpected file inside the shim apex",
+ Install.single(apex));
+ assertThat(InstallUtils.getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ }
+
+ @Test
+ public void testRejectsApexWithAdditionalFolder_rebootless() throws Exception {
+ assertThat(InstallUtils.getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ TestApp apex = new TestApp("ShimApex", SHIM_APEX_PACKAGE_NAME, 2,
+ true, "com.android.apex.cts.shim.v2_additional_folder.apex");
+ InstallUtils.commitExpectingFailure(
+ AssertionError.class,
+ "is an unexpected file inside the shim apex",
+ Install.single(apex));
+ assertThat(InstallUtils.getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ }
+
+ @Test
+ public void testRejectsApexWithPostInstallHook_rebootless() throws Exception {
+ assertThat(InstallUtils.getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ TestApp apex = new TestApp("ShimApex", SHIM_APEX_PACKAGE_NAME, 2,
+ true, "com.android.apex.cts.shim.v2_with_post_install_hook.apex");
+ InstallUtils.commitExpectingFailure(
+ AssertionError.class,
+ "Shim apex is not allowed to have pre or post install hooks",
+ Install.single(apex));
+ assertThat(InstallUtils.getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ }
+
+ @Test
+ public void testRejectsApexWithPreInstallHook_rebootless() throws Exception {
+ assertThat(InstallUtils.getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ TestApp apex = new TestApp("ShimApex", SHIM_APEX_PACKAGE_NAME, 2,
+ true, "com.android.apex.cts.shim.v2_with_pre_install_hook.apex");
+ InstallUtils.commitExpectingFailure(
+ AssertionError.class,
+ "Shim apex is not allowed to have pre or post install hooks",
+ Install.single(apex));
+ assertThat(InstallUtils.getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ }
+
+ @Test
+ public void testRejectsApexWrongSHA_rebootless() throws Exception {
+ assertThat(InstallUtils.getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ TestApp apex = new TestApp("ShimApex", SHIM_APEX_PACKAGE_NAME, 2,
+ true, "com.android.apex.cts.shim.v2_wrong_sha.apex");
+ InstallUtils.commitExpectingFailure(
+ AssertionError.class, "has unexpected SHA512 hash", Install.single(apex));
+ assertThat(InstallUtils.getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ }
+
private static int stageApex(String apexFileName) throws Exception {
TestApp apexTestApp = new TestApp("ShimApex", SHIM_APEX_PACKAGE_NAME, 2,
true, apexFileName);
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 24501e3cf28..e7d419b4edd 100644
--- a/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java
+++ b/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java
@@ -166,6 +166,12 @@ public class StagedInstallTest {
private static final TestApp Apex2SignPayloadWithDifferentKey = new TestApp(
"StagedInstallTestApexV2_SignPayloadWithDifferentKey", SHIM_APEX_PACKAGE_NAME, 1,
/*isApex*/true, "com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex");
+ private static final TestApp Apex2Rebootless = new TestApp(
+ "StagedInstallTestApexV2_Rebootless", SHIM_APEX_PACKAGE_NAME, 2,
+ /*isApex*/true, "com.android.apex.cts.shim.v2_rebootless.apex");
+ private static final TestApp Apex3Rebootless = new TestApp(
+ "StagedInstallTestApexV3_Rebootless", SHIM_APEX_PACKAGE_NAME, 3,
+ /*isApex*/true, "com.android.apex.cts.shim.v3_rebootless.apex");
@Before
public void adoptShellPermissions() {
@@ -1258,6 +1264,173 @@ public class StagedInstallTest {
assertThat(isUpdatedSystemApp).isTrue();
}
+ @Test
+ public void testRebootlessUpdate() throws Exception {
+ InstallUtils.dropShellPermissionIdentity();
+ InstallUtils.adoptShellPermissionIdentity(Manifest.permission.INSTALL_PACKAGE_UPDATES);
+
+ final PackageManager pm =
+ InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
+ {
+ PackageInfo apex = pm.getPackageInfo(SHIM_APEX_PACKAGE_NAME, PackageManager.MATCH_APEX);
+ assertThat(apex.getLongVersionCode()).isEqualTo(1);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
+ .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
+ .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
+ assertThat(apex.applicationInfo.sourceDir).startsWith("/system/apex");
+ }
+
+ Install.single(Apex2Rebootless).commit();
+ {
+ PackageInfo apex = pm.getPackageInfo(SHIM_APEX_PACKAGE_NAME, PackageManager.MATCH_APEX);
+ assertThat(apex.getLongVersionCode()).isEqualTo(2);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
+ .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
+ assertThat(apex.applicationInfo.sourceDir).startsWith("/data/apex/active");
+ }
+ {
+ PackageInfo apex = pm.getPackageInfo(SHIM_APEX_PACKAGE_NAME,
+ PackageManager.MATCH_APEX | PackageManager.MATCH_FACTORY_ONLY);
+ assertThat(apex.getLongVersionCode()).isEqualTo(1);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
+ .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
+ assertThat(apex.applicationInfo.sourceDir).startsWith("/system/apex");
+ }
+ }
+
+ @Test
+ public void testRebootlessUpdate_installV3() throws Exception {
+ InstallUtils.dropShellPermissionIdentity();
+ InstallUtils.adoptShellPermissionIdentity(Manifest.permission.INSTALL_PACKAGE_UPDATES);
+
+ final PackageManager pm =
+ InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
+
+ Install.single(Apex3Rebootless).commit();
+ {
+ PackageInfo apex = pm.getPackageInfo(SHIM_APEX_PACKAGE_NAME, PackageManager.MATCH_APEX);
+ assertThat(apex.getLongVersionCode()).isEqualTo(3);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
+ .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
+ assertThat(apex.applicationInfo.sourceDir).startsWith("/data/apex/active");
+ }
+ {
+ PackageInfo apex = pm.getPackageInfo(SHIM_APEX_PACKAGE_NAME,
+ PackageManager.MATCH_APEX | PackageManager.MATCH_FACTORY_ONLY);
+ assertThat(apex.getLongVersionCode()).isEqualTo(1);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
+ .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
+ assertThat(apex.applicationInfo.sourceDir).startsWith("/system/apex");
+ }
+ }
+
+ @Test
+ public void testRebootlessUpdate_downgradeToV2_fails() throws Exception {
+ InstallUtils.dropShellPermissionIdentity();
+ InstallUtils.adoptShellPermissionIdentity(Manifest.permission.INSTALL_PACKAGE_UPDATES);
+
+ final PackageManager pm =
+ InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
+
+ {
+ PackageInfo apex = pm.getPackageInfo(SHIM_APEX_PACKAGE_NAME, PackageManager.MATCH_APEX);
+ assertThat(apex.getLongVersionCode()).isEqualTo(3);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
+ assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
+ .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
+ assertThat(apex.applicationInfo.sourceDir).startsWith("/data/apex/active");
+ }
+
+ InstallUtils.commitExpectingFailure(
+ AssertionError.class,
+ "Downgrade of APEX package com.android.apex.cts.shim is not allowed",
+ Install.single(Apex2Rebootless));
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(3);
+ }
+
+ @Test
+ public void testRebootlessUpdate_noPermission_fails() throws Exception {
+ InstallUtils.dropShellPermissionIdentity();
+
+ InstallUtils.commitExpectingFailure(SecurityException.class,
+ "Not allowed to perform APEX updates",
+ Install.single(Apex2Rebootless));
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ }
+
+ @Test
+ public void testRebootlessUpdate_noPreInstalledApex_fails() throws Exception {
+ assertThat(getInstalledVersion(DIFFERENT_APEX_PACKAGE_NAME)).isEqualTo(-1);
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+
+ InstallUtils.commitExpectingFailure(
+ AssertionError.class,
+ "It is forbidden to install new APEX packages",
+ Install.single(Apex2DifferentPackageName));
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ }
+
+ @Test
+ public void testRebootlessUpdate_unsignedPayload_fails() throws Exception {
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+
+ InstallUtils.commitExpectingFailure(
+ AssertionError.class,
+ "AVB footer verification failed",
+ Install.single(Apex2UnsignedPayload));
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ }
+
+ @Test
+ public void testRebootlessUpdate_payloadSignedWithDifferentKey_fails() throws Exception {
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+
+ InstallUtils.commitExpectingFailure(
+ AssertionError.class,
+ "public key doesn't match the pre-installed one",
+ Install.single(Apex2SignPayloadWithDifferentKey));
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ }
+
+ @Test
+ public void testRebootlessUpdate_outerContainerSignedWithDifferentCert_fails()
+ throws Exception {
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+
+ InstallUtils.commitExpectingFailure(
+ AssertionError.class,
+ "APK container signature of .+ is not compatible with currently installed",
+ Install.single(Apex2DifferentCertificate));
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ }
+
+ @Test
+ public void testRebootlessUpdate_outerContainerUnsigned_fails() throws Exception {
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+
+ InstallUtils.commitExpectingFailure(
+ AssertionError.class,
+ "Failed collecting certificates for",
+ Install.single(Apex2NoApkSignature));
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ }
+
+ @Test
+ public void testRebootlessUpdate_targetsOlderSdk_fails() throws Exception {
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+
+ InstallUtils.commitExpectingFailure(
+ AssertionError.class,
+ "Requires development platform P",
+ Install.single(Apex2SdkTargetP));
+ assertThat(getInstalledVersion(SHIM_APEX_PACKAGE_NAME)).isEqualTo(1);
+ }
+
// It becomes harder to maintain this variety of install-related helper methods.
// TODO(ioffe): refactor install-related helper methods into a separate utility.
private static int createStagedSession() throws Exception {
diff --git a/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/ApexShimValidationTest.java b/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/ApexShimValidationTest.java
index dba49e91d77..ef03c1fda4c 100644
--- a/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/ApexShimValidationTest.java
+++ b/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/ApexShimValidationTest.java
@@ -210,6 +210,31 @@ public class ApexShimValidationTest extends BaseHostJUnit4Test {
runPhase("testInstallRejected_VerifyPostReboot");
}
+ @Test
+ public void testRejectsApexWithAdditionalFile_rebootless() throws Exception {
+ runPhase("testRejectsApexWithAdditionalFile_rebootless");
+ }
+
+ @Test
+ public void testRejectsApexWithAdditionalFolder_rebootless() throws Exception {
+ runPhase("testRejectsApexWithAdditionalFolder_rebootless");
+ }
+
+ @Test
+ public void testRejectsApexWithPostInstallHook_rebootless() throws Exception {
+ runPhase("testRejectsApexWithPostInstallHook_rebootless");
+ }
+
+ @Test
+ public void testRejectsApexWithPreInstallHook_rebootless() throws Exception {
+ runPhase("testRejectsApexWithPreInstallHook_rebootless");
+ }
+
+ @Test
+ public void testRejectsApexWrongSHA_rebootless() throws Exception {
+ runPhase("testRejectsApexWrongSHA_rebootless");
+ }
+
/**
* Extracts {@link #DEAPEXER_ZIP_FILE_NAME} into the destination folder. Updates executable
* attribute for the binaries of deapexer and debugfs_static.
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 b9b12a25a4c..73e832e0589 100644
--- a/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
+++ b/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
@@ -356,7 +356,27 @@ public class StagedInstallTest extends BaseHostJUnit4Test {
public void testInstallStagedApex_SameGrade() throws Exception {
assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
installV3Apex();
+ ApexInfo shim1 =
+ readApexInfoList().stream()
+ .filter(a -> a.getModuleName().equals(SHIM_APEX_PACKAGE_NAME))
+ .filter(ApexInfo::getIsActive)
+ .findAny()
+ .orElseThrow(() ->
+ new AssertionError(
+ "No active version of " + SHIM_APEX_PACKAGE_NAME
+ + " found in /apex/apex-info-list.xml"));
+
installV3Apex();
+ ApexInfo shim2 =
+ readApexInfoList().stream()
+ .filter(a -> a.getModuleName().equals(SHIM_APEX_PACKAGE_NAME))
+ .filter(ApexInfo::getIsActive)
+ .findAny()
+ .orElseThrow(() ->
+ new AssertionError(
+ "No active version of " + SHIM_APEX_PACKAGE_NAME
+ + " found in /apex/apex-info-list.xml"));
+ assertThat(shim1.getLastUpdateMillis()).isNotEqualTo(shim2.getLastUpdateMillis());
}
@Test
@@ -732,6 +752,7 @@ public class StagedInstallTest extends BaseHostJUnit4Test {
assertThat(apexInfo.getModulePath()).isEqualTo(apex.sourceDir);
assertThat(apexInfo.getVersionCode()).isEqualTo(apex.versionCode);
assertThat(apexInfo.getIsActive()).isTrue();
+ assertThat(apexInfo.getLastUpdateMillis()).isGreaterThan(0);
}
}
@@ -739,6 +760,8 @@ public class StagedInstallTest extends BaseHostJUnit4Test {
public void testApexInfoListAfterUpdate() throws Exception {
assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+ ApexInfo shimBeforeUpdate = getShimApexInfo();
+
installV2Apex();
List<ApexInfo> shimApexInfo =
@@ -762,6 +785,8 @@ public class StagedInstallTest extends BaseHostJUnit4Test {
assertThat(factoryShimApexInfo.getVersionCode()).isEqualTo(1);
assertThat(factoryShimApexInfo.getModulePath())
.isEqualTo(factoryShimApexInfo.getPreinstalledModulePath());
+ assertThat(factoryShimApexInfo.getLastUpdateMillis())
+ .isEqualTo(shimBeforeUpdate.getLastUpdateMillis());
ApexInfo activeShimApexInfo =
shimApexInfo.stream()
@@ -777,6 +802,108 @@ public class StagedInstallTest extends BaseHostJUnit4Test {
assertThat(activeShimApexInfo.getVersionCode()).isEqualTo(2);
assertThat(activeShimApexInfo.getPreinstalledModulePath())
.isEqualTo(factoryShimApexInfo.getModulePath());
+ assertThat(activeShimApexInfo.getLastUpdateMillis())
+ .isNotEqualTo(shimBeforeUpdate.getLastUpdateMillis());
+ }
+
+ @Test
+ @LargeTest
+ public void testRebootlessUpdate() throws Exception {
+ assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+
+ runPhase("testRebootlessUpdate");
+ ApexInfo activeShimApexInfo = getActiveShimApexInfo();
+ assertThat(activeShimApexInfo.getModuleName()).isEqualTo(SHIM_APEX_PACKAGE_NAME);
+ assertThat(activeShimApexInfo.getIsActive()).isTrue();
+ assertThat(activeShimApexInfo.getIsFactory()).isFalse();
+ assertThat(activeShimApexInfo.getVersionCode()).isEqualTo(2);
+ }
+
+ @Test
+ public void testRebootlessUpdate_fromV2ToV3_sameBoot() throws Exception {
+ assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+
+ runPhase("testRebootlessUpdate");
+ runPhase("testRebootlessUpdate_installV3");
+ ApexInfo activeShimApexInfo = getActiveShimApexInfo();
+ assertThat(activeShimApexInfo.getModuleName()).isEqualTo(SHIM_APEX_PACKAGE_NAME);
+ assertThat(activeShimApexInfo.getIsActive()).isTrue();
+ assertThat(activeShimApexInfo.getIsFactory()).isFalse();
+ assertThat(activeShimApexInfo.getVersionCode()).isEqualTo(3);
+ }
+
+ @Test
+ @LargeTest
+ public void testRebootlessUpdate_fromV2ToV3_rebootInBetween() throws Exception {
+ assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+
+ runPhase("testRebootlessUpdate");
+ getDevice().reboot();
+ runPhase("testRebootlessUpdate_installV3");
+ ApexInfo activeShimApexInfo = getActiveShimApexInfo();
+ assertThat(activeShimApexInfo.getModuleName()).isEqualTo(SHIM_APEX_PACKAGE_NAME);
+ assertThat(activeShimApexInfo.getIsActive()).isTrue();
+ assertThat(activeShimApexInfo.getIsFactory()).isFalse();
+ assertThat(activeShimApexInfo.getVersionCode()).isEqualTo(3);
+ }
+
+ @Test
+ @LargeTest
+ public void testRebootlessUpdate_downgrage_fails() throws Exception {
+ assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+
+ runPhase("testRebootlessUpdate_installV3");
+ runPhase("testRebootlessUpdate_downgradeToV2_fails");
+ }
+
+ @Test
+ public void testRebootlessUpdate_noPermission_fails() throws Exception {
+ assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+
+ runPhase("testRebootlessUpdate_noPermission_fails");
+ }
+
+ @Test
+ public void testRebootlessUpdate_noPreInstalledApex_fails() throws Exception {
+ assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+
+ runPhase("testRebootlessUpdate_noPreInstalledApex_fails");
+ }
+
+ @Test
+ public void testRebootlessUpdate_unsignedPayload_fails() throws Exception {
+ assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+
+ runPhase("testRebootlessUpdate_unsignedPayload_fails");
+ }
+
+ @Test
+ public void testRebootlessUpdate_payloadSignedWithDifferentKey_fails() throws Exception {
+ assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+
+ runPhase("testRebootlessUpdate_payloadSignedWithDifferentKey_fails");
+ }
+
+ @Test
+ public void testRebootlessUpdate_outerContainerSignedWithDifferentCert_fails()
+ throws Exception {
+ assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+
+ runPhase("testRebootlessUpdate_outerContainerSignedWithDifferentCert_fails");
+ }
+
+ @Test
+ public void testRebootlessUpdate_outerContainerUnsigned_fails() throws Exception {
+ assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+
+ runPhase("testRebootlessUpdate_outerContainerUnsigned_fails");
+ }
+
+ @Test
+ public void testRebootlessUpdate_targetsOlderSdk_fails() throws Exception {
+ assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+
+ runPhase("testRebootlessUpdate_targetsOlderSdk_fails");
}
private List<ApexInfo> readApexInfoList() throws Exception {
@@ -786,6 +913,26 @@ public class StagedInstallTest extends BaseHostJUnit4Test {
}
}
+ private ApexInfo getShimApexInfo() throws Exception {
+ List<ApexInfo> temp =
+ readApexInfoList().stream()
+ .filter(a -> a.getModuleName().equals(SHIM_APEX_PACKAGE_NAME))
+ .collect(Collectors.toList());
+ assertThat(temp).hasSize(1);
+ return temp.get(0);
+ }
+
+ private ApexInfo getActiveShimApexInfo() throws Exception {
+ return readApexInfoList().stream()
+ .filter(a -> a.getModuleName().equals(SHIM_APEX_PACKAGE_NAME))
+ .filter(ApexInfo::getIsActive)
+ .findAny()
+ .orElseThrow(() ->
+ new AssertionError(
+ "No active version of " + SHIM_APEX_PACKAGE_NAME
+ + " found in /apex/apex-info-list.xml"));
+ }
+
/**
* Store the component name of the default launcher. This value will be used to reset the
* default launcher to its correct component upon test completion.
diff --git a/tests/autofillservice/src/android/autofillservice/cts/activities/SimpleSaveActivity.java b/tests/autofillservice/src/android/autofillservice/cts/activities/SimpleSaveActivity.java
index 1ba0b07b4d3..2866cbc371d 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/activities/SimpleSaveActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/activities/SimpleSaveActivity.java
@@ -105,12 +105,16 @@ public class SimpleSaveActivity extends AbstractAutoFillActivity {
mClearFieldsOnSubmit = flag;
}
- public FillExpectation expectAutoFill(String input) {
+ public FillExpectation expectInputTextChange(String input) {
final FillExpectation expectation = new FillExpectation(input, null);
mInput.addTextChangedListener(expectation.mInputWatcher);
return expectation;
}
+ public FillExpectation expectAutoFill(String input) {
+ return expectInputTextChange(input);
+ }
+
public FillExpectation expectAutoFill(String input, String password) {
final FillExpectation expectation = new FillExpectation(input, password);
mInput.addTextChangedListener(expectation.mInputWatcher);
@@ -133,6 +137,10 @@ public class SimpleSaveActivity extends AbstractAutoFillActivity {
: new OneTimeTextWatcher("password", mPassword, password);
}
+ public void assertTextChange() throws Exception {
+ assertAutoFilled();
+ }
+
public void assertAutoFilled() throws Exception {
mInputWatcher.assertAutoFilled();
if (mPasswordWatcher != null) {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineSimpleSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineSimpleSaveActivityTest.java
index da84344e06b..d07f95b0c0f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineSimpleSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineSimpleSaveActivityTest.java
@@ -92,8 +92,10 @@ public class InlineSimpleSaveActivityTest
mUiBot.assertNoDatasetsEver();
// Change input
+ final SimpleSaveActivity.FillExpectation changeExpectation =
+ mActivity.expectInputTextChange("ID");
mActivity.syncRunOnUiThread(() -> mActivity.getInput().setText("ID"));
- mUiBot.waitForIdle();
+ changeExpectation.assertTextChange();
// Trigger save UI.
mUiBot.selectByRelativeId(ID_COMMIT);
@@ -136,15 +138,19 @@ public class InlineSimpleSaveActivityTest
mUiBot.assertDatasets("YO");
// Select suggestion
+ final SimpleSaveActivity.FillExpectation fillExpectation =
+ mActivity.expectAutoFill("id", "pass");
mUiBot.selectDataset("YO");
mUiBot.waitForIdle();
// Check the results.
- mActivity.expectAutoFill("id", "pass");
+ fillExpectation.assertAutoFilled();
// Change input
+ final SimpleSaveActivity.FillExpectation changeExpectation =
+ mActivity.expectInputTextChange("ID");
mActivity.syncRunOnUiThread(() -> mActivity.getInput().setText("ID"));
- mUiBot.waitForIdle();
+ changeExpectation.assertTextChange();
// Trigger save UI.
mUiBot.selectByRelativeId(ID_COMMIT);
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraExtensionSessionTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraExtensionSessionTest.java
index d181f9e4ecc..e50a0c8c6c2 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraExtensionSessionTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraExtensionSessionTest.java
@@ -130,7 +130,7 @@ public class CameraExtensionSessionTest extends Camera2ParameterizedTestCase {
for (String id : mCameraIdsUnderTest) {
StaticMetadata staticMeta =
new StaticMetadata(mTestRule.getCameraManager().getCameraCharacteristics(id));
- if (!staticMeta.isColorCorrectionSupported()) {
+ if (!staticMeta.isColorOutputSupported()) {
continue;
}
updatePreviewSurfaceTexture();
@@ -180,7 +180,7 @@ public class CameraExtensionSessionTest extends Camera2ParameterizedTestCase {
for (String id : mCameraIdsUnderTest) {
StaticMetadata staticMeta =
new StaticMetadata(mTestRule.getCameraManager().getCameraCharacteristics(id));
- if (!staticMeta.isColorCorrectionSupported()) {
+ if (!staticMeta.isColorOutputSupported()) {
continue;
}
updatePreviewSurfaceTexture();
@@ -247,7 +247,7 @@ public class CameraExtensionSessionTest extends Camera2ParameterizedTestCase {
for (String id : mCameraIdsUnderTest) {
StaticMetadata staticMeta =
new StaticMetadata(mTestRule.getCameraManager().getCameraCharacteristics(id));
- if (!staticMeta.isColorCorrectionSupported()) {
+ if (!staticMeta.isColorOutputSupported()) {
continue;
}
updatePreviewSurfaceTexture();
@@ -309,7 +309,7 @@ public class CameraExtensionSessionTest extends Camera2ParameterizedTestCase {
for (String id : mCameraIdsUnderTest) {
StaticMetadata staticMeta =
new StaticMetadata(mTestRule.getCameraManager().getCameraCharacteristics(id));
- if (!staticMeta.isColorCorrectionSupported()) {
+ if (!staticMeta.isColorOutputSupported()) {
continue;
}
updatePreviewSurfaceTexture();
@@ -368,7 +368,7 @@ public class CameraExtensionSessionTest extends Camera2ParameterizedTestCase {
for (String id : mCameraIdsUnderTest) {
StaticMetadata staticMeta =
new StaticMetadata(mTestRule.getCameraManager().getCameraCharacteristics(id));
- if (!staticMeta.isColorCorrectionSupported()) {
+ if (!staticMeta.isColorOutputSupported()) {
continue;
}
updatePreviewSurfaceTexture();
@@ -474,7 +474,7 @@ public class CameraExtensionSessionTest extends Camera2ParameterizedTestCase {
for (String id : mCameraIdsUnderTest) {
StaticMetadata staticMeta =
new StaticMetadata(mTestRule.getCameraManager().getCameraCharacteristics(id));
- if (!staticMeta.isColorCorrectionSupported()) {
+ if (!staticMeta.isColorOutputSupported()) {
continue;
}
updatePreviewSurfaceTexture();
@@ -616,7 +616,7 @@ public class CameraExtensionSessionTest extends Camera2ParameterizedTestCase {
for (String id : mCameraIdsUnderTest) {
StaticMetadata staticMeta =
new StaticMetadata(mTestRule.getCameraManager().getCameraCharacteristics(id));
- if (!staticMeta.isColorCorrectionSupported()) {
+ if (!staticMeta.isColorOutputSupported()) {
continue;
}
CameraExtensionCharacteristics extensionChars =
@@ -760,7 +760,7 @@ public class CameraExtensionSessionTest extends Camera2ParameterizedTestCase {
for (String id : mCameraIdsUnderTest) {
StaticMetadata staticMeta =
new StaticMetadata(mTestRule.getCameraManager().getCameraCharacteristics(id));
- if (!staticMeta.isColorCorrectionSupported()) {
+ if (!staticMeta.isColorOutputSupported()) {
continue;
}
updatePreviewSurfaceTexture();
@@ -1066,7 +1066,7 @@ public class CameraExtensionSessionTest extends Camera2ParameterizedTestCase {
for (String id : mCameraIdsUnderTest) {
StaticMetadata staticMeta =
new StaticMetadata(mTestRule.getCameraManager().getCameraCharacteristics(id));
- if (!staticMeta.isColorCorrectionSupported()) {
+ if (!staticMeta.isColorOutputSupported()) {
continue;
}
updatePreviewSurfaceTexture();
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index d6d5cfc0941..4b483909f5b 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -110,6 +110,7 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
private static final long MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION = 5000000;
private static final long MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION = 4000000;
+ private static final long MIN_UHR_SENSOR_RESOLUTION = 24000000;
/*
* HW Levels short hand
*/
@@ -1481,65 +1482,100 @@ public class ExtendedCameraCharacteristicsTest extends Camera2AndroidTestCase {
}
/**
- * Check remosaic reprocessing capabilities. Check that ImageFormat.RAW_SENSOR is supported as
- * input and output.
+ * Check ultra high resolution sensor characteristics.
*/
@Test
- public void testRemosaicReprocessingCharacteristics() {
+ public void testUltraHighResolutionSensorCharacteristics() {
for (int i = 0; i < mAllCameraIds.length; i++) {
- Log.i(TAG, "testRemosaicReprocessingCharacteristics: Testing camera ID " +
- mAllCameraIds[i]);
-
CameraCharacteristics c = mCharacteristics.get(i);
+ String cameraId = mAllCameraIds[i];
int[] capabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
assertNotNull("android.request.availableCapabilities must never be null",
capabilities);
+ boolean isUltraHighResolutionSensor = arrayContains(capabilities,
+ CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR);
+
boolean supportsRemosaic = arrayContains(capabilities,
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING);
- if (!supportsRemosaic) {
- Log.i(TAG, "Remosaic reprocessing not supported by camera id " + i +
- " skipping test");
+
+ if (!isUltraHighResolutionSensor) {
+ Log.i(TAG, "Camera id " + cameraId + " not ultra high resolution. Skipping " +
+ "testUltraHighResolutionSensorCharacteristics");
continue;
}
+ assertArrayContains(
+ String.format("Ultra high resolution sensor, camera id %s" +
+ " must also have the RAW capability", cameraId), capabilities,
+ CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW);
StreamConfigurationMap configs =
c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION);
- Integer maxNumInputStreams =
- c.get(CameraCharacteristics.REQUEST_MAX_NUM_INPUT_STREAMS);
- int[] inputFormats = configs.getInputFormats();
+ assertNotNull("Maximum resolution stream configuration map must not be null for ultra" +
+ " high resolution sensor camera " + cameraId, configs);
+ Size uhrPixelArraySize = CameraTestUtils.getValueNotNull(
+ c, CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION);
+ long uhrSensorSize = uhrPixelArraySize.getHeight() * uhrPixelArraySize.getWidth();
+
+ assertTrue("ULTRA_HIGH_RESOLUTION_SENSOR pixel array size should be at least " +
+ MIN_UHR_SENSOR_RESOLUTION + " pixels, is " + uhrSensorSize + ", for camera id "
+ + cameraId, uhrSensorSize >= MIN_UHR_SENSOR_RESOLUTION);
+
int[] outputFormats = configs.getOutputFormats();
+ assertArrayContains(String.format("No max res JPEG image format for ultra high" +
+ " resolution sensor: ID %s", cameraId), outputFormats, ImageFormat.JPEG);
+ assertArrayContains(String.format("No max res YUV_420_88 image format for ultra high" +
+ " resolution sensor: ID %s", cameraId), outputFormats, ImageFormat.YUV_420_888);
+ assertArrayContains(String.format("No max res RAW_SENSOR image format for ultra high" +
+ " resolution sensor: ID %s", cameraId), outputFormats, ImageFormat.RAW_SENSOR);
- mCollector.expectTrue("Support reprocessing but max number of input stream is " +
- maxNumInputStreams, maxNumInputStreams != null && maxNumInputStreams > 0);
-
- // Verify mandatory input formats are supported
- mCollector.expectTrue("RAW_SENSOR input support needed for REMOSAIC reprocessing",
- arrayContains(inputFormats, ImageFormat.RAW_SENSOR));
- // max capture stall must be reported if one of the reprocessing is supported.
- final int MAX_ALLOWED_STALL_FRAMES = 4;
- Integer maxCaptureStall = c.get(CameraCharacteristics.REPROCESS_MAX_CAPTURE_STALL);
- mCollector.expectTrue("max capture stall must be non-null and no larger than "
- + MAX_ALLOWED_STALL_FRAMES,
- maxCaptureStall != null && maxCaptureStall <= MAX_ALLOWED_STALL_FRAMES);
-
- for (int input : inputFormats) {
- // Verify mandatory output formats are supported
- int[] outputFormatsForInput = configs.getValidOutputFormatsForInput(input);
-
- // Verify camera can output the reprocess input formats and sizes.
- Size[] inputSizes = configs.getInputSizes(input);
- Size[] outputSizes = configs.getOutputSizes(input);
- Size[] highResOutputSizes = configs.getHighResolutionOutputSizes(input);
- mCollector.expectTrue("no input size supported for format " + input,
- inputSizes.length > 0);
- mCollector.expectTrue("no output size supported for format " + input,
- outputSizes.length > 0);
-
- for (Size inputSize : inputSizes) {
- mCollector.expectTrue("Camera must be able to output the supported " +
- "reprocessing input size",
- arrayContains(outputSizes, inputSize) ||
- arrayContains(highResOutputSizes, inputSize));
- }
+ if (supportsRemosaic) {
+ testRemosaicReprocessingCharacteristics(cameraId, c);
+ }
+ }
+
+ }
+ /**
+ * Check remosaic reprocessing capabilities. Check that ImageFormat.RAW_SENSOR is supported as
+ * input and output.
+ */
+ private void testRemosaicReprocessingCharacteristics(String cameraId, CameraCharacteristics c) {
+ StreamConfigurationMap configs =
+ c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION);
+ Integer maxNumInputStreams =
+ c.get(CameraCharacteristics.REQUEST_MAX_NUM_INPUT_STREAMS);
+ int[] inputFormats = configs.getInputFormats();
+ int[] outputFormats = configs.getOutputFormats();
+
+ mCollector.expectTrue("Support reprocessing but max number of input stream is " +
+ maxNumInputStreams, maxNumInputStreams != null && maxNumInputStreams > 0);
+
+ // Verify mandatory input formats are supported
+ mCollector.expectTrue("RAW_SENSOR input support needed for REMOSAIC reprocessing",
+ arrayContains(inputFormats, ImageFormat.RAW_SENSOR));
+ // max capture stall must be reported if one of the reprocessing is supported.
+ final int MAX_ALLOWED_STALL_FRAMES = 4;
+ Integer maxCaptureStall = c.get(CameraCharacteristics.REPROCESS_MAX_CAPTURE_STALL);
+ mCollector.expectTrue("max capture stall must be non-null and no larger than "
+ + MAX_ALLOWED_STALL_FRAMES,
+ maxCaptureStall != null && maxCaptureStall <= MAX_ALLOWED_STALL_FRAMES);
+
+ for (int input : inputFormats) {
+ // Verify mandatory output formats are supported
+ int[] outputFormatsForInput = configs.getValidOutputFormatsForInput(input);
+
+ // Verify camera can output the reprocess input formats and sizes.
+ Size[] inputSizes = configs.getInputSizes(input);
+ Size[] outputSizes = configs.getOutputSizes(input);
+ Size[] highResOutputSizes = configs.getHighResolutionOutputSizes(input);
+ mCollector.expectTrue("no input size supported for format " + input,
+ inputSizes.length > 0);
+ mCollector.expectTrue("no output size supported for format " + input,
+ outputSizes.length > 0);
+
+ for (Size inputSize : inputSizes) {
+ mCollector.expectTrue("Camera must be able to output the supported " +
+ "reprocessing input size",
+ arrayContains(outputSizes, inputSize) ||
+ arrayContains(highResOutputSizes, inputSize));
}
}
}
diff --git a/tests/framework/base/windowmanager/appProfileable/src/android/server/wm/profileable/ProfileableAppActivity.java b/tests/framework/base/windowmanager/appProfileable/src/android/server/wm/profileable/ProfileableAppActivity.java
index e7fa8ffa17c..46f6183838e 100644
--- a/tests/framework/base/windowmanager/appProfileable/src/android/server/wm/profileable/ProfileableAppActivity.java
+++ b/tests/framework/base/windowmanager/appProfileable/src/android/server/wm/profileable/ProfileableAppActivity.java
@@ -61,7 +61,14 @@ public class ProfileableAppActivity extends BasicTestActivity {
/** Monitor the close event of trace file. */
private static class TraceFileObserver extends FileObserver {
- private static final long TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5);
+ /**
+ * The timeout for the close event of trace file. Although the trace file may take longer
+ * than 3 seconds, it is enough because the test only checks the first line of the file.
+ * Note that this timeout must be less than the value of
+ * {@link android.server.wm.CommandSession.ActivitySession.Response#TIMEOUT_MILLIS}.
+ * Otherwise the caller who sent {@link COMMAND_WAIT_FOR_PROFILE_OUTPUT} may get exception.
+ */
+ private static final long TIMEOUT_MS = TimeUnit.SECONDS.toMillis(3);
private volatile boolean mDone;
TraceFileObserver() {
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodManagerTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodManagerTest.java
index 9b1c83652bb..5eaa32ed205 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodManagerTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodManagerTest.java
@@ -207,7 +207,7 @@ public class InputMethodManagerTest {
PackageManager.FEATURE_INPUT_METHODS));
enableImes(MOCK_IME_ID, HIDDEN_FROM_PICKER_IME_ID);
- TestActivity.startSync(activity -> {
+ final TestActivity testActivity = TestActivity.startSync(activity -> {
final View view = new View(activity);
view.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
@@ -222,8 +222,9 @@ public class InputMethodManagerTest {
// Test InputMethodManager#showInputMethodPicker() works as expected.
mImManager.showInputMethodPicker();
- waitOnMainUntil(() -> mImManager.isInputMethodPickerShown(), TIMEOUT,
- "InputMethod picker should be shown");
+ waitOnMainUntil(() -> mImManager.isInputMethodPickerShown()
+ && !testActivity.hasWindowFocus(), TIMEOUT,
+ "InputMethod picker should be shown and test activity lost focus");
final UiDevice uiDevice =
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
assertThat(uiDevice.wait(Until.hasObject(By.text(MOCK_IME_LABEL)), TIMEOUT)).isTrue();
@@ -234,6 +235,8 @@ public class InputMethodManagerTest {
new Intent(ACTION_CLOSE_SYSTEM_DIALOGS).setFlags(FLAG_RECEIVER_FOREGROUND));
waitOnMainUntil(() -> !mImManager.isInputMethodPickerShown(), TIMEOUT,
"InputMethod picker should be closed");
+ waitOnMainUntil(() -> testActivity.hasWindowFocus(), TIMEOUT,
+ "Activity should be focused after picker dismissed");
}
private void enableImes(String... ids) {
diff --git a/tests/sensor/src/android/hardware/cts/helpers/SensorCtsHelper.java b/tests/sensor/src/android/hardware/cts/helpers/SensorCtsHelper.java
index 597496e75ad..366e1482bc8 100644
--- a/tests/sensor/src/android/hardware/cts/helpers/SensorCtsHelper.java
+++ b/tests/sensor/src/android/hardware/cts/helpers/SensorCtsHelper.java
@@ -247,7 +247,7 @@ public class SensorCtsHelper {
sb.append("(");
}
for (int i = 0; i < array.length; i++) {
- sb.append(String.format("%.2f", array[i]));
+ sb.append(String.format("%.8f", array[i]));
if (i != array.length - 1) {
sb.append(", ");
}
diff --git a/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java b/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
index 2472d48c29d..bc813aab38a 100644
--- a/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
+++ b/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
@@ -1099,8 +1099,7 @@ public class CarrierApiTest extends BaseCarrierApiTest {
(sm) -> getSubscriptionIdList(sm.getSubscriptionsInGroup(uuid)));
activeSubGroup.add(subId);
- assertThat(infoList).hasSize(activeSubGroup.size());
- assertThat(infoList).containsExactly(activeSubGroup);
+ assertThat(infoList).containsExactlyElementsIn(activeSubGroup);
} finally {
removeSubscriptionsFromGroup(uuid);
}
@@ -1132,8 +1131,7 @@ public class CarrierApiTest extends BaseCarrierApiTest {
List<Integer> infoList =
getSubscriptionIdList(mSubscriptionManager.getSubscriptionsInGroup(uuid));
accessibleSubGroup.add(subId);
- assertThat(infoList).hasSize(accessibleSubGroup.size());
- assertThat(infoList).containsExactly(accessibleSubGroup);
+ assertThat(infoList).containsExactlyElementsIn(accessibleSubGroup);
}
} finally {
removeSubscriptionsFromGroup(uuid);
diff --git a/tests/tests/graphics/src/android/graphics/cts/OpenGlEsDeqpLevelTest.java b/tests/tests/graphics/src/android/graphics/cts/OpenGlEsDeqpLevelTest.java
index ceed14a8db8..c6e4b96def5 100644
--- a/tests/tests/graphics/src/android/graphics/cts/OpenGlEsDeqpLevelTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/OpenGlEsDeqpLevelTest.java
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import android.content.pm.PackageManager;
+import android.platform.test.annotations.AppModeFull;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -38,6 +39,7 @@ import org.junit.runner.RunWith;
*/
@SmallTest
@RunWith(AndroidJUnit4.class)
+@AppModeFull(reason = "Instant apps cannot access ro.board.* system properties")
public class OpenGlEsDeqpLevelTest {
private static final String TAG = OpenGlEsDeqpLevelTest.class.getSimpleName();
diff --git a/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java b/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java
index eace470bede..277ca805c78 100644
--- a/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java
@@ -21,6 +21,7 @@ import static org.junit.Assume.assumeTrue;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager;
+import android.platform.test.annotations.AppModeFull;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -40,6 +41,7 @@ import org.junit.runner.RunWith;
*/
@SmallTest
@RunWith(AndroidJUnit4.class)
+@AppModeFull(reason = "Instant apps cannot access ro.board.* system properties")
public class VulkanDeqpLevelTest {
private static final String TAG = VulkanDeqpLevelTest.class.getSimpleName();
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTestImpl.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTestImpl.java
index 215387df073..85136bc2fe5 100644
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTestImpl.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTestImpl.java
@@ -427,7 +427,8 @@ public class EncodeVirtualDisplayWithCompositionTestImpl {
* Determines if two color values are approximately equal.
*/
private static boolean approxEquals(int expected, int actual) {
- final int MAX_DELTA = 7;
+ // allow differences between BT.601 and BT.709 conversions during encoding/decoding for now
+ final int MAX_DELTA = 17;
return Math.abs(expected - actual) <= MAX_DELTA;
}
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index dad5154d4f0..33358b655b2 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -2664,6 +2664,7 @@ public class MediaCodecTest extends AndroidTestCase {
for (String mime: info.getSupportedTypes()) {
CodecCapabilities caps = info.getCapabilitiesForType(mime);
boolean isVideo = (caps.getVideoCapabilities() != null);
+ boolean isAudio = (caps.getAudioCapabilities() != null);
MediaCodec codec = null;
MediaFormat format = null;
@@ -2681,7 +2682,7 @@ public class MediaCodecTest extends AndroidTestCase {
format.setInteger(MediaFormat.KEY_BIT_RATE, minBitrate);
format.setInteger(MediaFormat.KEY_FRAME_RATE, minFrameRate);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
- } else {
+ } else if(isAudio){
AudioCapabilities acaps = caps.getAudioCapabilities();
int minSampleRate = acaps.getSupportedSampleRateRanges()[0].getLower();
int minChannelCount = 1;
@@ -2692,11 +2693,13 @@ public class MediaCodecTest extends AndroidTestCase {
format = MediaFormat.createAudioFormat(mime, minSampleRate, minChannelCount);
format.setInteger(MediaFormat.KEY_BIT_RATE, minBitrate);
}
- format.setInteger(MediaFormat.KEY_PREPEND_HEADER_TO_SYNC_FRAMES, 1);
- codec.configure(format, null /* surface */, null /* crypto */,
- isEncoder ? codec.CONFIGURE_FLAG_ENCODE : 0);
+ if (isVideo || isAudio) {
+ format.setInteger(MediaFormat.KEY_PREPEND_HEADER_TO_SYNC_FRAMES, 1);
+ codec.configure(format, null /* surface */, null /* crypto */,
+ isEncoder ? codec.CONFIGURE_FLAG_ENCODE : 0);
+ }
if (isVideo && isEncoder) {
Log.i(TAG, info.getName() + " supports KEY_PREPEND_HEADER_TO_SYNC_FRAMES");
} else {
diff --git a/tests/tests/security/res/raw/cve_2021_0635_1.flv b/tests/tests/security/res/raw/cve_2021_0635_1.flv
new file mode 100644
index 00000000000..8d87f0446cb
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2021_0635_1.flv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2021_0635_2.flv b/tests/tests/security/res/raw/cve_2021_0635_2.flv
new file mode 100644
index 00000000000..beebacdd322
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2021_0635_2.flv
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0521.java b/tests/tests/security/src/android/security/cts/CVE_2021_0521.java
new file mode 100644
index 00000000000..8a883ff7fdc
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0521.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.os.IBinder;
+import android.os.Parcel;
+import android.platform.test.annotations.AsbSecurityTest;
+import android.platform.test.annotations.SecurityTest;
+import android.util.Log;
+import androidx.test.runner.AndroidJUnit4;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.List;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assume.assumeThat;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2021_0521 {
+
+ private String TAG = "CVE_2021_0521";
+
+ private int getFunctionCode(String className) {
+ int code = -1;
+ try {
+ Class c = Class.forName(className);
+ Field field = c.getDeclaredField("TRANSACTION_getAllPackages");
+ field.setAccessible(true);
+ code = field.getInt(c);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception caught " + e.toString());
+ }
+ return code;
+ }
+
+ private IBinder getIBinderFromServiceManager(String serviceName) {
+ try {
+ return (IBinder) Class.forName("android.os.ServiceManager")
+ .getMethod("getService", String.class).invoke(null, serviceName);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * b/174661955
+ */
+ @AsbSecurityTest(cveBugId = 174661955)
+ @SecurityTest(minPatchLevel = "2021-06")
+ @Test
+ public void testPocCVE_2021_0521() {
+ IBinder pmsBinder = getIBinderFromServiceManager("package");
+ List<String> allPkgList = Collections.<String>emptyList();
+ try {
+ String desciption = pmsBinder.getInterfaceDescriptor();
+ int code = getFunctionCode(desciption + "$Stub");
+ assumeThat(code, not(is(-1)));
+ Parcel send = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ send.writeInterfaceToken(desciption);
+ if (pmsBinder.transact(code, send, reply, 0)) {
+ reply.readException();
+ allPkgList = reply.createStringArrayList();
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Exception caught " + e.toString());
+ } finally {
+ Log.e(TAG, "List of installed packages: " + allPkgList.toString());
+ assertThat("Got a non empty list of installed packages, hence device "
+ + "is vulnerable to b/174661955", allPkgList.size(), is(0));
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 725cdbf5d38..3d3efb119d0 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -2606,6 +2606,13 @@ public class StagefrightTest {
assertExtractorDoesNotHang(R.raw.bug_127313764);
}
+ @Test
+ @AsbSecurityTest(cveBugId = 189402477)
+ public void testStagefright_cve_2021_0635() throws Exception {
+ doStagefrightTest(R.raw.cve_2021_0635_1);
+ doStagefrightTest(R.raw.cve_2021_0635_2);
+ }
+
private int[] getFrameSizes(int rid) throws IOException {
final Context context = getInstrumentation().getContext();
final Resources resources = context.getResources();
diff --git a/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt b/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt
index a133e19938e..d5035fab288 100644
--- a/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt
+++ b/tests/tests/sensorprivacy/src/android/sensorprivacy/cts/SensorPrivacyBaseTest.kt
@@ -187,6 +187,9 @@ abstract class SensorPrivacyBaseTest(
@Test
@AppModeFull(reason = "Instant apps can't manage keyguard")
fun testCantChangeWhenLocked() {
+ Assume.assumeTrue(packageManager
+ .hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN))
+
setSensor(false)
assertFalse(isSensorPrivacyEnabled())
runWhileLocked {