Merge "Remove volume change test for default route" into oreo-cts-dev
diff --git a/apps/CameraITS/tests/scene1/scene1_0.67_scaled.pdf b/apps/CameraITS/tests/scene1/scene1_0.67_scaled.pdf
new file mode 100644
index 0000000..3103cd8
--- /dev/null
+++ b/apps/CameraITS/tests/scene1/scene1_0.67_scaled.pdf
Binary files differ
diff --git a/apps/CameraITS/tests/scene2/scene2_0.67_scaled.pdf b/apps/CameraITS/tests/scene2/scene2_0.67_scaled.pdf
new file mode 100644
index 0000000..7b64817
--- /dev/null
+++ b/apps/CameraITS/tests/scene2/scene2_0.67_scaled.pdf
Binary files differ
diff --git a/apps/CameraITS/tests/scene3/scene3_0.67_scaled.pdf b/apps/CameraITS/tests/scene3/scene3_0.67_scaled.pdf
new file mode 100644
index 0000000..a3e18e2
--- /dev/null
+++ b/apps/CameraITS/tests/scene3/scene3_0.67_scaled.pdf
Binary files differ
diff --git a/apps/CameraITS/tests/scene4/scene4_0.67_scaled.pdf b/apps/CameraITS/tests/scene4/scene4_0.67_scaled.pdf
new file mode 100644
index 0000000..7fb1e42
--- /dev/null
+++ b/apps/CameraITS/tests/scene4/scene4_0.67_scaled.pdf
Binary files differ
diff --git a/apps/CameraITS/tools/load_scene.py b/apps/CameraITS/tools/load_scene.py
index 4e245f4..6255137 100644
--- a/apps/CameraITS/tools/load_scene.py
+++ b/apps/CameraITS/tools/load_scene.py
@@ -17,17 +17,20 @@
import subprocess
import sys
import time
-
+import numpy as np
def main():
"""Load charts on device and display."""
- camera_id = -1
scene = None
for s in sys.argv[1:]:
if s[:6] == 'scene=' and len(s) > 6:
scene = s[6:]
elif s[:7] == 'screen=' and len(s) > 7:
screen_id = s[7:]
+ elif s[:5] == 'dist=' and len(s) > 5:
+ chart_distance = float(re.sub('cm', '', s[5:]))
+ elif s[:4] == 'fov=' and len(s) > 4:
+ camera_fov = float(s[4:])
cmd = ('adb -s %s shell am force-stop com.google.android.apps.docs' %
screen_id)
@@ -43,8 +46,13 @@
remote_scene_file = '/sdcard/Download/%s.pdf' % scene
local_scene_file = os.path.join(os.environ['CAMERA_ITS_TOP'], 'tests',
- scene, scene+'.pdf')
- print 'Loading %s on %s' % (remote_scene_file, screen_id)
+ scene)
+ if np.isclose(chart_distance, 22, rtol=0.1) and camera_fov < 90:
+ local_scene_file = os.path.join(local_scene_file,
+ scene+'_0.67_scaled.pdf')
+ else:
+ local_scene_file = os.path.join(local_scene_file, scene+'.pdf')
+ print 'Loading %s on %s' % (local_scene_file, screen_id)
cmd = 'adb -s %s push %s /mnt%s' % (screen_id, local_scene_file,
remote_scene_file)
subprocess.Popen(cmd.split())
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index de269b7..dedc969 100644
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -13,8 +13,10 @@
# limitations under the License.
import copy
+import math
import os
import os.path
+import re
import tempfile
import subprocess
import time
@@ -25,9 +27,25 @@
from its.device import ItsSession
CHART_DELAY = 1 # seconds
+CHART_DISTANCE = 30.0 # cm
FACING_EXTERNAL = 2
SKIP_RET_CODE = 101 # note this must be same as tests/scene*/test_*
+def calc_camera_fov():
+ """Determine the camera field of view from internal params."""
+ with ItsSession() as cam:
+ props = cam.get_camera_properties()
+ try:
+ focal_l = props['android.lens.info.availableFocalLengths'][0]
+ sensor_size = props['android.sensor.info.physicalSize']
+ diag = math.sqrt(sensor_size['height'] ** 2 +
+ sensor_size['width'] ** 2)
+ fov = str(round(2 * math.degrees(math.atan(diag / (2 * focal_l))), 2))
+ except ValueError:
+ fov = str(0)
+ print 'Calculated FoV: %s' % fov
+ return fov
+
def skip_sensor_fusion():
"""Determine if sensor fusion test is skipped for this camera."""
@@ -60,6 +78,7 @@
all android devices.
skip_scene_validation: force skip scene validation. Used when test scene
is setup up front and don't require tester validation.
+ dist: [Experimental] chart distance in cm.
"""
# Not yet mandated tests
@@ -120,6 +139,7 @@
rot_rig_id = None
skip_scene_validation = False
+ chart_distance = CHART_DISTANCE
for s in sys.argv[1:]:
if s[:7] == "camera=" and len(s) > 7:
@@ -135,6 +155,8 @@
# The default '$VID:$PID:$CH' is '04d8:fc73:1'
elif s == 'skip_scene_validation':
skip_scene_validation = True
+ elif s[:5] == 'dist=' and len(s) > 5:
+ chart_distance = float(re.sub('cm', '', s[5:]))
auto_scene_switch = chart_host_id is not None
merge_result_switch = result_device_id is not None
@@ -163,7 +185,7 @@
break
if not valid_scenes:
- print "Unknown scene specifiied:", s
+ print 'Unknown scene specified:', s
assert False
scenes = temp_scenes
@@ -225,6 +247,7 @@
assert wake_code == 0
for camera_id in camera_ids:
+ camera_fov = calc_camera_fov()
# Loop capturing images until user confirm test scene is correct
camera_id_arg = "camera=" + camera_id
print "Preparing to run ITS on camera", camera_id
@@ -260,9 +283,11 @@
if (not merge_result_switch or
(merge_result_switch and camera_ids[0] == '0')):
scene_arg = 'scene=' + scene
+ chart_dist_arg = 'dist= ' + str(chart_distance)
+ fov_arg = 'fov=' + camera_fov
cmd = ['python',
os.path.join(os.getcwd(), 'tools/load_scene.py'),
- scene_arg, screen_id_arg]
+ scene_arg, chart_dist_arg, fov_arg, screen_id_arg]
else:
time.sleep(CHART_DELAY)
else:
diff --git a/apps/CtsVerifier/res/values-vrheadset/strings.xml b/apps/CtsVerifier/res/values-vrheadset/strings.xml
index 3132dfd..750ef34 100644
--- a/apps/CtsVerifier/res/values-vrheadset/strings.xml
+++ b/apps/CtsVerifier/res/values-vrheadset/strings.xml
@@ -24,4 +24,151 @@
<item>com.android.cts.verifier.notifications.ShortcutThrottlingResetActivity</item>
<item>com.android.cts.verifier.vr.VrListenerVerifierActivity</item>
</string-array>
+
+ <!-- Override default strings for features that non-handheld devices may not support. -->
+
+ <!-- This specific test is disabling tethering, non-handheld devices may not support tethering and this may effectively be a no-op. -->
+ <string name="disallow_config_tethering_action">
+ Configuring tethering and portable hotspots.\n
+ NOTE: If the device does not support tethering please pass the test using the green check mark.\n
+ </string>
+
+ <!-- This specific test is disallowing usb file transfers. non-handheld devices may not support usb file transfer features and this may effectively be a no-op. -->
+ <string name="device_owner_disallow_usb_file_transfer_test_info">
+ Please press below button to set the \"disallow USB file transfer\" restriction.\n
+ If a USB notification appears, open the notification and check that the
+ \"Transfer files (MTP)\" and \"Transfer photos (PTP)\" cannot be selected and trigger a
+ support message when trying to select them.\n
+ NOTE: If the device does not support MTP or PTP please pass the test using the green check mark.\n
+ Check if you can mount the device as a USB drive on your desktop computer. The test is
+ successful if you cannot mount the device, and files from your phone cannot be
+ downloaded through USB.\n
+ Please mark the test accordingly.
+ </string>
+
+ <!-- This specific test is disabling the keyguard, non-handheld devices may not support keyguard and this may effectively be a no-op. -->
+ <string name="device_owner_disable_keyguard_test_info">
+ NOTE: If the device does not support keyguard please pass the test using the green check mark.\n
+ Before running this test, please make sure you have not set any device lockscreen password.\n
+ Please press the below button to disable the keyguard. Press the power button on your device to
+ switch off the screen. Then press the power button to switch the screen back on and verify that
+ no keyguard was shown.\n
+ Next, press the button to reenable the keyguard and repeat the above steps, this time verifying that
+ a keyguard was shown.\n
+ Please mark the test accordingly.
+ </string>
+
+ <!-- This specific test is disabling the status bar, non-handheld devices may not support a status bar and this may effectively be a no-op. -->
+ <string name="device_owner_disable_statusbar_test_info">
+ NOTE: If the device does not support a status bar, please pass the test using the green check mark. \n
+ Please press the below button to disable the status bar and verify that quick settings, notifications
+ and the assist gesture are no longer available.\n
+ Next, press the button to reenable the status bar and verify that quick settings, notification
+ and the assist gesture are available again.\n
+ Please mark the test accordingly.
+ </string>
+
+ <!-- This specific test is disabling keyguard/lock screen notifications, non-handheld devices may not support
+ keyguard/lock screen notifciations and this may effectively be a no-op. -->
+ <string name="disallow_keyguard_unredacted_notifications_set_step">
+ NOTE: If the device does not support a keyguard or lock screen notifications, please pass the test
+ using the green checkmark.\n
+ Disallow unredacted notifications when device is locked by turning on the switch below
+ </string>
+
+ <!-- This specific test is disabling trust agents, non-handheld devices may not support trust agents and this may effectively be a no-op. -->
+ <string name="provisioning_byod_disable_trust_agents_instruction">
+ NOTE: If the device does not support trust agents, please mark the test as \"Pass\".\n
+ Please press the Go button to go to Settings > Security. Then go to Trusted agents and\n
+ check if the agents are shown as disabled by the administrator.
+ Then please press Back and mark the test as \"Pass\" or \"Fail\".
+ </string>
+
+ <!-- This specific test is disabling keyguard notifications, non-handheld devices may not support keyguard and this may effectively be a no-op. -->
+ <string name="device_admin_disable_notifications_instruction">
+ NOTE: If the device does not support a keyguard, please mark the test as \"Pass\".\n
+ Please press the Go button to lock the screen. Wait a few seconds to see
+ if a notification appears. Expected result is no notifications appear.
+ You should be able to see one after unlocking.
+ </string>
+
+ <!-- This specific test is disabling keyguard notifications, non-handheld devices may not support keyguard and this may effectively be a no-op. -->
+ <string name="device_admin_disable_unredacted_notifications_instruction">
+ Note: If the device does not support a keyguard, please mark the test as \"Pass"\.\n
+ Please press the Go button to lock the screen. Wait a few seconds to see
+ if a notification appears. Expected result is a notification appear with
+ its content hidden. You should be able to see the content after unlocking.
+ </string>
+
+ <!-- This specific test is setting a lock screen message, non-handheld devices may not support lock scren messages
+ and this may effectively be a no-op. -->
+ <string name="lock_screen_info_set_step">
+ NOTE: If the device does not support lock screen messages, pass the test using the green checkmark. \n
+ Select a lock screen info by setting a non-empty message in the edittext below.
+ </string>
+
+ <!-- This specific test is setting permitted accessibilty features, non-handheld devices may not support accessibility features and this may effectively be a no-op. -->
+ <string name="permitted_accessibility_services_set_step">
+ NOTE: If the device does not support accessibility features, please pass the test using the green check mark.\n
+ Check that \'Dummy Accessibility service\' is not enabled in Settings and disallow \'Dummy Accessibility service\' from permitted accessibility services by turning on
+ the switch below.
+ </string>
+
+ <!-- This specific test is disabling volume changes via audio settings.
+ Non-handheld devices may not support an audio settings page and this may effectively be a no-op. -->
+ <string name="disallow_adjust_volume_action">
+ NOTE: If the device does not support an audio settings page, please pass the test using the green checkmark.\n
+ Adjusting the volume
+ </string>
+
+ <!-- Non-handheld devices may not support a keyguard and this test may effectively be a no-op. -->
+ <string name="enterprise_privacy_keyguard_info">
+ NOTE: If the device does not support a keyguard, please pass the test using the green checkmark.\n
+ Please do the following:\n
+ 1) Press the Go button to open Settings.\n
+ 2) Navigate to \"Security\" > \"Screen lock\" and select the first screen lock type that is not \"None\".\n
+ 3) Use the Back button to return to this page.\n
+ 4) Lock the device.\n
+ 5) Verify that on the lock screen, you are not told the device is managed.\n
+ 6) Unlock the device.\n
+ 7) Repeat steps (1) through (6) for each screen lock type other than \"None\".
+ </string>
+
+ <!-- Non-handheld devices may not support quicksettings and this test may effectively be a no-op. -->
+ <string name="enterprise_privacy_quick_settings_info">
+ NOTE: If the device does not support quick settings, please pass the test using the green check mark. \n
+ Please do the following:\n
+ 1) Press the Clear Org button.\n
+ 2) Open and fully expand Quick Settings.\n
+ 3) Verify that at the bottom of Quick Settings, you are told the device is managed.\n
+ 4) Close Quick Settings.\n
+ 5) Press the Set Org button.\n
+ 6) Open and fully expand Quick Settings.\n
+ 7) Verify that at the bottom of Quick Settings, you are told the device is managed by \"Foo, Inc.\".\n
+ 8) Tap on the information.\n
+ 9) Verify that a dialog informing you about device monitoring opens.\n
+ 10) Tap the \"Learn more\" link.\n
+ 11) Verify that a screen informing you what your managing organization can do is shown.\n
+ \n
+ Use the Back button to return to this page.
+ </string>
+
+ <!-- Non-handheld devices may not support quicksettings but still should be able to validate the API via
+ the notification section. -->
+ <string name="device_owner_network_logging_ui_info">
+ Please do the following:\n
+ NOTE: If the device does not support quick settings, please only check the notifications section.\n
+ 1) Open and fully expand Quick Settings.\n
+ 2) Check that you are told that your device is managed.\n
+ 3) Close Quick Settings.\n
+ 4) Enable network logging by tapping on the left button below.\n
+ 5) Open Quick Settings again. Check that an icon appeared next to the text about device management.\n
+ 6) Verify that a notification including the same icon popped up, informing you that network logging has been enabled.\n
+ 7) Tap the notification.\n
+ 8) Verify that a dialog about device monitoring opens, and informs you about: the name of the app that manages this device, details about the device owner\'s capabilities, and information that the admin has activated network logging and can see all network traffic.\n
+ 9) Close the dialog.\n
+ 10) Tap the right button below to disable network logging.\n
+ 11) Verify that the notification disappeared.\n
+ </string>
+
</resources>
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java
index 5ef3a93..5b3339b 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java
@@ -139,8 +139,11 @@
int numTests = countTestCases();
long startTime = System.currentTimeMillis();
listener.testRunStarted(getClass().getName(), numTests);
- super.run(new HostTestListener(listener));
- listener.testRunEnded(System.currentTimeMillis() - startTime, Collections.emptyMap());
+ try {
+ super.run(new HostTestListener(listener));
+ } finally {
+ listener.testRunEnded(System.currentTimeMillis() - startTime, Collections.emptyMap());
+ }
}
/**
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserAdminHelper.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserAdminHelper.java
index e092888..12e9698 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserAdminHelper.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserAdminHelper.java
@@ -42,7 +42,7 @@
if (mDpm.isAdminActive(cn)) {
mDpm.removeActiveAdmin(cn);
// Wait until device admin is not active (with 2 minutes timeout).
- for (int i = 0; i < 2 * 60 && mDpm.isAdminActive(cn); i++) {
+ for (int i = 0; i < 5 * 60 && mDpm.isAdminActive(cn); i++) {
Thread.sleep(1000); // 1 second.
}
}
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTests.java
index 9cbf328..c8e327e 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTests.java
@@ -1285,7 +1285,6 @@
executeShellCommand("am start -n " + getActivityComponentName(LAUNCHING_ACTIVITY));
final int stackId = mVrHeadset ? defaultDisplayFrontStackId : frontStackId;
- final int focusedStackTaskCount = mVrHeadset ? 3 : 1;
mAmWmState.waitForFocusedStack(mDevice, stackId);
// Check that the third intent is redirected to the first task
@@ -1294,8 +1293,10 @@
assertEquals("Activity launched on default display must be resumed",
getActivityComponentName(LAUNCHING_ACTIVITY), secondFrontStack.mResumedActivity);
mAmWmState.assertFocusedStack("Focus must be on primary display", stackId);
- assertEquals("Focused stack must contain correct tasks",
- focusedStackTaskCount, secondFrontStack.getTasks().size());
+ if (!mVrHeadset) {
+ assertEquals("Focused stack must contain correct tasks",
+ 1, secondFrontStack.getTasks().size());
+ }
assertEquals("Focused task must only contain 1 activity",
1, secondFrontStack.getTasks().get(0).mActivities.size());
}
@@ -1357,9 +1358,10 @@
assertEquals("Activity must be launched on secondary display",
getActivityComponentName(LAUNCHING_ACTIVITY),
secondFrontStack.mResumedActivity);
- final int taskCount = mVrHeadset ? 3 : 2;
- assertEquals("Secondary display must contain correct tasks",
- taskCount, secondFrontStack.getTasks().size());
+ if (!mVrHeadset) {
+ assertEquals("Secondary display must contain correct tasks",
+ 2, secondFrontStack.getTasks().size());
+ }
}
/**
diff --git a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
index 74ead54..945bebd 100755
--- a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
+++ b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
@@ -41,7 +41,7 @@
private static final int GRAY = 0xFF808080;
/** Maximum allowable number of consecutive failed pixels. */
- private static final int MAX_CONSECUTIVE_FAILURES = 1;
+ private static final int MAX_CONSECUTIVE_FAILURES = 2;
private final String mName;
private final File mExpected;
@@ -87,6 +87,43 @@
return (color & 0xFF000000) >>> 24;
}
+ /**
+ * Verifies that the pixels of reference and generated images are similar
+ * within a specified threshold.
+ *
+ * @param expected expected image
+ * @param actual actual image
+ * @param threshold maximum difference per channel
+ * @return {@code true} if the images are similar, false otherwise
+ */
+ private static boolean checkNeighbors(int x, int y, BufferedImage reference,
+ BufferedImage generated, int threshold) {
+ final int w = generated.getWidth();
+ final int h = generated.getHeight();
+ for (int i = x - MAX_CONSECUTIVE_FAILURES; i <= x + MAX_CONSECUTIVE_FAILURES; i++) {
+ if (i >= 0 && i != x && i < w) {
+ for (int j = y - MAX_CONSECUTIVE_FAILURES; j <= y + MAX_CONSECUTIVE_FAILURES; j++) {
+ if (j >= 0 && j != y && j < h) {
+ final int p1 = reference.getRGB(i, j);
+ final int p2 = generated.getRGB(i, j);
+
+ final int dr = getAlphaScaledRed(p1) - getAlphaScaledRed(p2);
+ final int dg = getAlphaScaledGreen(p1) - getAlphaScaledGreen(p2);
+ final int db = getAlphaScaledBlue(p1) - getAlphaScaledBlue(p2);
+
+ if (Math.abs(db) <= threshold &&
+ Math.abs(dg) <= threshold &&
+ Math.abs(dr) <= threshold) {
+ // If we find at least one matching neighbor, we assume the difference
+ // is in antialiasing.
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
/**
* Verifies that the pixels of reference and generated images are similar
@@ -107,7 +144,6 @@
double maxDist = 0;
for (int i = 0; i < w; i++) {
- int consecutive = 0;
for (int j = 0; j < h; j++) {
final int p1 = reference.getRGB(i, j);
@@ -121,45 +157,16 @@
Math.abs(dg) > threshold ||
Math.abs(dr) > threshold) {
System.err.println("fail dr=" + dr+ " dg=" + dg+ " db=" + db);
-
- consecutive++;
-
- if (consecutive > MAX_CONSECUTIVE_FAILURES) {
+ if (!checkNeighbors(i, j, reference, generated, threshold)) {
System.err.println("consecutive fail");
return false;
}
- } else {
- consecutive = 0;
}
}
}
return true;
}
- /**
- * Returns the perceptual difference score (lower is better) for the
- * provided ARGB pixels.
- */
- private static double computeLabDistance(int p1, int p2) {
- // Blend with neutral gray to account for opacity.
- p1 = ColorUtils.blendSrcOver(p1, GRAY);
- p2 = ColorUtils.blendSrcOver(p2, GRAY);
-
- // Convert to LAB.
- double[] lab1 = new double[3];
- double[] lab2 = new double[3];
- ColorUtils.colorToLAB(p1, lab1);
- ColorUtils.colorToLAB(p2, lab2);
-
- // Compute the distance
- double dist = 0;
- for (int i = 0; i < 3; i++) {
- double delta = lab1[i] - lab2[i];
- dist += delta * delta;
- }
- return Math.sqrt(dist);
- }
-
private static void createDiff(BufferedImage expected, BufferedImage actual, File out)
throws IOException {
final int w1 = expected.getWidth();
diff --git a/tests/autofillservice/AndroidManifest.xml b/tests/autofillservice/AndroidManifest.xml
index 08f0754..9303955 100644
--- a/tests/autofillservice/AndroidManifest.xml
+++ b/tests/autofillservice/AndroidManifest.xml
@@ -66,6 +66,10 @@
<activity android:name=".OutOfProcessLoginActivity"
android:process="android.autofillservice.cts.outside"/>
<activity android:name=".FragmentContainerActivity" />
+ <activity android:name=".WebViewActivity"/>
+ <activity android:name=".TrampolineWelcomeActivity"/>
+ <activity android:name=".AttachedContextActivity"/>
+ <activity android:name=".TrampolineForResultActivity" />
<service
android:name=".InstrumentedAutoFillService"
@@ -75,6 +79,22 @@
<action android:name="android.service.autofill.AutofillService" />
</intent-filter>
</service>
+ <service
+ android:name=".NoOpAutofillService"
+ android:label="NoOpAutofillService"
+ android:permission="android.permission.BIND_AUTOFILL_SERVICE" >
+ <intent-filter>
+ <action android:name="android.service.autofill.AutofillService" />
+ </intent-filter>
+ </service>
+ <!-- BadAutofillService does not declare the proper permission -->
+ <service
+ android:name=".BadAutofillService"
+ android:label="BadAutofillService">
+ <intent-filter>
+ <action android:name="android.service.autofill.AutofillService" />
+ </intent-filter>
+ </service>
</application>
<instrumentation
diff --git a/tests/autofillservice/src/android/autofillservice/cts/BadAutofillService.java b/tests/autofillservice/src/android/autofillservice/cts/BadAutofillService.java
new file mode 100644
index 0000000..19a8ec1
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/BadAutofillService.java
@@ -0,0 +1,49 @@
+/*
+ * 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.autofillservice.cts;
+
+import android.os.CancellationSignal;
+import android.service.autofill.AutofillService;
+import android.service.autofill.FillCallback;
+import android.service.autofill.FillRequest;
+import android.service.autofill.SaveCallback;
+import android.service.autofill.SaveRequest;
+import android.util.Log;
+
+/**
+ * An {@link AutofillService} implementation that does fails if called upon.
+ */
+public class BadAutofillService extends AutofillService {
+
+ private static final String TAG = "BadAutofillService";
+
+ static final String SERVICE_NAME = BadAutofillService.class.getPackage().getName()
+ + "/." + BadAutofillService.class.getSimpleName();
+ static final String SERVICE_LABEL = "BadAutofillService";
+
+ @Override
+ public void onFillRequest(FillRequest request, CancellationSignal cancellationSignal,
+ FillCallback callback) {
+ Log.e(TAG, "onFillRequest() should never be called");
+ throw new UnsupportedOperationException("onFillRequest() should never be called");
+ }
+
+ @Override
+ public void onSaveRequest(SaveRequest request, SaveCallback callback) {
+ Log.e(TAG, "onSaveRequest() should never be called");
+ throw new UnsupportedOperationException("onSaveRequest() should never be called");
+ }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
index 0280b44..0c384ff 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
@@ -59,6 +59,8 @@
static final boolean VERBOSE = false;
+ static final String MY_PACKAGE = "android.autofillservice.cts";
+
static final String ID_USERNAME_LABEL = "username_label";
static final String ID_USERNAME = "username";
static final String ID_PASSWORD_LABEL = "password_label";
diff --git a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
index 9650fff..0840f28 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
@@ -53,8 +53,11 @@
*/
public class InstrumentedAutoFillService extends AutofillService {
- static final String SERVICE_NAME = InstrumentedAutoFillService.class.getPackage()
- .getName() + "/." + InstrumentedAutoFillService.class.getSimpleName();
+ static final String SERVICE_PACKAGE = Helper.MY_PACKAGE;
+ static final String SERVICE_CLASS = "InstrumentedAutoFillService";
+
+ static final String SERVICE_NAME = SERVICE_PACKAGE + "/." + SERVICE_CLASS;
+ protected static final String sServiceLabel = SERVICE_CLASS;
private static final String TAG = "InstrumentedAutoFillService";
diff --git a/tests/autofillservice/src/android/autofillservice/cts/NoOpAutofillService.java b/tests/autofillservice/src/android/autofillservice/cts/NoOpAutofillService.java
new file mode 100644
index 0000000..a4c2a10
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/NoOpAutofillService.java
@@ -0,0 +1,42 @@
+/*
+ * 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.autofillservice.cts;
+
+import android.os.CancellationSignal;
+import android.service.autofill.AutofillService;
+import android.service.autofill.FillCallback;
+import android.service.autofill.FillRequest;
+import android.service.autofill.SaveCallback;
+import android.service.autofill.SaveRequest;
+
+/**
+ * {@link AutofillService} implementation that does not do anything...
+ */
+public class NoOpAutofillService extends AutofillService {
+
+ static final String SERVICE_NAME = NoOpAutofillService.class.getPackage().getName()
+ + "/." + NoOpAutofillService.class.getSimpleName();
+ static final String SERVICE_LABEL = "NoOpAutofillService";
+
+ @Override
+ public void onFillRequest(FillRequest request, CancellationSignal cancellationSignal,
+ FillCallback callback) {
+ }
+
+ @Override
+ public void onSaveRequest(SaveRequest request, SaveCallback callback) {
+ }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java b/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java
new file mode 100644
index 0000000..c91fd13
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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.autofillservice.cts;
+
+import static android.autofillservice.cts.Helper.runShellCommand;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
+import android.provider.Settings;
+import android.support.test.uiautomator.UiObject2;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class SettingsIntentTest extends AutoFillServiceTestCase {
+
+ private static final int MY_REQUEST_CODE = 42;
+
+ @Rule
+ public final AutofillActivityTestRule<TrampolineForResultActivity> mActivityRule =
+ new AutofillActivityTestRule<TrampolineForResultActivity>(
+ TrampolineForResultActivity.class);
+
+ protected TrampolineForResultActivity mActivity;
+
+ @Before
+ public void setActivity() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @After
+ public void killSettings() {
+ // Make sure there's no Settings activity left , as it could fail future tests.
+ runShellCommand("am force-stop com.android.settings");
+ }
+
+ @Test
+ public void testMultipleServicesShown() throws Exception {
+ disableService();
+
+ // Launches Settings.
+ mActivity.startForResult(newSettingsIntent(), MY_REQUEST_CODE);
+
+ // Asserts services are shown.
+ sUiBot.assertShownByText(InstrumentedAutoFillService.sServiceLabel);
+ sUiBot.assertShownByText(NoOpAutofillService.SERVICE_LABEL);
+ sUiBot.assertNotShowingForSure(BadAutofillService.SERVICE_LABEL);
+
+ // Finishes and asserts result.
+ sUiBot.pressBack();
+ mActivity.assertResult(Activity.RESULT_CANCELED);
+ }
+
+ @Test
+ public void testWarningShown_userRejectsByTappingBack() throws Exception {
+ disableService();
+
+ // Launches Settings.
+ mActivity.startForResult(newSettingsIntent(), MY_REQUEST_CODE);
+
+ // Asserts services are shown.
+ final UiObject2 object = sUiBot
+ .assertShownByText(InstrumentedAutoFillService.sServiceLabel);
+ object.click();
+
+ // TODO(b/79615759): should assert that "autofill_confirmation_message" is shown, but that
+ // string belongs to Settings - we need to move it to frameworks/base first (and/or use
+ // a resource id, also on framework).
+ // So, for now, just asserts the service name is showing again (in the popup), and the other
+ // services are not showing (because the popup hides then).
+
+ final UiObject2 msgObj = sUiBot.assertShownById("android:id/message");
+ final String msg = msgObj.getText();
+ assertWithMessage("Wrong warning message").that(msg)
+ .contains(InstrumentedAutoFillService.sServiceLabel);
+
+ // NOTE: assertion below is fine because it looks for the full text, not a substring
+ sUiBot.assertNotShowingForSure(InstrumentedAutoFillService.sServiceLabel);
+ sUiBot.assertNotShowingForSure(NoOpAutofillService.SERVICE_LABEL);
+ sUiBot.assertNotShowingForSure(BadAutofillService.SERVICE_LABEL);
+
+ // Finishes and asserts result.
+ sUiBot.pressBack();
+ mActivity.assertResult(Activity.RESULT_CANCELED);
+ }
+
+ // TODO(b/79615759): add testWarningShown_userRejectsByTappingCancel() and
+ // testWarningShown_userAccepts() - these tests would require adding the strings and resource
+ // ids to frameworks/base
+
+ private Intent newSettingsIntent() {
+ return new Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .setData(Uri.parse("package:" + Helper.MY_PACKAGE));
+ }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/TrampolineForResultActivity.java b/tests/autofillservice/src/android/autofillservice/cts/TrampolineForResultActivity.java
new file mode 100644
index 0000000..6cdd33e
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/TrampolineForResultActivity.java
@@ -0,0 +1,67 @@
+/*
+ * 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.autofillservice.cts;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.content.Intent;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Activity used to launch another activity for result.
+ */
+// TODO: move to common code
+public class TrampolineForResultActivity extends AbstractAutoFillActivity {
+ private static final String TAG = "TrampolineForResultActivity";
+
+ private final CountDownLatch mLatch = new CountDownLatch(1);
+
+ private int mExpectedRequestCode;
+ private int mActualRequestCode;
+ private int mActualResultCode;
+
+ /**
+ * Starts an activity for result.
+ */
+ public void startForResult(Intent intent, int requestCode) {
+ mExpectedRequestCode = requestCode;
+ startActivityForResult(intent, requestCode);
+ }
+
+ /**
+ * Asserts the activity launched by {@link #startForResult(Intent, int)} was finished with the
+ * expected result code, or fails if it times out.
+ */
+ public void assertResult(int expectedResultCode) throws Exception {
+ final boolean called = mLatch.await(1000, TimeUnit.MILLISECONDS);
+ assertWithMessage("Result not received in 1s").that(called).isTrue();
+ assertWithMessage("Wrong actual code").that(mActualRequestCode)
+ .isEqualTo(mExpectedRequestCode);
+ assertWithMessage("Wrong result code").that(mActualResultCode)
+ .isEqualTo(expectedResultCode);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ Log.d(TAG, "onActivityResult(): req=" + requestCode + ", res=" + resultCode);
+ mActualRequestCode = requestCode;
+ mActualResultCode = resultCode;
+ mLatch.countDown();
+ }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 495b05c..774d7fe 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -177,8 +177,34 @@
* {@link #assertDatasets(String...)}.
*/
public UiObject2 assertShownByText(String text) {
- final UiObject2 object = waitForObject(By.text(text));
- assertWithMessage(text).that(object).isNotNull();
+ return assertShownByText(text, UI_TIMEOUT_MS);
+ }
+
+ public UiObject2 assertShownByText(String text, int timeoutMs) {
+ final UiObject2 object = waitForObject(By.text(text), timeoutMs);
+ assertWithMessage("No node with text '%s'", text).that(object).isNotNull();
+ return object;
+ }
+
+ /**
+ * Asserts that the text is not showing for sure in the screen "as is", i.e., without waiting
+ * for it.
+ *
+ * <p>Typically called after another assertion that waits for a condition to be shown.
+ */
+ public void assertNotShowingForSure(String text) throws Exception {
+ final UiObject2 object = mDevice.findObject(By.text(text));
+ assertWithMessage("Find node with text '%s'", text).that(object).isNull();
+ }
+
+ /**
+ * Asserts a node with the given content description is shown.
+ *
+ */
+ public UiObject2 assertShownByContentDescription(String contentDescription) {
+ final UiObject2 object = waitForObject(By.desc(contentDescription));
+ assertWithMessage("No node with content description '%s'", contentDescription).that(object)
+ .isNotNull();
return object;
}
@@ -204,8 +230,10 @@
/**
* Asserts the id is shown on the screen.
*/
- void assertShownById(String id) {
- assertThat(waitForObject(By.res(id))).isNotNull();
+ UiObject2 assertShownById(String id) throws Exception {
+ final UiObject2 object = waitForObject(By.res(id));
+ assertThat(object).isNotNull();
+ return object;
}
/**
diff --git a/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java b/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java
index d2da516..378e39c 100755
--- a/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java
@@ -89,8 +89,8 @@
}
public void testAssistStructure() throws Throwable {
- if (mActivityManager.isLowRamDevice()) {
- Log.d(TAG, "Not running assist tests on low-RAM device.");
+ if (!mContext.getPackageManager().hasSystemFeature(FEATURE_VOICE_RECOGNIZERS)) {
+ Log.d(TAG, "Not running assist tests - voice_recognizers feature is not supported");
return;
}
mTestActivity.start3pApp(TEST_CASE_TYPE);
diff --git a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
index 33a7758..461f5d0 100644
--- a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
+++ b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
@@ -48,6 +48,7 @@
public class AssistTestBase extends ActivityInstrumentationTestCase2<TestStartActivity> {
private static final String TAG = "AssistTestBase";
+ protected static final String FEATURE_VOICE_RECOGNIZERS = "android.software.voice_recognizers";
protected ActivityManager mActivityManager;
protected TestStartActivity mTestActivity;
protected AssistContent mAssistContent;
diff --git a/tests/tests/assist/src/android/assist/cts/DisableContextTest.java b/tests/tests/assist/src/android/assist/cts/DisableContextTest.java
index 3c5a0fb..20437eb 100644
--- a/tests/tests/assist/src/android/assist/cts/DisableContextTest.java
+++ b/tests/tests/assist/src/android/assist/cts/DisableContextTest.java
@@ -49,8 +49,8 @@
}
public void testContextAndScreenshotOff() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- Log.d(TAG, "Not running assist tests on low-RAM device.");
+ if (!mContext.getPackageManager().hasSystemFeature(FEATURE_VOICE_RECOGNIZERS)) {
+ Log.d(TAG, "Not running assist tests - voice_recognizers feature is not supported");
return;
}
// Both settings off
diff --git a/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java b/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java
index fc7c8fb3..43364f8 100644
--- a/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java
+++ b/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java
@@ -77,8 +77,8 @@
}
public void testSecureActivity() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- Log.d(TAG, "Not running assist tests on low-RAM device.");
+ if (!mContext.getPackageManager().hasSystemFeature(FEATURE_VOICE_RECOGNIZERS)) {
+ Log.d(TAG, "Not running assist tests - voice_recognizers feature is not supported");
return;
}
mTestActivity.startTest(TEST_CASE_TYPE);
diff --git a/tests/tests/assist/src/android/assist/cts/LifecycleTest.java b/tests/tests/assist/src/android/assist/cts/LifecycleTest.java
index 237fe6e..a4a1606 100644
--- a/tests/tests/assist/src/android/assist/cts/LifecycleTest.java
+++ b/tests/tests/assist/src/android/assist/cts/LifecycleTest.java
@@ -121,8 +121,8 @@
}
public void testLayerDoesNotTriggerLifecycleMethods() throws Exception {
- if (mActivityManager.isLowRamDevice()) {
- Log.d(TAG, "Not running assist tests on low-RAM device.");
+ if (!mContext.getPackageManager().hasSystemFeature(FEATURE_VOICE_RECOGNIZERS)) {
+ Log.d(TAG, "Not running assist tests - voice_recognizers feature is not supported");
return;
}
mTestActivity.startTest(Utils.LIFECYCLE);
diff --git a/tests/tests/content/src/android/content/cts/ContentProviderCursorWindowTest.java b/tests/tests/content/src/android/content/cts/ContentProviderCursorWindowTest.java
index e771461..5cfd532 100644
--- a/tests/tests/content/src/android/content/cts/ContentProviderCursorWindowTest.java
+++ b/tests/tests/content/src/android/content/cts/ContentProviderCursorWindowTest.java
@@ -17,14 +17,13 @@
package android.content.cts;
import android.database.Cursor;
+import android.database.CursorWindowAllocationException;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.platform.test.annotations.SecurityTest;
import android.test.AndroidTestCase;
import android.util.Log;
-import java.io.IOException;
-
/**
* Test {@link CursorWindowContentProvider} .
*/
@@ -32,11 +31,20 @@
public class ContentProviderCursorWindowTest extends AndroidTestCase {
private static final String TAG = "ContentProviderCursorWindowTest";
- public void testQuery() throws IOException {
- Cursor cursor = getContext().getContentResolver().query(
- Uri.parse("content://cursorwindow.provider/hello"),
- null, null, null, null
- );
+ public void testQuery() {
+ // First check if the system has a patch for enforcing protected Parcel data
+ Cursor cursor;
+ try {
+ cursor = getContext().getContentResolver().query(
+ Uri.parse("content://cursorwindow.provider/hello"),
+ null, null, null, null);
+ } catch (CursorWindowAllocationException expected) {
+ Log.i(TAG, "Expected exception: " + expected);
+ return;
+ }
+
+ // If the system has no patch for protected Parcel data,
+ // it should still fail while reading from the cursor
try {
cursor.moveToFirst();
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 34e8a82..60394be 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -1375,7 +1375,19 @@
}
// start decoding
- final long kTimeOutUs = 5000;
+ MediaFormat outFormat = codec.getOutputFormat();
+ long kTimeOutUs = 5000; // 5ms timeout
+ String outMime = format.getString(MediaFormat.KEY_MIME);
+ if (outMime != null && outMime.startsWith("video/")) {
+ int outWidth = outFormat.getInteger(MediaFormat.KEY_WIDTH);
+ int outHeight = outFormat.getInteger(MediaFormat.KEY_HEIGHT);
+ // in the 4K decoding case in byte buffer mode, set kTimeOutUs to 10ms as decode may
+ // involve a memcpy
+ if (outWidth * outHeight >= 8000000) {
+ kTimeOutUs = 10000;
+ }
+ }
+
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
boolean sawInputEOS = false;
boolean sawOutputEOS = false;
diff --git a/tools/cts-device-info/Android.mk b/tools/cts-device-info/Android.mk
index 81c8caf..e38d210 100644
--- a/tools/cts-device-info/Android.mk
+++ b/tools/cts-device-info/Android.mk
@@ -36,7 +36,7 @@
LOCAL_PACKAGE_NAME := CtsDeviceInfo
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts
include $(BUILD_CTS_DEVICE_INFO_PACKAGE)