Merge "CTS: WifiLockState"
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
index 343c960..dd7ef21 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
@@ -12,20 +12,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import its.image
+import math
+import os.path
import its.caps
import its.device
+import its.image
import its.objects
import its.target
-import os.path
-import math
+
+NAME = os.path.basename(__file__).split(".")[0]
+THRESHOLD_MAX_RMS_DIFF = 0.035
+
def main():
- """Test capturing a single frame as both RAW and YUV outputs.
- """
- NAME = os.path.basename(__file__).split(".")[0]
-
- THRESHOLD_MAX_RMS_DIFF = 0.035
+ """Test capturing a single frame as both RAW and YUV outputs."""
with its.device.ItsSession() as cam:
props = cam.get_camera_properties()
@@ -38,34 +38,35 @@
e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
req = its.objects.manual_capture_request(s, e, 0.0, True, props)
- if 0 in props['android.shading.availableModes']:
- req["android.shading.mode"] = 0
+ mode = req["android.shading.mode"]
+ print "shading mode:", mode
- max_raw_size = \
- its.objects.get_available_output_sizes("raw", props)[0]
- w,h = its.objects.get_available_output_sizes(
+ max_raw_size = its.objects.get_available_output_sizes("raw", props)[0]
+ w, h = its.objects.get_available_output_sizes(
"yuv", props, (1920, 1080), max_raw_size)[0]
- out_surfaces = [{"format":"raw"},
- {"format":"yuv", "width":w, "height":h}]
+ out_surfaces = [{"format": "raw"},
+ {"format": "yuv", "width": w, "height": h}]
cap_raw, cap_yuv = cam.do_capture(req, out_surfaces)
img = its.image.convert_capture_to_rgb_image(cap_yuv)
- its.image.write_image(img, "%s_yuv.jpg" % (NAME), True)
+ its.image.write_image(img, "%s_shading=%d_yuv.jpg" % (NAME, mode), True)
tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
rgb0 = its.image.compute_image_means(tile)
# Raw shots are 1/2 x 1/2 smaller after conversion to RGB, but tile
# cropping is relative.
img = its.image.convert_capture_to_rgb_image(cap_raw, props=props)
- its.image.write_image(img, "%s_raw.jpg" % (NAME), True)
+ its.image.write_image(img, "%s_shading=%d_raw.jpg" % (NAME, mode), True)
tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
rgb1 = its.image.compute_image_means(tile)
rms_diff = math.sqrt(
sum([pow(rgb0[i] - rgb1[i], 2.0) for i in range(3)]) / 3.0)
- print "RMS difference:", rms_diff
- assert(rms_diff < THRESHOLD_MAX_RMS_DIFF)
+ msg = "RMS difference: %.4f, spec: %.3f" % (rms_diff,
+ THRESHOLD_MAX_RMS_DIFF)
+ print msg
+ assert rms_diff < THRESHOLD_MAX_RMS_DIFF, msg
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
index 6ecdca7..9c0c69b 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
@@ -12,20 +12,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import its.image
+import math
+import os.path
import its.caps
import its.device
+import its.image
import its.objects
import its.target
-import os.path
-import math
+
+NAME = os.path.basename(__file__).split(".")[0]
+THRESHOLD_MAX_RMS_DIFF = 0.035
+
def main():
- """Test capturing a single frame as both RAW10 and YUV outputs.
- """
- NAME = os.path.basename(__file__).split(".")[0]
-
- THRESHOLD_MAX_RMS_DIFF = 0.035
+ """Test capturing a single frame as both RAW10 and YUV outputs."""
with its.device.ItsSession() as cam:
props = cam.get_camera_properties()
@@ -38,34 +38,36 @@
e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
req = its.objects.manual_capture_request(s, e, 0.0, True, props)
- if 0 in props['android.shading.availableModes']:
- req["android.shading.mode"] = 0
+ mode = req["android.shading.mode"]
+ print "shading mode:", mode
- max_raw10_size = \
- its.objects.get_available_output_sizes("raw10", props)[0]
- w,h = its.objects.get_available_output_sizes(
+ max_raw10_size = its.objects.get_available_output_sizes("raw10",
+ props)[0]
+ w, h = its.objects.get_available_output_sizes(
"yuv", props, (1920, 1080), max_raw10_size)[0]
- cap_raw, cap_yuv = cam.do_capture(req,
- [{"format":"raw10"},
- {"format":"yuv", "width":w, "height":h}])
+ out_surfaces = [{"format": "raw10"},
+ {"format": "yuv", "width": w, "height": h}]
+ cap_raw, cap_yuv = cam.do_capture(req, out_surfaces)
img = its.image.convert_capture_to_rgb_image(cap_yuv)
- its.image.write_image(img, "%s_yuv.jpg" % (NAME), True)
+ its.image.write_image(img, "%s_shading=%d_yuv.jpg" % (NAME, mode), True)
tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
rgb0 = its.image.compute_image_means(tile)
# Raw shots are 1/2 x 1/2 smaller after conversion to RGB, but tile
# cropping is relative.
img = its.image.convert_capture_to_rgb_image(cap_raw, props=props)
- its.image.write_image(img, "%s_raw.jpg" % (NAME), True)
+ its.image.write_image(img, "%s_shading=%d_raw.jpg" % (NAME, mode), True)
tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
rgb1 = its.image.compute_image_means(tile)
rms_diff = math.sqrt(
sum([pow(rgb0[i] - rgb1[i], 2.0) for i in range(3)]) / 3.0)
- print "RMS difference:", rms_diff
- assert(rms_diff < THRESHOLD_MAX_RMS_DIFF)
+ msg = "RMS difference: %.4f, spec: %.3f" % (rms_diff,
+ THRESHOLD_MAX_RMS_DIFF)
+ print msg
+ assert rms_diff < THRESHOLD_MAX_RMS_DIFF, msg
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/hostsidetests/backup/src/android/cts/backup/SuccessNotificationHostSideTest.java b/hostsidetests/backup/src/android/cts/backup/SuccessNotificationHostSideTest.java
index 0e2abb8..414e3bc 100644
--- a/hostsidetests/backup/src/android/cts/backup/SuccessNotificationHostSideTest.java
+++ b/hostsidetests/backup/src/android/cts/backup/SuccessNotificationHostSideTest.java
@@ -168,11 +168,13 @@
private void addBackupFinishedNotificationReceiver()
throws DeviceNotAvailableException {
mOriginalBackupManagerConstants = getDevice().executeShellCommand(String.format(
- "settings get secure %s", BACKUP_MANAGER_CONSTANTS_PREF));
+ "settings get secure %s", BACKUP_MANAGER_CONSTANTS_PREF)).trim();
+ if ("null".equals(mOriginalBackupManagerConstants)) {
+ mOriginalBackupManagerConstants = null;
+ }
String backupManagerConstants = null;
- if (mOriginalBackupManagerConstants == null ||
- mOriginalBackupManagerConstants.trim().isEmpty()) {
+ if (mOriginalBackupManagerConstants == null || mOriginalBackupManagerConstants.isEmpty()) {
backupManagerConstants =
BACKUP_FINISHED_NOTIFICATION_RECEIVERS + "=" + SUCCESS_NOTIFICATION_APP_PACKAGE;
} else {
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PasswordBlacklistTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PasswordBlacklistTest.java
index 6d7af3b..7856aff 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PasswordBlacklistTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PasswordBlacklistTest.java
@@ -17,12 +17,14 @@
package com.android.cts.deviceandprofileowner;
import android.app.admin.DevicePolicyManager;
+import android.util.Log;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
public final class PasswordBlacklistTest extends BaseDeviceAdminTest {
+ private static final String TAG = "PasswordBlacklistTest";
private static final byte[] TOKEN = "abcdefghijklmnopqrstuvwxyz0123456789".getBytes();
private boolean mShouldRun = true;
@@ -40,6 +42,7 @@
TOKEN));
} catch (SecurityException e) {
if (e.getMessage().equals("Escrow token is disabled on the current user")) {
+ Log.i(TAG, "Skip some password blacklist test because escrow token is disabled");
mShouldRun = false;
} else {
throw e;
@@ -132,17 +135,11 @@
}
public void testMaxBlacklistSize() {
- if (!mShouldRun) {
- return;
- }
assertTrue(mDevicePolicyManager.setPasswordBlacklist(
ADMIN_RECEIVER_COMPONENT, "max size", generateMaxBlacklist()));
}
public void testBlacklistTooBig() {
- if (!mShouldRun) {
- return;
- }
try {
mDevicePolicyManager.setPasswordBlacklist(
ADMIN_RECEIVER_COMPONENT, "too big", generateJustTooBigBlacklist());
@@ -202,9 +199,6 @@
}
public void testPasswordBlacklistWithEmptyName() {
- if (!mShouldRun) {
- return;
- }
final String emptyName = "";
assertTrue(mDevicePolicyManager.setPasswordBlacklist(
ADMIN_RECEIVER_COMPONENT, emptyName, Arrays.asList("test", "empty", "name")));
@@ -213,9 +207,6 @@
}
public void testBlacklistNameCanBeChanged() {
- if (!mShouldRun) {
- return;
- }
final String firstName = "original";
assertTrue(mDevicePolicyManager.setPasswordBlacklist(
ADMIN_RECEIVER_COMPONENT, firstName, Arrays.asList("a")));
@@ -230,9 +221,6 @@
}
public void testCannotNameClearedBlacklist() {
- if (!mShouldRun) {
- return;
- }
final String name = "empty!";
assertTrue(mDevicePolicyManager.setPasswordBlacklist(
ADMIN_RECEIVER_COMPONENT, name, null));
@@ -240,9 +228,6 @@
}
public void testClearingBlacklistClearsName() {
- if (!mShouldRun) {
- return;
- }
final String firstName = "gotone";
assertTrue(mDevicePolicyManager.setPasswordBlacklist(
ADMIN_RECEIVER_COMPONENT, firstName, Arrays.asList("something")));
@@ -256,9 +241,6 @@
}
public void testNullAdminWhenGettingBlacklistName() {
- if (!mShouldRun) {
- return;
- }
try {
mDevicePolicyManager.getPasswordBlacklistName(null);
fail("Did not throw NullPointerException");
@@ -268,6 +250,9 @@
}
public void testBlacklistNotConsideredByIsActivePasswordSufficient() {
+ if (!mShouldRun) {
+ return;
+ }
mDevicePolicyManager.setPasswordQuality(ADMIN_RECEIVER_COMPONENT,
DevicePolicyManager.PASSWORD_QUALITY_COMPLEX);
final String complexPassword = ".password123";
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/Android.mk b/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
index 196dc4c..85e369b 100644
--- a/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
+++ b/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
@@ -30,7 +30,6 @@
android-support-v4 \
ctstestrunner \
android-support-test \
- legacy-android-test \
compatibility-device-util \
ShortcutManagerTestUtils \
testng
diff --git a/hostsidetests/seccomp/Android.mk b/hostsidetests/seccomp/Android.mk
new file mode 100644
index 0000000..2c1c077
--- /dev/null
+++ b/hostsidetests/seccomp/Android.mk
@@ -0,0 +1,32 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := tests
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+LOCAL_MODULE := CtsSeccompHostTestCases
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed compatibility-host-util
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/seccomp/AndroidTest.xml b/hostsidetests/seccomp/AndroidTest.xml
new file mode 100644
index 0000000..cbfd1c4
--- /dev/null
+++ b/hostsidetests/seccomp/AndroidTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Config for CTS Sseccomp host test cases">
+ <option name="test-suite-tag" value="cts" />
+ <option name="config-descriptor:metadata" key="component" value="misc" />
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="CtsSeccompDeviceApp.apk" />
+ </target_preparer>
+ <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+ <option name="jar" value="CtsSeccompHostTestCases.jar" />
+ </test>
+</configuration>
diff --git a/hostsidetests/seccomp/app/Android.mk b/hostsidetests/seccomp/app/Android.mk
new file mode 100644
index 0000000..726e64b
--- /dev/null
+++ b/hostsidetests/seccomp/app/Android.mk
@@ -0,0 +1,56 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-test \
+ compatibility-device-util \
+
+LOCAL_JNI_SHARED_LIBRARIES := \
+ libctsseccomp_jni \
+ libcts_jni \
+ libnativehelper_compat_libc++ \
+ libnativehelper \
+ libcutils \
+ libc++ \
+ libpackagelistparser \
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+LOCAL_PACKAGE_NAME := CtsSeccompDeviceApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/seccomp/app/AndroidManifest.xml b/hostsidetests/seccomp/app/AndroidManifest.xml
new file mode 100644
index 0000000..b8e97e3
--- /dev/null
+++ b/hostsidetests/seccomp/app/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.seccomp.cts.app">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.seccomp.cts.app" />
+
+</manifest>
diff --git a/hostsidetests/seccomp/app/jni/Android.mk b/hostsidetests/seccomp/app/jni/Android.mk
new file mode 100644
index 0000000..a0604a1
--- /dev/null
+++ b/hostsidetests/seccomp/app/jni/Android.mk
@@ -0,0 +1,41 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libctsseccomp_jni
+
+# Don't include this package in any configuration by default.
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ CtsSeccompJniOnLoad.cpp \
+ android_seccomp_cts_app_SeccompDeviceTest.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libnativehelper \
+ liblog \
+ libcutils \
+ libc++ \
+ libpackagelistparser \
+
+
+LOCAL_C_INCLUDES += ndk/sources/cpufeatures
+LOCAL_STATIC_LIBRARIES := cpufeatures
+
+LOCAL_CFLAGS := -Wall -Werror
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/hostsidetests/seccomp/app/jni/CtsSeccompJniOnLoad.cpp b/hostsidetests/seccomp/app/jni/CtsSeccompJniOnLoad.cpp
new file mode 100644
index 0000000..928b8c5
--- /dev/null
+++ b/hostsidetests/seccomp/app/jni/CtsSeccompJniOnLoad.cpp
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#include <jni.h>
+#include <stdio.h>
+
+extern int register_android_seccomp_cts_app_SeccompTest(JNIEnv*);
+
+jint JNI_OnLoad(JavaVM *vm, void * /*reserved*/) {
+ JNIEnv *env = NULL;
+
+ if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
+ return JNI_ERR;
+ }
+
+ if (register_android_seccomp_cts_app_SeccompTest(env)) {
+ return JNI_ERR;
+ }
+
+ return JNI_VERSION_1_4;
+}
diff --git a/tests/tests/security/jni/android_security_cts_SeccompTest.cpp b/hostsidetests/seccomp/app/jni/android_seccomp_cts_app_SeccompDeviceTest.cpp
similarity index 91%
rename from tests/tests/security/jni/android_security_cts_SeccompTest.cpp
rename to hostsidetests/seccomp/app/jni/android_seccomp_cts_app_SeccompDeviceTest.cpp
index ee36cdd..de82b44 100644
--- a/tests/tests/security/jni/android_security_cts_SeccompTest.cpp
+++ b/hostsidetests/seccomp/app/jni/android_seccomp_cts_app_SeccompDeviceTest.cpp
@@ -36,7 +36,7 @@
int pid = fork();
if (pid == 0) {
ALOGI("Calling syscall %d", nr);
- int ret = syscall(nr);
+ syscall(nr);
return false;
} else {
int status;
@@ -72,9 +72,9 @@
(void*) testSyscallBlocked },
};
-int register_android_security_cts_SeccompTest(JNIEnv* env)
+int register_android_seccomp_cts_app_SeccompTest(JNIEnv* env)
{
- jclass clazz = env->FindClass("android/security/cts/SeccompTest");
+ jclass clazz = env->FindClass("android/seccomp/cts/app/SeccompDeviceTest");
return env->RegisterNatives(clazz, gMethods,
sizeof(gMethods) / sizeof(JNINativeMethod));
diff --git a/tests/tests/security/src/android/security/cts/SeccompTest.java b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
similarity index 81%
rename from tests/tests/security/src/android/security/cts/SeccompTest.java
rename to hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
index 745aa87..2a7bcb3 100644
--- a/tests/tests/security/src/android/security/cts/SeccompTest.java
+++ b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
@@ -14,23 +14,28 @@
* limitations under the License.
*/
-package android.security.cts;
+package android.seccomp.cts.app;
-import android.test.AndroidTestCase;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import android.support.test.runner.AndroidJUnit4;
import com.android.compatibility.common.util.CpuFeatures;
-import junit.framework.TestCase;
-
/**
- * Verify that the seccomp policy is enforced
+ * Device-side tests for CtsSeccompHostTestCases
*/
-public class SeccompTest extends AndroidTestCase {
-
+@RunWith(AndroidJUnit4.class)
+public class SeccompDeviceTest {
static {
- System.loadLibrary("ctssecurity_jni");
+ System.loadLibrary("ctsseccomp_jni");
}
+ @Test
public void testCTSSyscallBlocked() {
if (CpuFeatures.isArm64Cpu()) {
testBlocked(217); // __NR_add_key
@@ -63,10 +68,11 @@
testBlocked(4282); // __NR_keyctl
testAllowed(4288); // __NR_openat
} else {
- fail("Unsupported OS");
+ Assert.fail("Unsupported OS");
}
}
+ @Test
public void testCTSSwapOnOffBlocked() {
if (CpuFeatures.isArm64Cpu()) {
testBlocked(224); // __NR_swapon
@@ -87,16 +93,16 @@
testBlocked(4087); // __NR_swapon
testBlocked(4115); // __NR_swapoff
} else {
- fail("Unsupported OS");
+ Assert.fail("Unsupported OS");
}
}
private void testBlocked(int nr) {
- assertTrue("Syscall " + nr + " allowed", testSyscallBlocked(nr));
+ Assert.assertTrue("Syscall " + nr + " not blocked", testSyscallBlocked(nr));
}
private void testAllowed(int nr) {
- assertFalse("Syscall " + nr + " blocked", testSyscallBlocked(nr));
+ Assert.assertFalse("Syscall " + nr + " blocked", testSyscallBlocked(nr));
}
private static final native boolean testSyscallBlocked(int nr);
diff --git a/hostsidetests/seccomp/src/android/seccomp/cts/SeccompHostJUnit4DeviceTest.java b/hostsidetests/seccomp/src/android/seccomp/cts/SeccompHostJUnit4DeviceTest.java
new file mode 100644
index 0000000..63258e3
--- /dev/null
+++ b/hostsidetests/seccomp/src/android/seccomp/cts/SeccompHostJUnit4DeviceTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+package android.seccomp.cts;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test that collects test results from test package android.seccomp.cts.app.
+ *
+ * When this test builds, it also builds a support APK containing
+ * {@link android.seccomp.cts.app.SeccompDeviceTest}, the results of which are
+ * collected from the hostside and reported accordingly.
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class SeccompHostJUnit4DeviceTest extends BaseHostJUnit4Test {
+
+ private static final String TEST_PKG = "android.seccomp.cts.app";
+ private static final String TEST_CLASS = TEST_PKG + "." + "SeccompDeviceTest";
+ private static final String TEST_APP = "CtsSeccompDeviceApp.apk";
+
+ private static final String TEST_CTS_SYSCALL_BLOCKED = "testCTSSyscallBlocked";
+ private static final String TEST_CTS_SWAP_ON_OFF_BLOCKED = "testCTSSwapOnOffBlocked";
+
+ @Before
+ public void setUp() throws Exception {
+ installPackage(TEST_APP);
+ }
+
+ @Test
+ public void testCTSSyscallBlocked() throws Exception {
+ Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_CTS_SYSCALL_BLOCKED));
+ }
+
+ @Test
+ public void testCTSSwapOnOffBlocked() throws Exception {
+ Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_CTS_SWAP_ON_OFF_BLOCKED));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ uninstallPackage(getDevice(), TEST_PKG);
+ }
+
+}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/HostAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/HostAtomTests.java
index cbf3cc0..5ef6deb 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/HostAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/HostAtomTests.java
@@ -32,6 +32,7 @@
import com.android.os.AtomsProto.BatterySaverModeStateChanged;
import com.android.os.AtomsProto.ChargingStateChanged;
import com.android.os.AtomsProto.CpuTimePerUid;
+import com.android.os.AtomsProto.CpuTimePerFreq;
import com.android.os.AtomsProto.CpuTimePerUidFreq;
import com.android.os.AtomsProto.DeviceIdleModeStateChanged;
import com.android.os.AtomsProto.KernelWakelock;
@@ -598,6 +599,31 @@
assertTrue(atom.getKernelWakelock().hasTime());
}
+ public void testCpuTimePerFreq() throws Exception {
+ if (!TESTS_ENABLED) {return;}
+ StatsdConfig.Builder config = getPulledAndAnomalyConfig();
+ FieldMatcher.Builder dimension = FieldMatcher.newBuilder()
+ .setField(Atom.CPU_TIME_PER_FREQ_FIELD_NUMBER)
+ .addChild(FieldMatcher.newBuilder()
+ .setField(CpuTimePerFreq.CLUSTER_FIELD_NUMBER));
+ addGaugeAtom(config, Atom.CPU_TIME_PER_FREQ_FIELD_NUMBER, dimension);
+
+ turnScreenOff();
+
+ uploadConfig(config);
+
+ Thread.sleep(2000);
+ turnScreenOn();
+ Thread.sleep(2000);
+
+ List<Atom> data = getGaugeMetricDataList();
+
+ Atom atom = data.get(0);
+ assertTrue(atom.getCpuTimePerFreq().getCluster() >= 0);
+ assertTrue(atom.getCpuTimePerFreq().getFreqIndex() >= 0);
+ assertTrue(atom.getCpuTimePerFreq().getTimeMs() > 0);
+ }
+
public void testCpuTimePerUidFreq() throws Exception {
if (!TESTS_ENABLED) {return;}
StatsdConfig.Builder config = getPulledAndAnomalyConfig();
diff --git a/tests/framework/base/activitymanager/AndroidManifest.xml b/tests/framework/base/activitymanager/AndroidManifest.xml
index 4ca4a5d..15c07be 100644
--- a/tests/framework/base/activitymanager/AndroidManifest.xml
+++ b/tests/framework/base/activitymanager/AndroidManifest.xml
@@ -22,6 +22,7 @@
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
<uses-permission android:name="android.permission.ACTIVITY_EMBEDDING" />
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<application android:label="CtsActivityManagerDeviceTestCases">
<uses-library android:name="android.test.runner" />
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityAndWindowManagerOverrideConfigTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityAndWindowManagerOverrideConfigTests.java
index 12bfb78..116c026 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityAndWindowManagerOverrideConfigTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityAndWindowManagerOverrideConfigTests.java
@@ -18,6 +18,8 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.server.am.StateLogger.log;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -71,21 +73,23 @@
launchActivity(TEST_ACTIVITY_NAME, WINDOWING_MODE_FREEFORM);
- setDeviceRotation(0);
- String logSeparator = clearLogcat();
- resizeActivityTask(TEST_ACTIVITY_NAME, 0, 0, 100, 100);
- ConfigurationChangeObserver c = new ConfigurationChangeObserver();
- final boolean reportedSizeAfterResize = c.findConfigurationChange(TEST_ACTIVITY_NAME,
- logSeparator);
- assertTrue("Expected to observe configuration change when resizing",
- reportedSizeAfterResize);
+ try (final RotationSession rotationSession = new RotationSession()) {
+ rotationSession.set(ROTATION_0);
+ String logSeparator = clearLogcat();
+ resizeActivityTask(TEST_ACTIVITY_NAME, 0, 0, 100, 100);
+ ConfigurationChangeObserver c = new ConfigurationChangeObserver();
+ final boolean reportedSizeAfterResize = c.findConfigurationChange(TEST_ACTIVITY_NAME,
+ logSeparator);
+ assertTrue("Expected to observe configuration change when resizing",
+ reportedSizeAfterResize);
- logSeparator = clearLogcat();
- setDeviceRotation(2);
- final boolean reportedSizeAfterRotation = c.findConfigurationChange(TEST_ACTIVITY_NAME,
- logSeparator);
- assertFalse("Not expected to observe configuration change after flip rotation",
- reportedSizeAfterRotation);
+ logSeparator = clearLogcat();
+ rotationSession.set(ROTATION_180);
+ final boolean reportedSizeAfterRotation = c.findConfigurationChange(TEST_ACTIVITY_NAME,
+ logSeparator);
+ assertFalse("Not expected to observe configuration change after flip rotation",
+ reportedSizeAfterRotation);
+ }
}
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
index d32180a..404e5c7 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
@@ -24,6 +24,10 @@
import static android.server.am.ActivityManagerState.STATE_RESUMED;
import static android.server.am.StateLogger.log;
import static android.server.am.StateLogger.logE;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -119,14 +123,17 @@
public void testConfigurationUpdatesWhenRotatingWhileFullscreen() throws Exception {
assumeTrue("Skipping test: no rotation support", supportsRotation());
- setDeviceRotation(0);
- final String logSeparator = clearLogcat();
- launchActivity(RESIZEABLE_ACTIVITY_NAME,
- WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
- final ReportedSizes initialSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
- logSeparator);
+ try (final RotationSession rotationSession = new RotationSession()) {
+ rotationSession.set(ROTATION_0);
- rotateAndCheckSizes(initialSizes);
+ final String logSeparator = clearLogcat();
+ launchActivity(RESIZEABLE_ACTIVITY_NAME,
+ WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
+ final ReportedSizes initialSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
+ logSeparator);
+
+ rotateAndCheckSizes(rotationSession, initialSizes);
+ }
}
/**
@@ -138,17 +145,20 @@
public void testConfigurationUpdatesWhenRotatingWhileDocked() throws Exception {
assumeTrue("Skipping test: no multi-window support", supportsSplitScreenMultiWindow());
- setDeviceRotation(0);
- final String logSeparator = clearLogcat();
- // Launch our own activity to side in case Recents (or other activity to side) doesn't
- // support rotation.
- launchActivitiesInSplitScreen(LAUNCHING_ACTIVITY, TEST_ACTIVITY_NAME);
- // Launch target activity in docked stack.
- getLaunchActivityBuilder().setTargetActivityName(RESIZEABLE_ACTIVITY_NAME).execute();
- final ReportedSizes initialSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
- logSeparator);
+ try (final RotationSession rotationSession = new RotationSession()) {
+ rotationSession.set(ROTATION_0);
- rotateAndCheckSizes(initialSizes);
+ final String logSeparator = clearLogcat();
+ // Launch our own activity to side in case Recents (or other activity to side) doesn't
+ // support rotation.
+ launchActivitiesInSplitScreen(LAUNCHING_ACTIVITY, TEST_ACTIVITY_NAME);
+ // Launch target activity in docked stack.
+ getLaunchActivityBuilder().setTargetActivityName(RESIZEABLE_ACTIVITY_NAME).execute();
+ final ReportedSizes initialSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
+ logSeparator);
+
+ rotateAndCheckSizes(rotationSession, initialSizes);
+ }
}
/**
@@ -160,23 +170,27 @@
public void testConfigurationUpdatesWhenRotatingToSideFromDocked() throws Exception {
assumeTrue("Skipping test: no multi-window support", supportsSplitScreenMultiWindow());
- setDeviceRotation(0);
+ try (final RotationSession rotationSession = new RotationSession()) {
+ rotationSession.set(ROTATION_0);
- final String logSeparator = clearLogcat();
- launchActivitiesInSplitScreen(LAUNCHING_ACTIVITY, RESIZEABLE_ACTIVITY_NAME);
- final ReportedSizes initialSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
- logSeparator);
+ final String logSeparator = clearLogcat();
+ launchActivitiesInSplitScreen(LAUNCHING_ACTIVITY, RESIZEABLE_ACTIVITY_NAME);
+ final ReportedSizes initialSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
+ logSeparator);
- rotateAndCheckSizes(initialSizes);
+ rotateAndCheckSizes(rotationSession, initialSizes);
+ }
}
- private void rotateAndCheckSizes(ReportedSizes prevSizes) throws Exception {
- for (int rotation = 3; rotation >= 0; --rotation) {
+ private void rotateAndCheckSizes(RotationSession rotationSession, ReportedSizes prevSizes)
+ throws Exception {
+ final int[] rotations = { ROTATION_270, ROTATION_180, ROTATION_90, ROTATION_0 };
+ for (final int rotation : rotations) {
final String logSeparator = clearLogcat();
final int actualStackId = mAmWmState.getAmState().getTaskByActivityName(
RESIZEABLE_ACTIVITY_NAME).mStackId;
final int displayId = mAmWmState.getAmState().getStackById(actualStackId).mDisplayId;
- setDeviceRotation(rotation);
+ rotationSession.set(rotation);
final int newDeviceRotation = getDeviceRotation(displayId);
if (newDeviceRotation == INVALID_DEVICE_ROTATION) {
logE("Got an invalid device rotation value. "
@@ -356,14 +370,16 @@
@Test
public void testNonFullscreenActivityPermitted() throws Exception {
- setDeviceRotation(0);
+ try (final RotationSession rotationSession = new RotationSession()) {
+ rotationSession.set(ROTATION_0);
- launchActivity(SDK26_TRANSLUCENT_LANDSCAPE_ACTIVITY);
- mAmWmState.assertResumedActivity(
- "target SDK <= 26 non-fullscreen activity should be allowed to launch",
- SDK26_TRANSLUCENT_LANDSCAPE_ACTIVITY);
- assertEquals("non-fullscreen activity requested landscape orientation",
- 0 /* landscape */, mAmWmState.getWmState().getLastOrientation());
+ launchActivity(SDK26_TRANSLUCENT_LANDSCAPE_ACTIVITY);
+ mAmWmState.assertResumedActivity(
+ "target SDK <= 26 non-fullscreen activity should be allowed to launch",
+ SDK26_TRANSLUCENT_LANDSCAPE_ACTIVITY);
+ assertEquals("non-fullscreen activity requested landscape orientation",
+ 0 /* landscape */, mAmWmState.getWmState().getLastOrientation());
+ }
}
/**
@@ -428,11 +444,12 @@
@Presubmit
@Test
public void testSplitscreenPortraitAppOrientationRequests() throws Exception {
- if (!supportsSplitScreenMultiWindow()) {
- log("Skipping test: no multi-window support");
- return;
+ assumeTrue("Skipping test: no multi-window support", supportsSplitScreenMultiWindow());
+
+ try (final RotationSession rotationSession = new RotationSession()) {
+ requestOrientationInSplitScreen(rotationSession,
+ ROTATION_90 /* portrait */, LANDSCAPE_ACTIVITY_NAME);
}
- requestOrientationInSplitScreen(1 /* portrait */, LANDSCAPE_ACTIVITY_NAME);
}
/**
@@ -441,23 +458,24 @@
@Presubmit
@Test
public void testSplitscreenLandscapeAppOrientationRequests() throws Exception {
- if (!supportsSplitScreenMultiWindow()) {
- log("Skipping test: no multi-window support");
- return;
+ assumeTrue("Skipping test: no multi-window support", supportsSplitScreenMultiWindow());
+
+ try (final RotationSession rotationSession = new RotationSession()) {
+ requestOrientationInSplitScreen(rotationSession,
+ ROTATION_0 /* landscape */, PORTRAIT_ACTIVITY_NAME);
}
- requestOrientationInSplitScreen(0 /* landscape */, PORTRAIT_ACTIVITY_NAME);
}
/**
* Rotate the device and launch specified activity in split-screen, checking if orientation
* didn't change.
*/
- private void requestOrientationInSplitScreen(int orientation, String activity)
- throws Exception {
+ private void requestOrientationInSplitScreen(RotationSession rotationSession, int orientation,
+ String activity) throws Exception {
assumeTrue("Skipping test: no multi-window support", supportsSplitScreenMultiWindow());
// Set initial orientation.
- setDeviceRotation(orientation);
+ rotationSession.set(orientation);
// Launch activities that request orientations and check that device doesn't rotate.
launchActivitiesInSplitScreen(
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java
index 3320944..718fe85 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java
@@ -30,6 +30,8 @@
import static org.junit.Assume.assumeTrue;
import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
+import android.server.am.settings.SettingsSession;
import android.support.test.filters.FlakyTest;
import org.junit.Test;
@@ -66,17 +68,19 @@
@Presubmit
public void testLaunchingAssistantActivityIntoAssistantStack() throws Exception {
// Enable the assistant and launch an assistant activity
- enableAssistant();
- launchActivity(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION);
- mAmWmState.waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
+ try (final AssistantSession assistantSession = new AssistantSession()) {
+ assistantSession.set(getActivityComponentName(VOICE_INTERACTION_SERVICE));
- // Ensure that the activity launched in the fullscreen assistant stack
- assertAssistantStackExists();
- assertTrue("Expected assistant stack to be fullscreen",
- mAmWmState.getAmState().getStackByActivityType(
- ACTIVITY_TYPE_ASSISTANT).isFullscreen());
+ launchActivity(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION);
+ mAmWmState.waitForValidStateWithActivityType(ASSISTANT_ACTIVITY,
+ ACTIVITY_TYPE_ASSISTANT);
- disableAssistant();
+ // Ensure that the activity launched in the fullscreen assistant stack
+ assertAssistantStackExists();
+ assertTrue("Expected assistant stack to be fullscreen",
+ mAmWmState.getAmState().getStackByActivityType(
+ ACTIVITY_TYPE_ASSISTANT).isFullscreen());
+ }
}
@FlakyTest(bugId = 69573940)
@@ -100,25 +104,25 @@
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD);
// Enable the assistant and launch an assistant activity, ensure it is on top
- enableAssistant();
- launchActivity(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION);
- mAmWmState.waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
- assertAssistantStackExists();
+ try (final AssistantSession assistantSession = new AssistantSession()) {
+ assistantSession.set(getActivityComponentName(VOICE_INTERACTION_SERVICE));
- mAmWmState.assertFrontStack("Pinned stack should be on top.",
- WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
- mAmWmState.assertFocusedStack("Assistant stack should be focused.",
- WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
+ launchActivity(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION);
+ mAmWmState.waitForValidStateWithActivityType(ASSISTANT_ACTIVITY,
+ ACTIVITY_TYPE_ASSISTANT);
+ assertAssistantStackExists();
- disableAssistant();
+ mAmWmState.assertFrontStack("Pinned stack should be on top.",
+ WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
+ mAmWmState.assertFocusedStack("Assistant stack should be focused.",
+ WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
+ }
}
@Test
@Presubmit
public void testAssistantStackLaunchNewTask() throws Exception {
- enableAssistant();
assertAssistantStackCanLaunchAndReturnFromNewTask();
- disableAssistant();
}
@Test
@@ -133,9 +137,7 @@
mAmWmState.assertContainsStack("Must contain docked stack.",
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD);
- enableAssistant();
assertAssistantStackCanLaunchAndReturnFromNewTask();
- disableAssistant();
}
private void assertAssistantStackCanLaunchAndReturnFromNewTask() throws Exception {
@@ -143,10 +145,12 @@
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD);
// Enable the assistant and launch an assistant activity which will launch a new task
- enableAssistant();
- launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
- EXTRA_LAUNCH_NEW_TASK, TEST_ACTIVITY);
- disableAssistant();
+ try (final AssistantSession assistantSession = new AssistantSession()) {
+ assistantSession.set(getActivityComponentName(VOICE_INTERACTION_SERVICE));
+
+ launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
+ EXTRA_LAUNCH_NEW_TASK, TEST_ACTIVITY);
+ }
final int expectedWindowingMode = inSplitScreenMode
? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
@@ -174,10 +178,12 @@
// Launch an assistant activity on top of an existing fullscreen activity, and ensure that
// the fullscreen activity is still visible and on top after the assistant activity finishes
launchActivity(TEST_ACTIVITY);
- enableAssistant();
- launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
- EXTRA_FINISH_SELF, "true");
- disableAssistant();
+ try (final AssistantSession assistantSession = new AssistantSession()) {
+ assistantSession.set(getActivityComponentName(VOICE_INTERACTION_SERVICE));
+
+ launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
+ EXTRA_FINISH_SELF, "true");
+ }
mAmWmState.waitForValidState(TEST_ACTIVITY,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
mAmWmState.waitForActivityState(TEST_ACTIVITY, STATE_RESUMED);
@@ -191,10 +197,12 @@
@Test
@Presubmit
public void testDisallowEnterPiPFromAssistantStack() throws Exception {
- enableAssistant();
- launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
- EXTRA_ENTER_PIP, "true");
- disableAssistant();
+ try (final AssistantSession assistantSession = new AssistantSession()) {
+ assistantSession.set(getActivityComponentName(VOICE_INTERACTION_SERVICE));
+
+ launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
+ EXTRA_ENTER_PIP, "true");
+ }
mAmWmState.waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
mAmWmState.assertDoesNotContainStack("Must not contain pinned stack.",
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
@@ -204,102 +212,107 @@
@Presubmit
@Test
public void testTranslucentAssistantActivityStackVisibility() throws Exception {
- enableAssistant();
- // Go home, launch the assistant and check to see that home is visible
- removeStacksInWindowingModes(WINDOWING_MODE_FULLSCREEN,
- WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
- launchHomeActivity();
- launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
- EXTRA_IS_TRANSLUCENT, String.valueOf(true));
- mAmWmState.waitForValidStateWithActivityType(
- TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
- assertAssistantStackExists();
- mAmWmState.waitForHomeActivityVisible();
- if (hasHomeScreen()) {
- mAmWmState.assertHomeActivityVisible(true);
- }
+ try (final AssistantSession assistantSession = new AssistantSession()) {
+ assistantSession.set(getActivityComponentName(VOICE_INTERACTION_SERVICE));
- // Launch a fullscreen app and then launch the assistant and check to see that it is
- // also visible
- removeStacksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
- launchActivity(TEST_ACTIVITY);
- launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
- EXTRA_IS_TRANSLUCENT, String.valueOf(true));
- mAmWmState.waitForValidStateWithActivityType(
- TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
- assertAssistantStackExists();
- mAmWmState.assertVisibility(TEST_ACTIVITY, true);
-
- // Go home, launch assistant, launch app into fullscreen with activity present, and go back.
- // Ensure home is visible.
- removeStacksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
- launchHomeActivity();
- launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
- EXTRA_IS_TRANSLUCENT, String.valueOf(true), EXTRA_LAUNCH_NEW_TASK,
- TEST_ACTIVITY);
- mAmWmState.waitForValidState(TEST_ACTIVITY,
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
- mAmWmState.assertHomeActivityVisible(false);
- pressBackButton();
- mAmWmState.waitForFocusedStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
- assertAssistantStackExists();
- mAmWmState.waitForHomeActivityVisible();
- if (hasHomeScreen()) {
- mAmWmState.assertHomeActivityVisible(true);
- }
-
- // Launch a fullscreen and docked app and then launch the assistant and check to see that it
- // is also visible
- if (supportsSplitScreenMultiWindow()) {
- removeStacksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
- launchActivitiesInSplitScreen(DOCKED_ACTIVITY, TEST_ACTIVITY);
- mAmWmState.assertContainsStack("Must contain docked stack.",
- WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD);
+ // Go home, launch the assistant and check to see that home is visible
+ removeStacksInWindowingModes(WINDOWING_MODE_FULLSCREEN,
+ WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+ launchHomeActivity();
launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
EXTRA_IS_TRANSLUCENT, String.valueOf(true));
mAmWmState.waitForValidStateWithActivityType(
TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
assertAssistantStackExists();
- mAmWmState.assertVisibility(DOCKED_ACTIVITY, true);
+ mAmWmState.waitForHomeActivityVisible();
+ if (hasHomeScreen()) {
+ mAmWmState.assertHomeActivityVisible(true);
+ }
+
+ // Launch a fullscreen app and then launch the assistant and check to see that it is
+ // also visible
+ removeStacksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
+ launchActivity(TEST_ACTIVITY);
+ launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
+ EXTRA_IS_TRANSLUCENT, String.valueOf(true));
+ mAmWmState.waitForValidStateWithActivityType(
+ TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
+ assertAssistantStackExists();
mAmWmState.assertVisibility(TEST_ACTIVITY, true);
+
+ // Go home, launch assistant, launch app into fullscreen with activity present, and go back.
+
+ // Ensure home is visible.
+ removeStacksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
+ launchHomeActivity();
+ launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
+ EXTRA_IS_TRANSLUCENT, String.valueOf(true), EXTRA_LAUNCH_NEW_TASK,
+ TEST_ACTIVITY);
+ mAmWmState.waitForValidState(TEST_ACTIVITY,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ mAmWmState.assertHomeActivityVisible(false);
+ pressBackButton();
+ mAmWmState.waitForFocusedStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
+ assertAssistantStackExists();
+ mAmWmState.waitForHomeActivityVisible();
+ if (hasHomeScreen()) {
+ mAmWmState.assertHomeActivityVisible(true);
+ }
+
+ // Launch a fullscreen and docked app and then launch the assistant and check to see
+ // that it
+ // is also visible
+ if (supportsSplitScreenMultiWindow()) {
+ removeStacksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
+ launchActivitiesInSplitScreen(DOCKED_ACTIVITY, TEST_ACTIVITY);
+ mAmWmState.assertContainsStack("Must contain docked stack.",
+ WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD);
+ launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
+ EXTRA_IS_TRANSLUCENT, String.valueOf(true));
+ mAmWmState.waitForValidStateWithActivityType(
+ TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
+ assertAssistantStackExists();
+ mAmWmState.assertVisibility(DOCKED_ACTIVITY, true);
+ mAmWmState.assertVisibility(TEST_ACTIVITY, true);
+ }
}
- disableAssistant();
}
@FlakyTest(bugId = 69229402)
@Test
@Presubmit
public void testLaunchIntoSameTask() throws Exception {
- enableAssistant();
+ try (final AssistantSession assistantSession = new AssistantSession()) {
+ assistantSession.set(getActivityComponentName(VOICE_INTERACTION_SERVICE));
- // Launch the assistant
- launchActivity(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION);
- assertAssistantStackExists();
- mAmWmState.assertVisibility(ASSISTANT_ACTIVITY, true);
- mAmWmState.assertFocusedStack("Expected assistant stack focused",
- WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
- assertEquals(1, mAmWmState.getAmState().getStackByActivityType(
- ACTIVITY_TYPE_ASSISTANT).getTasks().size());
- final int taskId = mAmWmState.getAmState().getTaskByActivityName(ASSISTANT_ACTIVITY)
- .mTaskId;
+ // Launch the assistant
+ launchActivity(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION);
+ assertAssistantStackExists();
+ mAmWmState.assertVisibility(ASSISTANT_ACTIVITY, true);
+ mAmWmState.assertFocusedStack("Expected assistant stack focused",
+ WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
+ assertEquals(1, mAmWmState.getAmState().getStackByActivityType(
+ ACTIVITY_TYPE_ASSISTANT).getTasks().size());
+ final int taskId = mAmWmState.getAmState().getTaskByActivityName(ASSISTANT_ACTIVITY)
+ .mTaskId;
- // Launch a new fullscreen activity
- // Using Animation Test Activity because it is opaque on all devices.
- launchActivity(ANIMATION_TEST_ACTIVITY);
- mAmWmState.assertVisibility(ASSISTANT_ACTIVITY, false);
+ // Launch a new fullscreen activity
+ // Using Animation Test Activity because it is opaque on all devices.
+ launchActivity(ANIMATION_TEST_ACTIVITY);
+ mAmWmState.assertVisibility(ASSISTANT_ACTIVITY, false);
- // Launch the assistant again and ensure that it goes into the same task
- launchActivity(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION);
- assertAssistantStackExists();
- mAmWmState.assertVisibility(ASSISTANT_ACTIVITY, true);
- mAmWmState.assertFocusedStack("Expected assistant stack focused",
- WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
- assertEquals(1, mAmWmState.getAmState().getStackByActivityType(
- ACTIVITY_TYPE_ASSISTANT).getTasks().size());
- assertEquals(taskId,
- mAmWmState.getAmState().getTaskByActivityName(ASSISTANT_ACTIVITY).mTaskId);
+ // Launch the assistant again and ensure that it goes into the same task
+ launchActivity(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION);
+ assertAssistantStackExists();
+ mAmWmState.assertVisibility(ASSISTANT_ACTIVITY, true);
+ mAmWmState.assertFocusedStack("Expected assistant stack focused",
+ WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
+ assertEquals(1, mAmWmState.getAmState().getStackByActivityType(
+ ACTIVITY_TYPE_ASSISTANT).getTasks().size());
+ assertEquals(taskId,
+ mAmWmState.getAmState().getTaskByActivityName(ASSISTANT_ACTIVITY).mTaskId);
- disableAssistant();
+ }
}
@Test
@@ -307,22 +320,24 @@
assumeTrue(supportsPip());
assumeTrue(supportsSplitScreenMultiWindow());
- enableAssistant();
+ try (final AssistantSession assistantSession = new AssistantSession()) {
+ assistantSession.set(getActivityComponentName(VOICE_INTERACTION_SERVICE));
- // Launch a fullscreen activity and a PIP activity, then launch the assistant, and ensure
- // that the test activity is still visible
- launchActivity(TEST_ACTIVITY);
- launchActivity(PIP_ACTIVITY, EXTRA_ENTER_PIP, "true");
- launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
- EXTRA_IS_TRANSLUCENT, String.valueOf(true));
- mAmWmState.waitForValidStateWithActivityType(
- TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
- assertAssistantStackExists();
- mAmWmState.assertVisibility(TRANSLUCENT_ASSISTANT_ACTIVITY, true);
- mAmWmState.assertVisibility(PIP_ACTIVITY, true);
- mAmWmState.assertVisibility(TEST_ACTIVITY, true);
+ // Launch a fullscreen activity and a PIP activity, then launch the assistant, and ensure
- disableAssistant();
+ // that the test activity is still visible
+ launchActivity(TEST_ACTIVITY);
+ launchActivity(PIP_ACTIVITY, EXTRA_ENTER_PIP, "true");
+ launchActivity(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
+ EXTRA_IS_TRANSLUCENT, String.valueOf(true));
+ mAmWmState.waitForValidStateWithActivityType(
+ TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
+ assertAssistantStackExists();
+ mAmWmState.assertVisibility(TRANSLUCENT_ASSISTANT_ACTIVITY, true);
+ mAmWmState.assertVisibility(PIP_ACTIVITY, true);
+ mAmWmState.assertVisibility(TEST_ACTIVITY, true);
+
+ }
}
/**
@@ -333,18 +348,13 @@
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
}
- /**
- * Sets the system voice interaction service.
+ /** Helper class to save, set, and restore
+ * {@link Settings.Secure#VOICE_INTERACTION_SERVICE} system preference.
*/
- private void enableAssistant() throws Exception {
- executeShellCommand("settings put secure voice_interaction_service " +
- getActivityComponentName(VOICE_INTERACTION_SERVICE));
- }
-
- /**
- * Resets the system voice interaction service.
- */
- private void disableAssistant() throws Exception {
- executeShellCommand("settings delete secure voice_interaction_service");
+ private static class AssistantSession extends SettingsSession<String> {
+ AssistantSession() {
+ super(Settings.Secure.getUriFor(Settings.Secure.VOICE_INTERACTION_SERVICE),
+ Settings.Secure::getString, Settings.Secure::putString);
+ }
}
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerConfigChangeTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerConfigChangeTests.java
index 19b8399..a6760c3 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerConfigChangeTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerConfigChangeTests.java
@@ -24,6 +24,8 @@
import static org.junit.Assert.fail;
import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
+import android.server.am.settings.SettingsSession;
import org.junit.Test;
@@ -82,60 +84,73 @@
testChangeFontScale(FONT_SCALE_NO_RELAUNCH_ACTIVITY_NAME, false /* relaunch */);
}
- private void testRotation(
- String activityName, int rotationStep, int numRelaunch, int numConfigChange)
- throws Exception {
+ private void testRotation(String activityName, int rotationStep, int numRelaunch,
+ int numConfigChange) throws Exception {
launchActivity(activityName);
final String[] waitForActivitiesVisible = new String[] {activityName};
mAmWmState.computeState(waitForActivitiesVisible);
final int initialRotation = 4 - rotationStep;
- setDeviceRotation(initialRotation);
- mAmWmState.computeState(waitForActivitiesVisible);
- final int actualStackId = mAmWmState.getAmState().getTaskByActivityName(
- activityName).mStackId;
- final int displayId = mAmWmState.getAmState().getStackById(actualStackId).mDisplayId;
- final int newDeviceRotation = getDeviceRotation(displayId);
- if (newDeviceRotation == INVALID_DEVICE_ROTATION) {
- logE("Got an invalid device rotation value. "
- + "Continuing the test despite of that, but it is likely to fail.");
- } else if (newDeviceRotation != initialRotation) {
- log("This device doesn't support user rotation "
- + "mode. Not continuing the rotation checks.");
- return;
- }
-
- for (int rotation = 0; rotation < 4; rotation += rotationStep) {
- final String logSeparator = clearLogcat();
- setDeviceRotation(rotation);
+ try (final RotationSession rotationSession = new RotationSession()) {
+ rotationSession.set(initialRotation);
mAmWmState.computeState(waitForActivitiesVisible);
- assertRelaunchOrConfigChanged(activityName, numRelaunch, numConfigChange, logSeparator);
+ final int actualStackId = mAmWmState.getAmState().getTaskByActivityName(
+ activityName).mStackId;
+ final int displayId = mAmWmState.getAmState().getStackById(actualStackId).mDisplayId;
+ final int newDeviceRotation = getDeviceRotation(displayId);
+ if (newDeviceRotation == INVALID_DEVICE_ROTATION) {
+ logE("Got an invalid device rotation value. "
+ + "Continuing the test despite of that, but it is likely to fail.");
+ } else if (newDeviceRotation != initialRotation) {
+ log("This device doesn't support user rotation "
+ + "mode. Not continuing the rotation checks.");
+ return;
+ }
+
+ for (int rotation = 0; rotation < 4; rotation += rotationStep) {
+ final String logSeparator = clearLogcat();
+ rotationSession.set(rotation);
+ mAmWmState.computeState(waitForActivitiesVisible);
+ assertRelaunchOrConfigChanged(activityName, numRelaunch, numConfigChange,
+ logSeparator);
+ }
+ }
+ }
+
+ /** Helper class to save, set, and restore font_scale preferences. */
+ private static class FontScaleSession extends SettingsSession<Float> {
+ FontScaleSession() {
+ super(Settings.System.getUriFor(Settings.System.FONT_SCALE),
+ Settings.System::getFloat,
+ Settings.System::putFloat);
}
}
private void testChangeFontScale(
String activityName, boolean relaunch) throws Exception {
- setFontScale(1.0f);
- String logSeparator = clearLogcat();
- launchActivity(activityName);
- final String[] waitForActivitiesVisible = new String[] {activityName};
- mAmWmState.computeState(waitForActivitiesVisible);
-
- final int densityDpi = getActivityDensityDpi(activityName, logSeparator);
-
- for (float fontScale = 0.85f; fontScale <= 1.3f; fontScale += 0.15f) {
- logSeparator = clearLogcat();
- setFontScale(fontScale);
+ try (final FontScaleSession fontScaleSession = new FontScaleSession()) {
+ fontScaleSession.set(1.0f);
+ String logSeparator = clearLogcat();
+ launchActivity(activityName);
+ final String[] waitForActivitiesVisible = new String[]{activityName};
mAmWmState.computeState(waitForActivitiesVisible);
- assertRelaunchOrConfigChanged(activityName, relaunch ? 1 : 0, relaunch ? 0 : 1,
- logSeparator);
- // Verify that the display metrics are updated, and therefore the text size is also
- // updated accordingly.
- assertExpectedFontPixelSize(activityName,
- scaledPixelsToPixels(EXPECTED_FONT_SIZE_SP, fontScale, densityDpi),
- logSeparator);
+ final int densityDpi = getActivityDensityDpi(activityName, logSeparator);
+
+ for (float fontScale = 0.85f; fontScale <= 1.3f; fontScale += 0.15f) {
+ logSeparator = clearLogcat();
+ fontScaleSession.set(fontScale);
+ mAmWmState.computeState(waitForActivitiesVisible);
+ assertRelaunchOrConfigChanged(activityName, relaunch ? 1 : 0, relaunch ? 0 : 1,
+ logSeparator);
+
+ // Verify that the display metrics are updated, and therefore the text size is also
+ // updated accordingly.
+ assertExpectedFontPixelSize(activityName,
+ scaledPixelsToPixels(EXPECTED_FONT_SIZE_SP, fontScale, densityDpi),
+ logSeparator);
+ }
}
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayTests.java
index 58143db..3229905 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayTests.java
@@ -1487,7 +1487,7 @@
*/
@Test
public void testMoveToEmptyDisplayOnLaunch() throws Exception {
- if (!supportsMultiDisplay()) { return; }
+ assumeTrue(supportsMultiDisplay());
// Launch activity with unique affinity, so it will the only one in its task.
launchActivity(LAUNCHING_ACTIVITY);
@@ -1550,28 +1550,32 @@
RESIZEABLE_ACTIVITY_NAME, logSeparator);
assertNotNull("Test activity must have reported initial sizes on launch", initialSizes);
- // Rotate primary display and check that activity on secondary display is not affected.
- rotateAndCheckSameSizes(RESIZEABLE_ACTIVITY_NAME);
+ try (final RotationSession rotationSession = new RotationSession()) {
+ // Rotate primary display and check that activity on secondary display is not affected.
+ rotateAndCheckSameSizes(rotationSession, RESIZEABLE_ACTIVITY_NAME);
- // Launch activity to secondary display when primary one is rotated.
- final int initialRotation = mAmWmState.getWmState().getRotation();
- setDeviceRotation((initialRotation + 1) % 4);
+ // Launch activity to secondary display when primary one is rotated.
+ final int initialRotation = mAmWmState.getWmState().getRotation();
+ rotationSession.set((initialRotation + 1) % 4);
- logSeparator = clearLogcat();
- launchActivityOnDisplay(TEST_ACTIVITY_NAME, newDisplay.mId);
- mAmWmState.waitForActivityState(TEST_ACTIVITY_NAME, STATE_RESUMED);
- mAmWmState.assertFocusedActivity("Focus must be on secondary display",
- TEST_ACTIVITY_NAME);
- final ReportedSizes testActivitySizes = getLastReportedSizesForActivity(
- TEST_ACTIVITY_NAME, logSeparator);
- assertEquals("Sizes of secondary display must not change after rotation of primary display",
- initialSizes, testActivitySizes);
+ logSeparator = clearLogcat();
+ launchActivityOnDisplay(TEST_ACTIVITY_NAME, newDisplay.mId);
+ mAmWmState.waitForActivityState(TEST_ACTIVITY_NAME, STATE_RESUMED);
+ mAmWmState.assertFocusedActivity("Focus must be on secondary display",
+ TEST_ACTIVITY_NAME);
+ final ReportedSizes testActivitySizes = getLastReportedSizesForActivity(
+ TEST_ACTIVITY_NAME, logSeparator);
+ assertEquals(
+ "Sizes of secondary display must not change after rotation of primary display",
+ initialSizes, testActivitySizes);
+ }
}
- private void rotateAndCheckSameSizes(String activityName) throws Exception {
+ private void rotateAndCheckSameSizes(RotationSession rotationSession, String activityName)
+ throws Exception {
for (int rotation = 3; rotation >= 0; --rotation) {
final String logSeparator = clearLogcat();
- setDeviceRotation(rotation);
+ rotationSession.set(rotation);
final ReportedSizes rotatedSizes = getLastReportedSizesForActivity(activityName,
logSeparator);
assertNull("Sizes must not change after rotation", rotatedSizes);
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java
index 22f1de0..5ba794d 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java
@@ -38,8 +38,10 @@
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
import android.server.am.ActivityManagerState.ActivityStack;
import android.server.am.ActivityManagerState.ActivityTask;
+import android.server.am.settings.SettingsSession;
import android.support.test.filters.FlakyTest;
import org.junit.Test;
@@ -196,22 +198,24 @@
// Launch a PIP activity
launchActivity(PIP_ACTIVITY, EXTRA_ENTER_PIP, "true");
- setDeviceRotation(ROTATION_0);
- WindowManagerState wmState = mAmWmState.getWmState();
- wmState.computeState();
- Rect defaultPipBounds = wmState.getDefaultPinnedStackBounds();
- Rect stableBounds = wmState.getStableBounds();
- assertTrue(defaultPipBounds.width() > 0 && defaultPipBounds.height() > 0);
- assertTrue(stableBounds.contains(defaultPipBounds));
+ try (final RotationSession rotationSession = new RotationSession()) {
+ rotationSession.set(ROTATION_0);
- setDeviceRotation(ROTATION_90);
- wmState = mAmWmState.getWmState();
- wmState.computeState();
- defaultPipBounds = wmState.getDefaultPinnedStackBounds();
- stableBounds = wmState.getStableBounds();
- assertTrue(defaultPipBounds.width() > 0 && defaultPipBounds.height() > 0);
- assertTrue(stableBounds.contains(defaultPipBounds));
- setDeviceRotation(ROTATION_0);
+ WindowManagerState wmState = mAmWmState.getWmState();
+ wmState.computeState();
+ Rect defaultPipBounds = wmState.getDefaultPinnedStackBounds();
+ Rect stableBounds = wmState.getStableBounds();
+ assertTrue(defaultPipBounds.width() > 0 && defaultPipBounds.height() > 0);
+ assertTrue(stableBounds.contains(defaultPipBounds));
+
+ rotationSession.set(ROTATION_90);
+ wmState = mAmWmState.getWmState();
+ wmState.computeState();
+ defaultPipBounds = wmState.getDefaultPinnedStackBounds();
+ stableBounds = wmState.getStableBounds();
+ assertTrue(defaultPipBounds.width() > 0 && defaultPipBounds.height() > 0);
+ assertTrue(stableBounds.contains(defaultPipBounds));
+ }
}
@Test
@@ -221,22 +225,23 @@
// Launch a PIP activity
launchActivity(PIP_ACTIVITY, EXTRA_ENTER_PIP, "true");
- setDeviceRotation(ROTATION_0);
- WindowManagerState wmState = mAmWmState.getWmState();
- wmState.computeState();
- Rect pipMovementBounds = wmState.getPinnedStackMomentBounds();
- Rect stableBounds = wmState.getStableBounds();
- assertTrue(pipMovementBounds.width() > 0 && pipMovementBounds.height() > 0);
- assertTrue(stableBounds.contains(pipMovementBounds));
+ try (final RotationSession rotationSession = new RotationSession()) {
+ rotationSession.set(ROTATION_0);
+ WindowManagerState wmState = mAmWmState.getWmState();
+ wmState.computeState();
+ Rect pipMovementBounds = wmState.getPinnedStackMomentBounds();
+ Rect stableBounds = wmState.getStableBounds();
+ assertTrue(pipMovementBounds.width() > 0 && pipMovementBounds.height() > 0);
+ assertTrue(stableBounds.contains(pipMovementBounds));
- setDeviceRotation(ROTATION_90);
- wmState = mAmWmState.getWmState();
- wmState.computeState();
- pipMovementBounds = wmState.getPinnedStackMomentBounds();
- stableBounds = wmState.getStableBounds();
- assertTrue(pipMovementBounds.width() > 0 && pipMovementBounds.height() > 0);
- assertTrue(stableBounds.contains(pipMovementBounds));
- setDeviceRotation(ROTATION_0);
+ rotationSession.set(ROTATION_90);
+ wmState = mAmWmState.getWmState();
+ wmState.computeState();
+ pipMovementBounds = wmState.getPinnedStackMomentBounds();
+ stableBounds = wmState.getStableBounds();
+ assertTrue(pipMovementBounds.width() > 0 && pipMovementBounds.height() > 0);
+ assertTrue(stableBounds.contains(pipMovementBounds));
+ }
}
@Test
@@ -282,15 +287,16 @@
mAmWmState.waitForValidState(PIP_ACTIVITY, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
// Ensure that the PIP stack is fully visible in each orientation
- setDeviceRotation(ROTATION_0);
- assertPinnedStackActivityIsInDisplayBounds(PIP_ACTIVITY);
- setDeviceRotation(ROTATION_90);
- assertPinnedStackActivityIsInDisplayBounds(PIP_ACTIVITY);
- setDeviceRotation(ROTATION_180);
- assertPinnedStackActivityIsInDisplayBounds(PIP_ACTIVITY);
- setDeviceRotation(ROTATION_270);
- assertPinnedStackActivityIsInDisplayBounds(PIP_ACTIVITY);
- setDeviceRotation(ROTATION_0);
+ try (final RotationSession rotationSession = new RotationSession()) {
+ rotationSession.set(ROTATION_0);
+ assertPinnedStackActivityIsInDisplayBounds(PIP_ACTIVITY);
+ rotationSession.set(ROTATION_90);
+ assertPinnedStackActivityIsInDisplayBounds(PIP_ACTIVITY);
+ rotationSession.set(ROTATION_180);
+ assertPinnedStackActivityIsInDisplayBounds(PIP_ACTIVITY);
+ rotationSession.set(ROTATION_270);
+ assertPinnedStackActivityIsInDisplayBounds(PIP_ACTIVITY);
+ }
}
@Test
@@ -836,38 +842,48 @@
assertValidPictureInPictureCallbackOrder(PIP_ACTIVITY, logSeparator);
}
+ /** Helper class to save, set, and restore transition_animation_scale preferences. */
+ private static class TransitionAnimationScaleSession extends SettingsSession<Float> {
+ TransitionAnimationScaleSession() {
+ super(Settings.Global.getUriFor(Settings.Global.TRANSITION_ANIMATION_SCALE),
+ Settings.Global::getFloat,
+ Settings.Global::putFloat);
+ }
+ }
+
@Test
public void testEnterPipInterruptedCallbacks() throws Exception {
assumeTrue(supportsPip());
- // Slow down the transition animations for this test
- setWindowTransitionAnimationDurationScale(20);
+ try (final TransitionAnimationScaleSession transitionAnimationScaleSession =
+ new TransitionAnimationScaleSession()) {
+ // Slow down the transition animations for this test
+ transitionAnimationScaleSession.set(20f);
- // Launch a PiP activity
- launchActivity(PIP_ACTIVITY, EXTRA_ENTER_PIP, "true");
- // Wait until the PiP activity has moved into the pinned stack (happens before the
- // transition has started)
- mAmWmState.waitForValidState(PIP_ACTIVITY, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
- assertPinnedStackExists();
+ // Launch a PiP activity
+ launchActivity(PIP_ACTIVITY, EXTRA_ENTER_PIP, "true");
+ // Wait until the PiP activity has moved into the pinned stack (happens before the
+ // transition has started)
+ mAmWmState.waitForValidState(PIP_ACTIVITY, WINDOWING_MODE_PINNED,
+ ACTIVITY_TYPE_STANDARD);
+ assertPinnedStackExists();
- // Relaunch the PiP activity back into fullscreen
- String logSeparator = clearLogcat();
- launchActivity(PIP_ACTIVITY);
- // Wait until the PiP activity is reparented into the fullscreen stack (happens after the
- // transition has finished)
- mAmWmState.waitForValidState(
- PIP_ACTIVITY, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ // Relaunch the PiP activity back into fullscreen
+ String logSeparator = clearLogcat();
+ launchActivity(PIP_ACTIVITY);
+ // Wait until the PiP activity is reparented into the fullscreen stack (happens after
+ // the transition has finished)
+ mAmWmState.waitForValidState(
+ PIP_ACTIVITY, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
- // Ensure that we get the callbacks indicating that PiP/MW mode was cancelled, but no
- // configuration change (since none was sent)
- final ActivityLifecycleCounts lifecycleCounts = new ActivityLifecycleCounts(
- PIP_ACTIVITY, logSeparator);
- assertTrue(lifecycleCounts.mConfigurationChangedCount == 0);
- assertTrue(lifecycleCounts.mPictureInPictureModeChangedCount == 1);
- assertTrue(lifecycleCounts.mMultiWindowModeChangedCount == 1);
-
- // Reset the animation scale
- setWindowTransitionAnimationDurationScale(1);
+ // Ensure that we get the callbacks indicating that PiP/MW mode was cancelled, but no
+ // configuration change (since none was sent)
+ final ActivityLifecycleCounts lifecycleCounts = new ActivityLifecycleCounts(
+ PIP_ACTIVITY, logSeparator);
+ assertTrue(lifecycleCounts.mConfigurationChangedCount == 0);
+ assertTrue(lifecycleCounts.mPictureInPictureModeChangedCount == 1);
+ assertTrue(lifecycleCounts.mMultiWindowModeChangedCount == 1);
+ }
}
@FlakyTest(bugId = 71564769)
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
index 2e3209e..8c793b9 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
@@ -27,6 +27,10 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.server.am.WindowManagerState.TRANSIT_WALLPAPER_OPEN;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -348,22 +352,24 @@
// Each time we compute the state we implicitly assert valid bounds.
String[] waitForActivitiesVisible =
new String[] {LAUNCHING_ACTIVITY, TEST_ACTIVITY_NAME};
- for (int i = 0; i < 4; i++) {
- setDeviceRotation(i);
+ try (final RotationSession rotationSession = new RotationSession()) {
+ for (int i = 0; i < 4; i++) {
+ rotationSession.set(i);
+ mAmWmState.computeState(waitForActivitiesVisible);
+ }
+ // Double steps (180°) We ended the single step at 3. So, we jump directly to 1 for
+ // double step. So, we are testing 3-1-3 for one side and 0-2-0 for the other side.
+ rotationSession.set(ROTATION_90);
+ mAmWmState.computeState(waitForActivitiesVisible);
+ rotationSession.set(ROTATION_270);
+ mAmWmState.computeState(waitForActivitiesVisible);
+ rotationSession.set(ROTATION_0);
+ mAmWmState.computeState(waitForActivitiesVisible);
+ rotationSession.set(ROTATION_180);
+ mAmWmState.computeState(waitForActivitiesVisible);
+ rotationSession.set(ROTATION_0);
mAmWmState.computeState(waitForActivitiesVisible);
}
- // Double steps (180°) We ended the single step at 3. So, we jump directly to 1 for double
- // step. So, we are testing 3-1-3 for one side and 0-2-0 for the other side.
- setDeviceRotation(1);
- mAmWmState.computeState(waitForActivitiesVisible);
- setDeviceRotation(3);
- mAmWmState.computeState(waitForActivitiesVisible);
- setDeviceRotation(0);
- mAmWmState.computeState(waitForActivitiesVisible);
- setDeviceRotation(2);
- mAmWmState.computeState(waitForActivitiesVisible);
- setDeviceRotation(0);
- mAmWmState.computeState(waitForActivitiesVisible);
}
@Test
@@ -377,27 +383,31 @@
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD);
String[] waitForActivitiesVisible =
- new String[] {LAUNCHING_ACTIVITY, TEST_ACTIVITY_NAME};
- for (int i = 0; i < 4; i++) {
- sleepDevice();
- setDeviceRotation(i);
- wakeUpAndUnlockDevice();
- mAmWmState.computeState(waitForActivitiesVisible);
+ new String[] {LAUNCHING_ACTIVITY, TEST_ACTIVITY_NAME};
+ try (final RotationSession rotationSession = new RotationSession()) {
+ for (int i = 0; i < 4; i++) {
+ sleepDevice();
+ rotationSession.set(i);
+ wakeUpAndUnlockDevice();
+ mAmWmState.computeState(waitForActivitiesVisible);
+ }
}
}
@Test
public void testMinimizedFromEachDockedSide() throws Exception {
- for (int i = 0; i < 2; i++) {
- setDeviceRotation(i);
- launchActivityInDockStackAndMinimize(TEST_ACTIVITY_NAME);
- if (!mAmWmState.isScreenPortrait() && isTablet()) {
- // Test minimize to the right only on tablets in landscape
+ try (final RotationSession rotationSession = new RotationSession()) {
+ for (int i = 0; i < 2; i++) {
+ rotationSession.set(i);
+ launchActivityInDockStackAndMinimize(TEST_ACTIVITY_NAME);
+ if (!mAmWmState.isScreenPortrait() && isTablet()) {
+ // Test minimize to the right only on tablets in landscape
+ removeStacksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME);
+ launchActivityInDockStackAndMinimize(TEST_ACTIVITY_NAME,
+ SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT);
+ }
removeStacksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME);
- launchActivityInDockStackAndMinimize(TEST_ACTIVITY_NAME,
- SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT);
}
- removeStacksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME);
}
}
@@ -409,50 +419,55 @@
// Rotate device single steps (90°) 0-1-2-3.
// Each time we compute the state we implicitly assert valid bounds in minimized mode.
String[] waitForActivitiesVisible = new String[] {TEST_ACTIVITY_NAME};
- for (int i = 0; i < 4; i++) {
- setDeviceRotation(i);
+ try (final RotationSession rotationSession = new RotationSession()) {
+ for (int i = 0; i < 4; i++) {
+ rotationSession.set(i);
+ mAmWmState.computeState(waitForActivitiesVisible);
+ }
+
+ // Double steps (180°) We ended the single step at 3. So, we jump directly to 1 for
+ // double step. So, we are testing 3-1-3 for one side and 0-2-0 for the other side in
+ // minimized mode.
+ rotationSession.set(ROTATION_90);
+ mAmWmState.computeState(waitForActivitiesVisible);
+ rotationSession.set(ROTATION_270);
+ mAmWmState.computeState(waitForActivitiesVisible);
+ rotationSession.set(ROTATION_0);
+ mAmWmState.computeState(waitForActivitiesVisible);
+ rotationSession.set(ROTATION_180);
+ mAmWmState.computeState(waitForActivitiesVisible);
+ rotationSession.set(ROTATION_0);
mAmWmState.computeState(waitForActivitiesVisible);
}
-
- // Double steps (180°) We ended the single step at 3. So, we jump directly to 1 for double
- // step. So, we are testing 3-1-3 for one side and 0-2-0 for the other side in minimized
- // mode.
- setDeviceRotation(1);
- mAmWmState.computeState(waitForActivitiesVisible);
- setDeviceRotation(3);
- mAmWmState.computeState(waitForActivitiesVisible);
- setDeviceRotation(0);
- mAmWmState.computeState(waitForActivitiesVisible);
- setDeviceRotation(2);
- mAmWmState.computeState(waitForActivitiesVisible);
- setDeviceRotation(0);
- mAmWmState.computeState(waitForActivitiesVisible);
}
@Test
public void testMinimizeAndUnminimizeThenGoingHome() throws Exception {
// Rotate the screen to check that minimize, unminimize, dismiss the docked stack and then
// going home has the correct app transition
- for (int i = 0; i < 4; i++) {
- setDeviceRotation(i);
- launchActivityInDockStackAndMinimize(DOCKED_ACTIVITY_NAME);
+ try (final RotationSession rotationSession = new RotationSession()) {
+ for (int i = 0; i < 4; i++) {
+ rotationSession.set(i);
+ launchActivityInDockStackAndMinimize(DOCKED_ACTIVITY_NAME);
- // Unminimize the docked stack
- pressAppSwitchButton();
- waitForDockNotMinimized();
- assertDockNotMinimized();
+ // Unminimize the docked stack
+ pressAppSwitchButton();
+ waitForDockNotMinimized();
+ assertDockNotMinimized();
- // Dismiss the dock stack
- launchActivity(TEST_ACTIVITY_NAME, WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
- setActivityTaskWindowingMode(DOCKED_ACTIVITY_NAME,
- WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
- mAmWmState.computeState(new String[]{DOCKED_ACTIVITY_NAME});
+ // Dismiss the dock stack
+ launchActivity(TEST_ACTIVITY_NAME,
+ WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
+ setActivityTaskWindowingMode(DOCKED_ACTIVITY_NAME,
+ WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
+ mAmWmState.computeState(new String[]{DOCKED_ACTIVITY_NAME});
- // Go home and check the app transition
- assertNotSame(TRANSIT_WALLPAPER_OPEN, mAmWmState.getWmState().getLastTransition());
- pressHomeButton();
- mAmWmState.computeState();
- assertEquals(TRANSIT_WALLPAPER_OPEN, mAmWmState.getWmState().getLastTransition());
+ // Go home and check the app transition
+ assertNotSame(TRANSIT_WALLPAPER_OPEN, mAmWmState.getWmState().getLastTransition());
+ pressHomeButton();
+ mAmWmState.computeState();
+ assertEquals(TRANSIT_WALLPAPER_OPEN, mAmWmState.getWmState().getLastTransition());
+ }
}
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
index 7a20d1f..2c7c554 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
@@ -18,7 +18,9 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.view.Surface.ROTATION_90;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -284,16 +286,18 @@
mAmWmState.waitForKeyguardShowingAndNotOccluded();
mAmWmState.assertKeyguardShowingAndNotOccluded();
executeShellCommand(getAmStartCmd("ShowWhenLockedActivity"));
- mAmWmState.computeState(new WaitForValidActivityState.Builder("ShowWhenLockedActivity").build());
+ mAmWmState.computeState(new WaitForValidActivityState("ShowWhenLockedActivity"));
mAmWmState.assertVisibility("ShowWhenLockedActivity", true);
- setDeviceRotation(1);
- pressHomeButton();
- mAmWmState.waitForKeyguardShowingAndNotOccluded();
- mAmWmState.waitForDisplayUnfrozen();
- mAmWmState.assertSanity();
- mAmWmState.assertHomeActivityVisible(false);
- mAmWmState.assertKeyguardShowingAndNotOccluded();
- mAmWmState.assertVisibility("ShowWhenLockedActivity", false);
+ try (final RotationSession rotationSession = new RotationSession()) {
+ rotationSession.set(ROTATION_90);
+ pressHomeButton();
+ mAmWmState.waitForKeyguardShowingAndNotOccluded();
+ mAmWmState.waitForDisplayUnfrozen();
+ mAmWmState.assertSanity();
+ mAmWmState.assertHomeActivityVisible(false);
+ mAmWmState.assertKeyguardShowingAndNotOccluded();
+ mAmWmState.assertVisibility("ShowWhenLockedActivity", false);
+ }
}
private void assertWallpaperShowing() {
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
index 2acd049..7fe707a 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
@@ -44,10 +44,12 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.os.ParcelFileDescriptor;
+import android.provider.Settings;
+import android.server.am.settings.SettingsSession;
+import android.support.annotation.NonNull;
import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiDevice;
import android.view.Display;
-import android.view.Surface;
import com.android.compatibility.common.util.SystemUtil;
@@ -236,10 +238,6 @@
protected ActivityAndWindowManagersState mAmWmState = new ActivityAndWindowManagersState();
- private int mInitialAccelerometerRotation;
- private int mUserRotation;
- private float mFontScale;
-
private SurfaceTraceReceiver mSurfaceTraceReceiver;
private Thread mSurfaceTraceThread;
@@ -276,10 +274,6 @@
wakeUpAndUnlockDevice();
pressHomeButton();
removeStacksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME);
- // Store rotation settings.
- mInitialAccelerometerRotation = getAccelerometerRotation();
- mUserRotation = getUserRotation();
- mFontScale = getFontScale();
mLockCredentialsSet = false;
mLockDisabled = isLockDisabled();
}
@@ -290,11 +284,6 @@
executeShellCommand(AM_FORCE_STOP_TEST_PACKAGE);
executeShellCommand(AM_FORCE_STOP_SECOND_TEST_PACKAGE);
executeShellCommand(AM_FORCE_STOP_THIRD_TEST_PACKAGE);
- // Restore rotation settings to the state they were before test.
- setAccelerometerRotation(mInitialAccelerometerRotation);
- setUserRotation(mUserRotation);
- setFontScale(mFontScale);
- setWindowTransitionAnimationDurationScale(1);
removeStacksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME);
wakeUpAndUnlockDevice();
pressHomeButton();
@@ -782,14 +771,34 @@
runCommandAndPrintOutput("locksettings set-disabled " + lockDisabled);
}
- /**
- * Sets the device rotation, value corresponds to one of {@link Surface#ROTATION_0},
- * {@link Surface#ROTATION_90}, {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}.
- */
- protected void setDeviceRotation(int rotation) throws Exception {
- setAccelerometerRotation(0);
- setUserRotation(rotation);
- mAmWmState.waitForRotation(rotation);
+ /** Helper class to save, set & wait, and restore rotation related preferences. */
+ protected class RotationSession extends SettingsSession<Integer> {
+ private final SettingsSession<Integer> mUserRotation;
+
+ RotationSession() throws Exception {
+ // Save accelerometer_rotation preference.
+ super(Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION),
+ Settings.System::getInt, Settings.System::putInt);
+ mUserRotation = new SettingsSession<>(
+ Settings.System.getUriFor(Settings.System.USER_ROTATION),
+ Settings.System::getInt, Settings.System::putInt);
+ // Disable accelerometer_rotation.
+ super.set(0);
+ }
+
+ @Override
+ public void set(@NonNull Integer value) throws Exception {
+ mUserRotation.set(value);
+ // Wait for settling rotation.
+ mAmWmState.waitForRotation(value);
+ }
+
+ @Override
+ public void close() throws Exception {
+ mUserRotation.close();
+ // Restore accelerometer_rotation preference.
+ super.close();
+ }
}
protected int getDeviceRotation(int displayId) {
@@ -798,7 +807,7 @@
"(mDisplayId=" + displayId + ")([\\s\\S]*)(mOverrideDisplayInfo)(.*)"
+ "(rotation)(\\s+)(\\d+)");
Matcher matcher = pattern.matcher(displays);
- while (matcher.find()) {
+ if (matcher.find()) {
final String match = matcher.group(7);
return Integer.parseInt(match);
}
@@ -806,63 +815,6 @@
return INVALID_DEVICE_ROTATION;
}
- private int getAccelerometerRotation() {
- final String rotation =
- runCommandAndPrintOutput("settings get system accelerometer_rotation");
- return Integer.parseInt(rotation.trim());
- }
-
- private void setAccelerometerRotation(int rotation) {
- runCommandAndPrintOutput(
- "settings put system accelerometer_rotation " + rotation);
- }
-
- protected int getUserRotation() {
- final String rotation =
- runCommandAndPrintOutput("settings get system user_rotation").trim();
- if ("null".equals(rotation)) {
- return -1;
- }
- return Integer.parseInt(rotation);
- }
-
- private void setUserRotation(int rotation) {
- if (rotation == -1) {
- runCommandAndPrintOutput(
- "settings delete system user_rotation");
- } else {
- runCommandAndPrintOutput(
- "settings put system user_rotation " + rotation);
- }
- }
-
- protected void setFontScale(float fontScale) {
- if (fontScale == 0.0f) {
- runCommandAndPrintOutput(
- "settings delete system font_scale");
- } else {
- runCommandAndPrintOutput(
- "settings put system font_scale " + fontScale);
- }
- }
-
- protected void setWindowTransitionAnimationDurationScale(float animDurationScale) {
- runCommandAndPrintOutput(
- "settings put global transition_animation_scale " + animDurationScale);
- }
-
- protected float getFontScale() {
- try {
- final String fontScale =
- runCommandAndPrintOutput("settings get system font_scale").trim();
- return Float.parseFloat(fontScale);
- } catch (NumberFormatException e) {
- // If we don't have a valid font scale key, return 0.0f now so
- // that we delete the key in tearDown().
- return 0.0f;
- }
- }
-
protected String runCommandAndPrintOutput(String command) {
final String output = executeShellCommand(command);
log(output);
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/settings/SettingsSession.java b/tests/framework/base/activitymanager/util/src/android/server/am/settings/SettingsSession.java
new file mode 100644
index 0000000..9877209
--- /dev/null
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/settings/SettingsSession.java
@@ -0,0 +1,164 @@
+package android.server.am.settings;
+
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.provider.Settings.SettingNotFoundException;
+import android.support.annotation.NonNull;
+import android.support.test.InstrumentationRegistry;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Helper class to save, set, and restore global system-level preferences.
+ * <p>
+ * To use this class, testing APK must be self-instrumented and have
+ * {@link android.Manifest.permission#WRITE_SECURE_SETTINGS}.
+ * <p>
+ * A test that changes system-level preferences can be written easily and reliably.
+ * <pre>
+ * static class PrefSession extends SettingsSession<String> {
+ * PrefSession() {
+ * super(android.provider.Settings.Secure.getUriFor(
+ * android.provider.Settings.Secure.PREFERENCE_KEY),
+ * android.provider.Settings.Secure::getString,
+ * android.provider.Settings.Secure::putString);
+ * }
+ * }
+ *
+ * @Test
+ * public void doTest() throws Exception {
+ * try (final PrefSession prefSession = new PrefSession()) {
+ * prefSession.set("value 1");
+ * doTest1();
+ * prefSession.set("value 2");
+ * doTest2();
+ * }
+ * }
+ * </pre>
+ */
+public class SettingsSession<T> implements AutoCloseable {
+ private static final String TAG = SettingsSession.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ @FunctionalInterface
+ public interface SettingsGetter<T> {
+ T get(ContentResolver cr, String key) throws SettingNotFoundException;
+ }
+
+ @FunctionalInterface
+ public interface SettingsSetter<T> {
+ void set(ContentResolver cr, String key, T value);
+ }
+
+ /**
+ * To debug to detect nested sessions for the same key. Enabled when {@link #DEBUG} is true.
+ * Note that nested sessions can be merged into one session.
+ */
+ private static final SessionCounters sSessionCounters = new SessionCounters();
+
+ private final Uri mUri;
+ private final SettingsGetter<T> mGetter;
+ private final SettingsSetter<T> mSetter;
+ private final boolean mHasInitialValue;
+ private final T mInitialValue;
+
+ public SettingsSession(final Uri uri, final SettingsGetter<T> getter,
+ final SettingsSetter<T> setter) {
+ mUri = uri;
+ mGetter = getter;
+ mSetter = setter;
+ T initialValue;
+ boolean hasInitialValue;
+ try {
+ initialValue = get(uri, getter);
+ hasInitialValue = true;
+ } catch (SettingNotFoundException e) {
+ initialValue = null;
+ hasInitialValue = false;
+ }
+ mInitialValue = initialValue;
+ mHasInitialValue = hasInitialValue;
+ if (DEBUG) {
+ Log.i(TAG, "start: uri=" + uri
+ + (mHasInitialValue ? " value=" + mInitialValue : " undefined"));
+ sSessionCounters.open(uri);
+ }
+ }
+
+ public void set(final @NonNull T value) throws Exception {
+ put(mUri, mSetter, value);
+ if (DEBUG) {
+ Log.i(TAG, " set: uri=" + mUri + " value=" + value);
+ }
+ }
+
+ public T get() throws SettingNotFoundException {
+ return get(mUri, mGetter);
+ }
+
+ @Override
+ public void close() throws Exception {
+ if (mHasInitialValue) {
+ put(mUri, mSetter, mInitialValue);
+ if (DEBUG) {
+ Log.i(TAG, "close: uri=" + mUri + " value=" + mInitialValue);
+ }
+ } else {
+ try {
+ delete(mUri);
+ if (DEBUG) {
+ Log.i(TAG, "close: uri=" + mUri + " deleted");
+ }
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "Can't delete settings " + mUri, e);
+ }
+ }
+ if (DEBUG) {
+ sSessionCounters.close(mUri);
+ }
+ }
+
+ private static <T> void put(final Uri uri, final SettingsSetter<T> setter, T value)
+ throws SettingNotFoundException {
+ setter.set(getContentResolver(), uri.getLastPathSegment(), value);
+ }
+
+ private static <T> T get(final Uri uri, final SettingsGetter<T> getter)
+ throws SettingNotFoundException {
+ return getter.get(getContentResolver(), uri.getLastPathSegment());
+ }
+
+ private static void delete(final Uri uri) throws IllegalArgumentException {
+ getContentResolver().delete(uri, null, null);
+ }
+
+ private static ContentResolver getContentResolver() {
+ return InstrumentationRegistry.getTargetContext().getContentResolver();
+ }
+
+ private static class SessionCounters {
+ private final Map<Uri, Integer> mOpenSessions = new HashMap<>();
+
+ void open(final Uri uri) {
+ final Integer count = mOpenSessions.get(uri);
+ if (count == null) {
+ mOpenSessions.put(uri, 1);
+ return;
+ }
+ mOpenSessions.put(uri, count + 1);
+ Log.w(TAG, "Open nested session for " + uri, new Throwable());
+ }
+
+ void close(final Uri uri) {
+ final int count = mOpenSessions.get(uri);
+ if (count == 1) {
+ mOpenSessions.remove(uri);
+ return;
+ }
+ mOpenSessions.put(uri, count - 1);
+ Log.w(TAG, "Close nested session for " + uri, new Throwable());
+ }
+ }
+}
diff --git a/tests/signature/api-check/src/android/signature/cts/api/BootClassPathClassesProvider.java b/tests/signature/api-check/src/android/signature/cts/api/BootClassPathClassesProvider.java
new file mode 100644
index 0000000..e2c92b3
--- /dev/null
+++ b/tests/signature/api-check/src/android/signature/cts/api/BootClassPathClassesProvider.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.signature.cts.api;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.stream.Stream;
+
+import android.signature.cts.ClassProvider;
+import dalvik.system.DexFile;
+
+@SuppressWarnings("deprecation")
+public class BootClassPathClassesProvider extends ClassProvider {
+ private Stream<Class<?>> allClasses = null;
+
+ @Override
+ public Stream<Class<?>> getAllClasses() {
+ Stream.Builder<Class<?>> builder = Stream.builder();
+ if (allClasses == null) {
+ for (String file : getBootJarPaths()) {
+ try {
+ DexFile dexFile = new DexFile(file);
+ Enumeration<String> entries = dexFile.entries();
+ while (entries.hasMoreElements()) {
+ String className = entries.nextElement();
+ Class<?> clazz = getClass(className);
+ if (clazz != null) {
+ builder.add(clazz);
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to parse dex in " + file, e);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("Error while loading class in " + file, e);
+ }
+ }
+ allClasses = builder.build();
+ }
+ return allClasses;
+ }
+
+ private String[] getBootJarPaths() {
+ return System.getProperty("java.boot.class.path").split(":");
+ }
+
+}
diff --git a/tests/signature/api-check/src/android/signature/cts/api/SignatureTest.java b/tests/signature/api-check/src/android/signature/cts/api/SignatureTest.java
index 1ec58d7..4240588 100644
--- a/tests/signature/api-check/src/android/signature/cts/api/SignatureTest.java
+++ b/tests/signature/api-check/src/android/signature/cts/api/SignatureTest.java
@@ -18,8 +18,10 @@
import android.os.Bundle;
import android.signature.cts.ApiDocumentParser;
+import android.signature.cts.ClassProvider;
import android.signature.cts.ApiComplianceChecker;
import android.signature.cts.FailureType;
+import android.signature.cts.ExcludingClassProvider;
import android.signature.cts.JDiffClassDescription;
import android.signature.cts.ReflectionHelper;
import android.signature.cts.ResultObserver;
@@ -30,6 +32,8 @@
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
+import java.util.function.Predicate;
+
import org.xmlpull.v1.XmlPullParserException;
import repackaged.android.test.InstrumentationTestCase;
import repackaged.android.test.InstrumentationTestRunner;
@@ -114,9 +118,16 @@
*/
public void testSignature() {
try {
+
+ // Prepare for a class provider that loads classes from bootclasspath but filters
+ // out known inaccessible classes
+ ClassProvider classProvider = new ExcludingClassProvider(
+ new BootClassPathClassesProvider(),
+ KNOWN_INACCESSIBLE_CLASSES::contains);
+
Set<JDiffClassDescription> unexpectedClasses = loadUnexpectedClasses();
for (JDiffClassDescription classDescription : unexpectedClasses) {
- Class<?> unexpectedClass = findUnexpectedClass(classDescription);
+ Class<?> unexpectedClass = findUnexpectedClass(classDescription, classProvider);
if (unexpectedClass != null) {
mResultObserver.notifyFailure(
FailureType.UNEXPECTED_CLASS,
@@ -125,7 +136,8 @@
}
}
- ApiComplianceChecker complianceChecker = new ApiComplianceChecker(mResultObserver);
+ ApiComplianceChecker complianceChecker = new ApiComplianceChecker(mResultObserver,
+ classProvider);
ApiDocumentParser apiDocumentParser = new ApiDocumentParser(
TAG, new ApiDocumentParser.Listener() {
@Override
@@ -162,9 +174,10 @@
}
}
- private Class<?> findUnexpectedClass(JDiffClassDescription classDescription) {
+ private Class<?> findUnexpectedClass(JDiffClassDescription classDescription,
+ ClassProvider classProvider) {
try {
- return ReflectionHelper.findMatchingClass(classDescription);
+ return ReflectionHelper.findMatchingClass(classDescription, classProvider);
} catch (ClassNotFoundException e) {
return null;
}
diff --git a/tests/signature/api-check/system-current-api/Android.mk b/tests/signature/api-check/system-current-api/Android.mk
index 1c10d2c..34c6c22 100644
--- a/tests/signature/api-check/system-current-api/Android.mk
+++ b/tests/signature/api-check/system-current-api/Android.mk
@@ -20,6 +20,7 @@
LOCAL_SIGNATURE_API_FILES := \
system-current.api \
+ system-removed.api \
android-test-mock-current.api \
android-test-runner-current.api \
diff --git a/tests/signature/api-check/system-current-api/AndroidTest.xml b/tests/signature/api-check/system-current-api/AndroidTest.xml
index 31ee887..6c574ea 100644
--- a/tests/signature/api-check/system-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/system-current-api/AndroidTest.xml
@@ -24,6 +24,9 @@
<option name="push" value="system-current.api->/data/local/tmp/signature-test/system-current.api" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+ <option name="push" value="system-removed.api->/data/local/tmp/signature-test/system-removed.api" />
+ </target_preparer>
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="push" value="android-test-mock-current.api->/data/local/tmp/signature-test/android-test-mock-current.api" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
@@ -36,7 +39,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.signature.cts.api.system_current" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
- <option name="instrumentation-arg" key="expected-api-files" value="system-current.api" />
+ <option name="instrumentation-arg" key="expected-api-files" value="system-current.api,system-removed.api" />
<option name="instrumentation-arg" key="unexpected-api-files" value="android-test-mock-current.api,android-test-runner-current.api" />
<option name="runtime-hint" value="30s" />
</test>
diff --git a/tests/signature/src/android/signature/cts/ApiComplianceChecker.java b/tests/signature/src/android/signature/cts/ApiComplianceChecker.java
index 8dbf5e7..b27624b 100644
--- a/tests/signature/src/android/signature/cts/ApiComplianceChecker.java
+++ b/tests/signature/src/android/signature/cts/ApiComplianceChecker.java
@@ -71,9 +71,11 @@
private final ResultObserver resultObserver;
+ private final ClassProvider classProvider;
- public ApiComplianceChecker(ResultObserver resultObserver) {
+ public ApiComplianceChecker(ResultObserver resultObserver, ClassProvider classProvider) {
this.resultObserver = resultObserver;
+ this.classProvider = classProvider;
}
private static void loge(String message, Exception exception) {
@@ -188,7 +190,7 @@
private Class<?> findRequiredClass(JDiffClassDescription classDescription) {
try {
- return ReflectionHelper.findMatchingClass(classDescription);
+ return ReflectionHelper.findMatchingClass(classDescription, classProvider);
} catch (ClassNotFoundException e) {
loge("ClassNotFoundException for " + classDescription.getAbsoluteClassName(), e);
return null;
diff --git a/tests/signature/src/android/signature/cts/ClassProvider.java b/tests/signature/src/android/signature/cts/ClassProvider.java
new file mode 100644
index 0000000..2461f26
--- /dev/null
+++ b/tests/signature/src/android/signature/cts/ClassProvider.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.signature.cts;
+
+import java.util.stream.Stream;
+
+/**
+ * Generic class for getting runtime classes that will be matched against
+ * {@link JDiffClassDescription}. {@link ApiComplianceChecker} is using this
+ * when it needs runtime classes.
+ */
+public abstract class ClassProvider {
+ /**
+ * Get a specific class with the given name.
+ *
+ * @throws ClassNotFoundException
+ */
+ public Class<?> getClass(String name) throws ClassNotFoundException {
+ return Class.forName(name, false, this.getClass().getClassLoader());
+ }
+
+ /**
+ * Gets all classes available to this provider.
+ */
+ public abstract Stream<Class<?>> getAllClasses();
+}
diff --git a/tests/signature/src/android/signature/cts/ExcludingClassProvider.java b/tests/signature/src/android/signature/cts/ExcludingClassProvider.java
new file mode 100644
index 0000000..290cbf5
--- /dev/null
+++ b/tests/signature/src/android/signature/cts/ExcludingClassProvider.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.signature.cts;
+
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+/**
+ * A filtered class provider which excludes classes by their canonical names
+ */
+public class ExcludingClassProvider extends ClassProvider {
+ private final ClassProvider base;
+ private final Predicate<String> testForExclusion;
+
+ public ExcludingClassProvider(ClassProvider base,
+ Predicate<String> testForExclusion) {
+ this.base = base;
+ this.testForExclusion = testForExclusion;
+ }
+
+ @Override
+ public Class<?> getClass(String name) throws ClassNotFoundException {
+ if (!testForExclusion.test(name)) {
+ return base.getClass(name);
+ }
+ // a filtered-out class is the same as non-existing class
+ throw new ClassNotFoundException("Cannot find class " + name);
+ }
+
+ @Override
+ public Stream<Class<?>> getAllClasses() {
+ return base.getAllClasses()
+ .filter(clazz -> !testForExclusion.test(clazz.getCanonicalName()));
+ }
+}
diff --git a/tests/signature/src/android/signature/cts/ReflectionHelper.java b/tests/signature/src/android/signature/cts/ReflectionHelper.java
index 54640a3..d87037d 100644
--- a/tests/signature/src/android/signature/cts/ReflectionHelper.java
+++ b/tests/signature/src/android/signature/cts/ReflectionHelper.java
@@ -42,7 +42,7 @@
* @return the reflected class, or null if not found.
*/
@SuppressWarnings("unchecked")
- public static Class<?> findMatchingClass(JDiffClassDescription classDescription)
+ public static Class<?> findMatchingClass(JDiffClassDescription classDescription, ClassProvider classProvider)
throws ClassNotFoundException {
// even if there are no . in the string, split will return an
// array of length 1
@@ -51,8 +51,7 @@
String packageName = classDescription.getPackageName();
String currentName = packageName + "." + classNameParts[0];
- Class<?> clz = Class.forName(
- currentName, false, ReflectionHelper.class.getClassLoader());
+ Class<?> clz = classProvider.getClass(currentName);
String absoluteClassName = classDescription.getAbsoluteClassName();
if (clz.getCanonicalName().equals(absoluteClassName)) {
return clz;
diff --git a/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java b/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java
index 71d2e37..45e14a9 100644
--- a/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java
+++ b/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java
@@ -20,7 +20,6 @@
import android.signature.cts.FailureType;
import android.signature.cts.JDiffClassDescription;
import android.signature.cts.ResultObserver;
-
import junit.framework.Assert;
import junit.framework.TestCase;
@@ -74,7 +73,8 @@
private void checkSignatureCompliance(JDiffClassDescription classDescription,
ResultObserver resultObserver) {
- ApiComplianceChecker complianceChecker = new ApiComplianceChecker(resultObserver);
+ ApiComplianceChecker complianceChecker = new ApiComplianceChecker(resultObserver,
+ new TestClassesProvider());
complianceChecker.checkSignatureCompliance(classDescription);
}
diff --git a/tests/signature/tests/src/android/signature/cts/tests/TestClassesProvider.java b/tests/signature/tests/src/android/signature/cts/tests/TestClassesProvider.java
new file mode 100644
index 0000000..2cb614c
--- /dev/null
+++ b/tests/signature/tests/src/android/signature/cts/tests/TestClassesProvider.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.signature.cts.tests;
+
+import java.util.stream.Stream;
+
+import android.signature.cts.ClassProvider;
+import android.signature.cts.tests.data.AbstractClass;
+import android.signature.cts.tests.data.FinalClass;
+import android.signature.cts.tests.data.NormalClass;
+import android.signature.cts.tests.data.NormalException;
+import android.signature.cts.tests.data.NormalInterface;
+
+public class TestClassesProvider extends ClassProvider {
+ @Override
+ public Stream<Class<?>> getAllClasses() {
+ Stream.Builder<Class<?>> builder = Stream.builder();
+ builder.add(AbstractClass.class);
+ builder.add(FinalClass.class);
+ builder.add(NormalClass.class);
+ builder.add(NormalException.class);
+ builder.add(NormalInterface.class);
+ return builder.build();
+ }
+
+}
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_2_golden.png
index d7cf703..7ba7191 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_1_golden.png
index fc39cf4..37a0d21 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_1_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_2_golden.png
index d1b1f86..b011284 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_a_2_golden.png
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java b/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
index 2b7dccb..5afb71d 100644
--- a/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
+++ b/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
@@ -642,14 +642,6 @@
setStringProperty(drm, LISTENER_TEST_SUPPORT_PROPERTY_KEY, listenerTestSupport);
- // Test setting new string property
- setStringProperty(drm, "NewStringPropertyKeyTest", "test value");
-
- value = getStringProperty(drm, "NewStringPropertyKeyTest");
- if (!value.equals("test value")) {
- throw new Error("Failed to set property: NewStringPropertyKeyTest");
- }
-
// Test setting immutable properties
HashMap<String, String> defaultImmutableProperties = new HashMap<String, String>();
defaultImmutableProperties.put(ALGORITHMS_PROPERTY_KEY,
@@ -679,19 +671,11 @@
}
}
- // Test setPropertyByteArray
+ // Test setPropertyByteArray for immutable property
final byte[] bytes = new byte[] {
0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8,
0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0};
- setByteArrayProperty(drm, "someBytes", bytes);
-
- // Verify new property value
- if (!Arrays.equals(bytes, getByteArrayProperty(drm, "someBytes"))) {
- throw new Error("Failed to set byte array for key=" + "someBytes");
- }
-
- // Test setPropertyByteArray for immutable property
final byte[] deviceId = getByteArrayProperty(drm, DEVICEID_PROPERTY_KEY);
setByteArrayProperty(drm, DEVICEID_PROPERTY_KEY, bytes);
diff --git a/tests/tests/permission/src/android/permission/cts/AppOpsTest.java b/tests/tests/permission/src/android/permission/cts/AppOpsTest.java
index 8b1b9c9..7a97434 100644
--- a/tests/tests/permission/src/android/permission/cts/AppOpsTest.java
+++ b/tests/tests/permission/src/android/permission/cts/AppOpsTest.java
@@ -22,6 +22,7 @@
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.app.AppOpsManager.OPSTR_READ_SMS;
+import android.Manifest.permission;
import android.app.AppOpsManager;
import android.content.Context;
import android.os.Process;
@@ -33,16 +34,59 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
public class AppOpsTest extends InstrumentationTestCase {
- static final Class<?>[] sSetModeSignature = new Class[] {
- Context.class, AttributeSet.class};
-
private AppOpsManager mAppOps;
private Context mContext;
private String mOpPackageName;
private int mMyUid;
+ // These permissions and opStrs must map to the same op codes.
+ private static Map<String, String> permissionToOpStr = new HashMap<>();
+
+ static {
+ permissionToOpStr.put(permission.ACCESS_COARSE_LOCATION,
+ AppOpsManager.OPSTR_COARSE_LOCATION);
+ permissionToOpStr.put(permission.ACCESS_FINE_LOCATION, AppOpsManager.OPSTR_FINE_LOCATION);
+ permissionToOpStr.put(permission.READ_CONTACTS, AppOpsManager.OPSTR_READ_CONTACTS);
+ permissionToOpStr.put(permission.WRITE_CONTACTS, AppOpsManager.OPSTR_WRITE_CONTACTS);
+ permissionToOpStr.put(permission.READ_CALL_LOG, AppOpsManager.OPSTR_READ_CALL_LOG);
+ permissionToOpStr.put(permission.WRITE_CALL_LOG, AppOpsManager.OPSTR_WRITE_CALL_LOG);
+ permissionToOpStr.put(permission.READ_CALENDAR, AppOpsManager.OPSTR_READ_CALENDAR);
+ permissionToOpStr.put(permission.WRITE_CALENDAR, AppOpsManager.OPSTR_WRITE_CALENDAR);
+ permissionToOpStr.put(permission.CALL_PHONE, AppOpsManager.OPSTR_CALL_PHONE);
+ permissionToOpStr.put(permission.READ_SMS, AppOpsManager.OPSTR_READ_SMS);
+ permissionToOpStr.put(permission.RECEIVE_SMS, AppOpsManager.OPSTR_RECEIVE_SMS);
+ permissionToOpStr.put(permission.RECEIVE_MMS, AppOpsManager.OPSTR_RECEIVE_MMS);
+ permissionToOpStr.put(permission.RECEIVE_WAP_PUSH, AppOpsManager.OPSTR_RECEIVE_WAP_PUSH);
+ permissionToOpStr.put(permission.SEND_SMS, AppOpsManager.OPSTR_SEND_SMS);
+ permissionToOpStr.put(permission.READ_SMS, AppOpsManager.OPSTR_READ_SMS);
+ permissionToOpStr.put(permission.WRITE_SETTINGS, AppOpsManager.OPSTR_WRITE_SETTINGS);
+ permissionToOpStr.put(permission.SYSTEM_ALERT_WINDOW,
+ AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW);
+ permissionToOpStr.put(permission.ACCESS_NOTIFICATIONS,
+ AppOpsManager.OPSTR_ACCESS_NOTIFICATIONS);
+ permissionToOpStr.put(permission.CAMERA, AppOpsManager.OPSTR_CAMERA);
+ permissionToOpStr.put(permission.RECORD_AUDIO, AppOpsManager.OPSTR_RECORD_AUDIO);
+ permissionToOpStr.put(permission.READ_PHONE_STATE, AppOpsManager.OPSTR_READ_PHONE_STATE);
+ permissionToOpStr.put(permission.ADD_VOICEMAIL, AppOpsManager.OPSTR_ADD_VOICEMAIL);
+ permissionToOpStr.put(permission.USE_SIP, AppOpsManager.OPSTR_USE_SIP);
+ permissionToOpStr.put(permission.PROCESS_OUTGOING_CALLS,
+ AppOpsManager.OPSTR_PROCESS_OUTGOING_CALLS);
+ permissionToOpStr.put(permission.BODY_SENSORS, AppOpsManager.OPSTR_BODY_SENSORS);
+ permissionToOpStr.put(permission.READ_CELL_BROADCASTS,
+ AppOpsManager.OPSTR_READ_CELL_BROADCASTS);
+ permissionToOpStr.put(permission.READ_EXTERNAL_STORAGE,
+ AppOpsManager.OPSTR_READ_EXTERNAL_STORAGE);
+ permissionToOpStr.put(permission.WRITE_EXTERNAL_STORAGE,
+ AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE);
+ }
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -115,6 +159,46 @@
}
}
+ @SmallTest
+ public void testAllOpsHaveOpString() {
+ Set<String> opStrs = new HashSet<>();
+ for (String opStr : AppOpsManager.getOpStrs()) {
+ assertNotNull("Each app op must have an operation string defined", opStr);
+ opStrs.add(opStr);
+ }
+ assertEquals("Not all op strings are unique", AppOpsManager._NUM_OP, opStrs.size());
+ }
+
+ @SmallTest
+ public void testOpCodesUnique() {
+ String[] opStrs = AppOpsManager.getOpStrs();
+ Set<Integer> opCodes = new HashSet<>();
+ for (String opStr : opStrs) {
+ opCodes.add(AppOpsManager.strOpToOp(opStr));
+ }
+ assertEquals("Not all app op codes are unique", opStrs.length, opCodes.size());
+ }
+
+ @SmallTest
+ public void testPermissionMapping() {
+ for (String permission : permissionToOpStr.keySet()) {
+ testPermissionMapping(permission, permissionToOpStr.get(permission));
+ }
+ }
+
+ private void testPermissionMapping(String permission, String opStr) {
+ // Do the public value => internal op code lookups.
+ String mappedOpStr = AppOpsManager.permissionToOp(permission);
+ assertEquals(mappedOpStr, opStr);
+ int mappedOpCode = AppOpsManager.permissionToOpCode(permission);
+ int mappedOpCode2 = AppOpsManager.strOpToOp(opStr);
+ assertEquals(mappedOpCode, mappedOpCode2);
+
+ // Do the internal op code => public value lookup (reverse lookup).
+ String permissionMappedBack = AppOpsManager.opToPermission(mappedOpCode);
+ assertEquals(permission, permissionMappedBack);
+ }
+
/**
* Test that the app can not change the app op mode for itself.
*/
diff --git a/tests/tests/security/jni/Android.mk b/tests/tests/security/jni/Android.mk
index fe4f779..4fefdab 100644
--- a/tests/tests/security/jni/Android.mk
+++ b/tests/tests/security/jni/Android.mk
@@ -28,7 +28,6 @@
android_security_cts_LinuxRngTest.cpp \
android_security_cts_NativeCodeTest.cpp \
android_security_cts_SELinuxTest.cpp \
- android_security_cts_SeccompTest.cpp \
android_security_cts_MMapExecutableTest.cpp \
android_security_cts_EncryptionTest.cpp \
diff --git a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
index 835d1a6..2014591 100644
--- a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
+++ b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
@@ -49,11 +49,7 @@
return JNI_ERR;
}
- if (register_android_security_cts_SeccompTest(env)) {
- return JNI_ERR;
- }
-
- if (register_android_security_cts_KernelSettingsTest(env)) {
+ if (register_android_security_cts_KernelSettingsTest(env)) {
return JNI_ERR;
}
diff --git a/tests/tests/widget/res/layout/textview_fallbacklinespacing_layout.xml b/tests/tests/widget/res/layout/textview_fallbacklinespacing_layout.xml
new file mode 100644
index 0000000..684d821
--- /dev/null
+++ b/tests/tests/widget/res/layout/textview_fallbacklinespacing_layout.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/layout_textviewtest"
+ android:orientation="vertical">
+
+ <TextView android:id="@+id/textview_true"
+ android:fallbackLineSpacing="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ <TextView android:id="@+id/textview_false"
+ android:fallbackLineSpacing="false"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ <TextView android:id="@+id/textview_default"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ <TextView android:id="@+id/textview_style_true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@style/TextAppearance.FallbackLineSpacingTrue"/>
+
+ <TextView android:id="@+id/textview_style_false"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@style/TextAppearance.FallbackLineSpacingFalse"/>
+
+ <TextView android:id="@+id/textview_style_default"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@style/TextAppearance"/>
+
+</LinearLayout>
diff --git a/tests/tests/widget/res/values/styles.xml b/tests/tests/widget/res/values/styles.xml
index 8d44c7a..abb85ad 100644
--- a/tests/tests/widget/res/values/styles.xml
+++ b/tests/tests/widget/res/values/styles.xml
@@ -141,6 +141,15 @@
<item name="android:elegantTextHeight">false</item>
</style>
+
+ <style name="TextAppearance.FallbackLineSpacingFalse">
+ <item name="android:fallbackLineSpacing">false</item>
+ </style>
+
+ <style name="TextAppearance.FallbackLineSpacingTrue">
+ <item name="android:fallbackLineSpacing">true</item>
+ </style>
+
<style name="AllCapsPassword">
<item name="android:textAllCaps">true</item>
<item name="android:password">true</item>
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index ca1c9a1..cc4d023 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -7817,6 +7817,70 @@
assertEquals(Typeface.DEFAULT, mTextView.getTypeface());
}
+ @UiThreadTest
+ @Test
+ public void testFallbackLineSpacing_readsFromLayoutXml() {
+ mActivity.setContentView(R.layout.textview_fallbacklinespacing_layout);
+ mTextView = findTextView(R.id.textview_true);
+ assertTrue(mTextView.isFallbackLineSpacing());
+
+ mTextView = findTextView(R.id.textview_default);
+ assertTrue(mTextView.isFallbackLineSpacing());
+
+ mTextView = findTextView(R.id.textview_false);
+ assertFalse(mTextView.isFallbackLineSpacing());
+ }
+
+ @UiThreadTest
+ @Test
+ public void testFallbackLineSpacing_set_get() {
+ mActivity.setContentView(R.layout.textview_fallbacklinespacing_layout);
+ mTextView = findTextView(R.id.textview_true);
+ assertTrue(mTextView.isFallbackLineSpacing());
+
+ mTextView.setFallbackLineSpacing(false);
+ assertFalse(mTextView.isFallbackLineSpacing());
+
+ mTextView.setFallbackLineSpacing(true);
+ assertTrue(mTextView.isFallbackLineSpacing());
+ }
+
+ @UiThreadTest
+ @Test
+ public void testFallbackLineSpacing_readsFromStyleXml() {
+ mActivity.setContentView(R.layout.textview_fallbacklinespacing_layout);
+ mTextView = findTextView(R.id.textview_style_true);
+ assertTrue(mTextView.isFallbackLineSpacing());
+
+ mTextView = findTextView(R.id.textview_style_default);
+ assertTrue(mTextView.isFallbackLineSpacing());
+
+ mTextView = findTextView(R.id.textview_style_false);
+ assertFalse(mTextView.isFallbackLineSpacing());
+ }
+
+ @UiThreadTest
+ @Test
+ public void testFallbackLineSpacing_textAppearance_set_get() {
+ mActivity.setContentView(R.layout.textview_fallbacklinespacing_layout);
+ mTextView = findTextView(R.id.textview_default);
+ assertTrue(mTextView.isFallbackLineSpacing());
+
+ mTextView.setTextAppearance(R.style.TextAppearance_FallbackLineSpacingFalse);
+ assertFalse(mTextView.isFallbackLineSpacing());
+
+ mTextView.setTextAppearance(R.style.TextAppearance_FallbackLineSpacingTrue);
+ assertTrue(mTextView.isFallbackLineSpacing());
+
+ mTextView.setFallbackLineSpacing(false);
+ mTextView.setTextAppearance(R.style.TextAppearance);
+ assertFalse(mTextView.isFallbackLineSpacing());
+
+ mTextView.setFallbackLineSpacing(true);
+ mTextView.setTextAppearance(R.style.TextAppearance);
+ assertTrue(mTextView.isFallbackLineSpacing());
+ }
+
private void initializeTextForSmartSelection(CharSequence text) throws Throwable {
assertTrue(text.length() >= SMARTSELECT_END);
mActivityRule.runOnUiThread(() -> {