Merge "add capability to filter modules by metadata field" into oc-dev
diff --git a/apps/CameraITS/pymodules/its/objects.py b/apps/CameraITS/pymodules/its/objects.py
index 1269b84..dbddb8e 100644
--- a/apps/CameraITS/pymodules/its/objects.py
+++ b/apps/CameraITS/pymodules/its/objects.py
@@ -138,6 +138,7 @@
"android.control.afMode": 1,
"android.colorCorrection.mode": 1,
"android.tonemap.mode": 1,
+ "android.lens.opticalStabilizationMode": 0
}
def fastest_auto_capture_request(props):
diff --git a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
index a8b9863..5da1ade 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
@@ -68,7 +68,7 @@
# Pass/fail thresholds.
THRESH_MAX_CORR_DIST = 0.005
-THRESH_MAX_SHIFT_MS = 2
+THRESH_MAX_SHIFT_MS = 1
THRESH_MIN_ROT = 0.001
# lens facing
@@ -379,9 +379,7 @@
# Sleep a while for gyro events to stabilize.
time.sleep(0.5)
- # TODO: Ensure that OIS is disabled; set to DISABLE and wait some time.
-
- # Capture the frames.
+ # Capture the frames. OIS is disabled for manual captures.
facing = props['android.lens.facing']
if facing != FACING_FRONT and facing != FACING_BACK:
print "Unknown lens facing", facing
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index 49ce01c..72b7693 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -1029,6 +1029,9 @@
CaptureRequest.CONTROL_AWB_MODE_AUTO);
req.set(CaptureRequest.CONTROL_AWB_LOCK, false);
req.set(CaptureRequest.CONTROL_AWB_REGIONS, regionAWB);
+ // ITS only turns OIS on when it's explicitly requested
+ req.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE,
+ CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE_OFF);
if (evComp != 0) {
req.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, evComp);
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java
index 42fb999..0276b3c 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java
@@ -27,11 +27,13 @@
import com.android.tradefed.config.OptionSetter;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.invoker.IInvocationContext;
import com.android.tradefed.result.ITestInvocationListener;
import com.android.tradefed.suite.checker.ISystemStatusChecker;
import com.android.tradefed.suite.checker.ISystemStatusCheckerReceiver;
import com.android.tradefed.testtype.IBuildReceiver;
import com.android.tradefed.testtype.IDeviceTest;
+import com.android.tradefed.testtype.IInvocationContextReceiver;
import com.android.tradefed.testtype.IRemoteTest;
import com.google.common.annotations.VisibleForTesting;
@@ -48,7 +50,7 @@
*/
@OptionClass(alias = "compatibility")
public class RetryFactoryTest implements IRemoteTest, IDeviceTest, IBuildReceiver,
- ISystemStatusCheckerReceiver {
+ ISystemStatusCheckerReceiver, IInvocationContextReceiver {
/**
* Mirror the {@link CompatibilityTest} options in order to create it.
@@ -102,6 +104,7 @@
private List<ISystemStatusChecker> mStatusCheckers;
private IBuildInfo mBuildInfo;
private ITestDevice mDevice;
+ private IInvocationContext mContext;
@Override
public void setSystemStatusChecker(List<ISystemStatusChecker> systemCheckers) {
@@ -123,6 +126,11 @@
return mDevice;
}
+ @Override
+ public void setInvocationContext(IInvocationContext invocationContext) {
+ mContext = invocationContext;
+ }
+
/**
* Build a CompatibilityTest with appropriate filters to run only the tests of interests.
*/
@@ -155,6 +163,7 @@
test.setDevice(mDevice);
test.setBuild(mBuildInfo);
test.setSystemStatusChecker(mStatusCheckers);
+ test.setInvocationContext(mContext);
// clean the helper
helper.tearDown();
// run the retry run.
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
index 235179b..c0e8b6a 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
@@ -19,11 +19,17 @@
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.DeviceTestCase;
import com.android.tradefed.testtype.IAbi;
import com.android.tradefed.testtype.IAbiReceiver;
import com.android.tradefed.testtype.IBuildReceiver;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
/**
* Tests for ephemeral packages.
*/
@@ -53,6 +59,47 @@
private static final String TEST_CLASS = ".ClientTest";
private static final String WEBVIEW_TEST_CLASS = ".WebViewTest";
+ private static final List<Map<String, String>> EXPECTED_EXPOSED_INTENTS =
+ new ArrayList<>();
+ static {
+ // Framework intents we expect the system to expose to instant applications
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.intent.action.CHOOSER",
+ null, null));
+ // Contact intents we expect the system to expose to instant applications
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.intent.action.PICK", null, "vnd.android.cursor.dir/contact"));
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.intent.action.PICK", null, "vnd.android.cursor.dir/phone_v2"));
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.intent.action.PICK", null, "vnd.android.cursor.dir/email_v2"));
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.intent.action.PICK", null, "vnd.android.cursor.dir/postal-address_v2"));
+ // Storage intents we expect the system to expose to instant applications
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.intent.action.OPEN_DOCUMENT",
+ "android.intent.category.OPENABLE", "\\*/\\*"));
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.intent.action.OPEN_DOCUMENT", null, "\\*/\\*"));
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.intent.action.GET_CONTENT",
+ "android.intent.category.OPENABLE", "\\*/\\*"));
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.intent.action.GET_CONTENT", null, "\\*/\\*"));
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.intent.action.OPEN_DOCUMENT_TREE", null, null));
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.intent.action.CREATE_DOCUMENT",
+ "android.intent.category.OPENABLE", "text/plain"));
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.intent.action.CREATE_DOCUMENT", null, "text/plain"));
+ /** Camera intents we expect the system to expose to instant applications */
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.media.action.IMAGE_CAPTURE", null, null));
+ EXPECTED_EXPOSED_INTENTS.add(makeArgs(
+ "android.media.action.VIDEO_CAPTURE", null, null));
+ }
+
private String mOldVerifierValue;
private IAbi mAbi;
private IBuildInfo mBuildInfo;
@@ -142,7 +189,14 @@
}
public void testExposedSystemActivities() throws Exception {
- runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testExposedSystemActivities");
+ for (Map<String, String> testArgs : EXPECTED_EXPOSED_INTENTS) {
+ final boolean exposed = isIntentExposed(testArgs);
+ if (exposed) {
+ runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testExposedActivity", testArgs);
+ } else {
+ CLog.i("Skip intent; " + dumpArgs(testArgs));
+ }
+ }
}
public void testBuildSerialUnknown() throws Exception {
@@ -165,11 +219,58 @@
runDeviceTests(EPHEMERAL_1_PKG, TEST_CLASS, "testInstallPermissionGranted");
}
+ private static final HashMap<String, String> makeArgs(
+ String action, String category, String mimeType) {
+ if (action == null || action.length() == 0) {
+ fail("action not specified");
+ }
+ final HashMap<String, String> testArgs = new HashMap<>();
+ testArgs.put("action", action);
+ if (category != null && category.length() > 0) {
+ testArgs.put("category", category);
+ }
+ if (mimeType != null && mimeType.length() > 0) {
+ testArgs.put("mime_type", mimeType);
+ }
+ return testArgs;
+ }
+
+ private boolean isIntentExposed(Map<String, String> testArgs)
+ throws DeviceNotAvailableException {
+ final StringBuffer command = new StringBuffer();
+ command.append("cmd package query-activities");
+ command.append(" -a ").append(testArgs.get("action"));
+ if (testArgs.get("category") != null) {
+ command.append(" -c ").append(testArgs.get("category"));
+ }
+ if (testArgs.get("mime_type") != null) {
+ command.append(" -t ").append(testArgs.get("mime_type"));
+ }
+ return !"No activities found".equals(getDevice().executeShellCommand(command.toString()));
+ }
+
+ private static final String dumpArgs(Map<String, String> testArgs) {
+ final StringBuffer dump = new StringBuffer();
+ dump.append("action: ").append(testArgs.get("action"));
+ if (testArgs.get("category") != null) {
+ dump.append(", category: ").append(testArgs.get("category"));
+ }
+ if (testArgs.get("mime_type") != null) {
+ dump.append(", type: ").append(testArgs.get("mime_type"));
+ }
+ return dump.toString();
+ }
+
private void runDeviceTests(String packageName, String testClassName, String testMethodName)
throws DeviceNotAvailableException {
Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
}
+ private void runDeviceTests(String packageName, String testClassName, String testMethodName,
+ Map<String, String> testArgs) throws DeviceNotAvailableException {
+ Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName, testArgs);
+ }
+
private void installApp(String apk) throws Exception {
CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mBuildInfo);
assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), false));
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java
index 8e83c87..ee55180 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java
@@ -33,31 +33,43 @@
public static void runDeviceTests(ITestDevice device, String packageName)
throws DeviceNotAvailableException {
- runDeviceTests(device, packageName, null, null, USER_SYSTEM);
+ runDeviceTests(device, packageName, null, null, USER_SYSTEM, null);
}
public static void runDeviceTests(ITestDevice device, String packageName, int userId)
throws DeviceNotAvailableException {
- runDeviceTests(device, packageName, null, null, userId);
+ runDeviceTests(device, packageName, null, null, userId, null);
}
public static void runDeviceTests(ITestDevice device, String packageName, String testClassName)
throws DeviceNotAvailableException {
- runDeviceTests(device, packageName, testClassName, null, USER_SYSTEM);
+ runDeviceTests(device, packageName, testClassName, null, USER_SYSTEM, null);
}
public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
int userId) throws DeviceNotAvailableException {
- runDeviceTests(device, packageName, testClassName, null, userId);
+ runDeviceTests(device, packageName, testClassName, null, userId, null);
}
public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
String testMethodName) throws DeviceNotAvailableException {
- runDeviceTests(device, packageName, testClassName, testMethodName, USER_SYSTEM);
+ runDeviceTests(device, packageName, testClassName, testMethodName, USER_SYSTEM, null);
+ }
+
+ public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
+ String testMethodName, Map<String, String> testArgs)
+ throws DeviceNotAvailableException {
+ runDeviceTests(device, packageName, testClassName, testMethodName, USER_SYSTEM, testArgs);
}
public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
String testMethodName, int userId) throws DeviceNotAvailableException {
+ runDeviceTests(device, packageName, testClassName, testMethodName, userId, null);
+ }
+
+ public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
+ String testMethodName, int userId, Map<String, String> testArgs)
+ throws DeviceNotAvailableException {
if (testClassName != null && testClassName.startsWith(".")) {
testClassName = packageName + testClassName;
}
@@ -70,6 +82,12 @@
testRunner.setClassName(testClassName);
}
+ if (testArgs != null && testArgs.size() > 0) {
+ for (String name : testArgs.keySet()) {
+ final String value = testArgs.get(name);
+ testRunner.addInstrumentationArg(name, value);
+ }
+ }
final CollectingTestListener listener = new CollectingTestListener();
device.runInstrumentationTestsAsUser(testRunner, userId, listener);
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
index 44a797c..8ecd860 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
@@ -38,6 +38,7 @@
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.ServiceManager.ServiceNotFoundException;
import android.provider.CalendarContract;
@@ -83,50 +84,6 @@
private static final String EXTRA_ACTIVITY_RESULT =
"com.android.cts.ephemeraltest.EXTRA_ACTIVITY_RESULT";
- /**
- * Contact Intents that we expect the system to expose activities to ephemeral apps to handle
- * (if the system does not have FEATURE_WATCH).
- */
- private static final Intent[] EXPECTED_EXPOSED_SYSTEM_CONTACT_INTENTS = new Intent[] {
- makeIntent(Intent.ACTION_PICK, null, ContactsContract.Contacts.CONTENT_TYPE, null),
- makeIntent(Intent.ACTION_PICK, null,
- ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE, null),
- makeIntent(Intent.ACTION_PICK, null,
- ContactsContract.CommonDataKinds.Email.CONTENT_TYPE, null),
- makeIntent(Intent.ACTION_PICK, null,
- ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_TYPE, null),
- };
-
- /**
- * File Storage Intents that we expect the system to expose activities to ephemeral apps to
- * handle (if the system does not have FEATURE_WATCH).
- */
- private static final Intent[] EXPECTED_EXPOSED_SYSTEM_STORAGE_INTENTS = new Intent[] {
- makeIntent(Intent.ACTION_OPEN_DOCUMENT, Intent.CATEGORY_OPENABLE, "*/*", null),
- makeIntent(Intent.ACTION_OPEN_DOCUMENT, null, "*/*", null),
- makeIntent(Intent.ACTION_GET_CONTENT, Intent.CATEGORY_OPENABLE, "*/*", null),
- makeIntent(Intent.ACTION_GET_CONTENT, null, "*/*", null),
- makeIntent(Intent.ACTION_OPEN_DOCUMENT_TREE, null, null, null),
- makeIntent(Intent.ACTION_CREATE_DOCUMENT, Intent.CATEGORY_OPENABLE, "text/plain", null),
- makeIntent(Intent.ACTION_CREATE_DOCUMENT, null, "text/plain", null),
- };
-
- /**
- * Framework Intents that we expect the system to expose activities to ephemeral apps
- * to handle.
- */
- private static final Intent[] EXPECTED_EXPOSED_SYSTEM_FRAMEWORK_INTENTS = new Intent[] {
- makeIntent(Intent.ACTION_CHOOSER, null, null, null),
- };
-
- /**
- * Camera Intents that we expect the system to expose (if the system has FEATURE_CAMERA).
- */
- private static final Intent[] EXPECTED_EXPOSED_CAMERA_INTENTS = new Intent[] {
- makeIntent(MediaStore.ACTION_IMAGE_CAPTURE, null, null, null),
- makeIntent(MediaStore.ACTION_VIDEO_CAPTURE, null, null, null),
- };
-
private BroadcastReceiver mReceiver;
private final SynchronousQueue<TestResult> mResultQueue = new SynchronousQueue<>();
@@ -986,35 +943,16 @@
}
@Test
- public void testExposedSystemActivities() throws Exception {
- for (Intent queryIntent : EXPECTED_EXPOSED_SYSTEM_FRAMEWORK_INTENTS) {
- assertIntentHasExposedActivities(queryIntent);
- }
-
- PackageManager packageManager = InstrumentationRegistry.getContext().getPackageManager();
- if (!(packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)
- || packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK))) {
-
- for (Intent queryIntent : EXPECTED_EXPOSED_SYSTEM_CONTACT_INTENTS) {
- assertIntentHasExposedActivities(queryIntent);
- }
-
- for (Intent queryIntent : EXPECTED_EXPOSED_SYSTEM_STORAGE_INTENTS) {
- assertIntentHasExposedActivities(queryIntent);
- }
- }
-
- if (InstrumentationRegistry.getContext().getPackageManager()
- .hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
- for (Intent queryIntent : EXPECTED_EXPOSED_CAMERA_INTENTS) {
- assertIntentHasExposedActivities(queryIntent);
- }
- }
- }
-
- private void assertIntentHasExposedActivities(Intent queryIntent) throws Exception {
- final List<ResolveInfo> resolveInfo = InstrumentationRegistry
- .getContext().getPackageManager().queryIntentActivities(queryIntent, 0 /*flags*/);
+ public void testExposedActivity() throws Exception {
+ final Bundle testArgs = InstrumentationRegistry.getArguments();
+ assertThat(testArgs, is(notNullValue()));
+ final String action = testArgs.getString("action");
+ final String category = testArgs.getString("category");
+ final String mimeType = testArgs.getString("mime_type");
+ assertThat(action, is(notNullValue()));
+ final Intent queryIntent = makeIntent(action, category, mimeType);
+ final List<ResolveInfo> resolveInfo = InstrumentationRegistry.getContext()
+ .getPackageManager().queryIntentActivities(queryIntent, 0 /*flags*/);
if (resolveInfo == null || resolveInfo.size() == 0) {
fail("No activies found for Intent: " + queryIntent);
}
@@ -1033,7 +971,7 @@
return result;
}
- private static Intent makeIntent(String action, String category, String mimeType, Uri data) {
+ private static Intent makeIntent(String action, String category, String mimeType) {
Intent intent = new Intent(action);
if (category != null) {
intent.addCategory(category);
@@ -1041,9 +979,6 @@
if (mimeType != null) {
intent.setType(mimeType);
}
- if (data != null) {
- intent.setData(data);
- }
return intent;
}
diff --git a/hostsidetests/incident/src/com/android/server/cts/FingerprintIncidentTest.java b/hostsidetests/incident/src/com/android/server/cts/FingerprintIncidentTest.java
index ddd8ea8..9e32e1c 100644
--- a/hostsidetests/incident/src/com/android/server/cts/FingerprintIncidentTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/FingerprintIncidentTest.java
@@ -20,7 +20,8 @@
import android.service.fingerprint.FingerprintServiceDumpProto;
import android.service.fingerprint.FingerprintUserStatsProto;
-import java.util.Scanner;
+import com.android.tradefed.log.LogUtil.CLog;
+
/**
* Test to check that the fingerprint service properly outputs its dump state.
@@ -32,14 +33,15 @@
* @throws Exception
*/
public void testNoneRegistered() throws Exception {
- final FingerprintServiceDumpProto dump = getDump(FingerprintServiceDumpProto.parser(),
- "dumpsys fingerprint --proto");
-
// If the device doesn't support fingerprints, then pass.
if (!getDevice().hasFeature("android.hardware.fingerprint")) {
+ CLog.d("Bypass as android.hardware.fingerprint is not supported.");
return;
}
+ final FingerprintServiceDumpProto dump =
+ getDump(FingerprintServiceDumpProto.parser(), "dumpsys fingerprint --proto");
+
// One of them
assertEquals(1, dump.getUsersCount());
diff --git a/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java b/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java
index f042a89..f8099ef 100644
--- a/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java
+++ b/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java
@@ -26,6 +26,7 @@
import com.android.tradefed.testtype.IAbi;
import com.android.tradefed.testtype.IAbiReceiver;
import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.util.AbiUtils;
import com.android.tradefed.util.ZipUtil;
import java.io.File;
import java.util.LinkedList;
@@ -75,6 +76,19 @@
public void testJvmti() throws Exception {
final ITestDevice device = getDevice();
+ String testingArch = AbiUtils.getBaseArchForAbi(mAbi.getName());
+ String deviceArch = getDeviceBaseArch(device);
+
+ //Only bypass if Base Archs are different
+ if (!testingArch.equals(deviceArch)) {
+ CLog.d(
+ "Bypass as testing Base Arch:"
+ + testingArch
+ + " is different from DUT Base Arch:"
+ + deviceArch);
+ return;
+ }
+
if (mTestApk == null || mTestPackageName == null) {
throw new IllegalStateException("Incorrect configuration");
}
@@ -92,6 +106,12 @@
assertFalse(tr.getErrors(), tr.hasFailed());
}
+ private String getDeviceBaseArch(ITestDevice device) throws Exception {
+ String abi = device.executeShellCommand("getprop ro.product.cpu.abi").replace("\n", "");
+ CLog.d("DUT abi:" + abi);
+ return AbiUtils.getBaseArchForAbi(abi);
+ }
+
private class AttachAgent implements Runnable {
private ITestDevice mDevice;
private String mPkg;
diff --git a/hostsidetests/os/src/android/os/cts/StaticSharedLibsHostTests.java b/hostsidetests/os/src/android/os/cts/StaticSharedLibsHostTests.java
index 550b7a3..549fdc0 100644
--- a/hostsidetests/os/src/android/os/cts/StaticSharedLibsHostTests.java
+++ b/hostsidetests/os/src/android/os/cts/StaticSharedLibsHostTests.java
@@ -56,12 +56,27 @@
private static final String STATIC_LIB_PROVIDER6_APK = "CtsStaticSharedLibProviderApp6.apk";
private static final String STATIC_LIB_PROVIDER6_PKG = "android.os.lib.provider";
+ private static final String STATIC_LIB_NATIVE_PROVIDER_APK =
+ "CtsStaticSharedNativeLibProvider.apk";
+ private static final String STATIC_LIB_NATIVE_PROVIDER_PKG =
+ "android.os.lib.provider";
+
+ private static final String STATIC_LIB_NATIVE_PROVIDER_APK1 =
+ "CtsStaticSharedNativeLibProvider1.apk";
+ private static final String STATIC_LIB_NATIVE_PROVIDER_PKG1 =
+ "android.os.lib.provider";
+
private static final String STATIC_LIB_CONSUMER1_APK = "CtsStaticSharedLibConsumerApp1.apk";
private static final String STATIC_LIB_CONSUMER1_PKG = "android.os.lib.consumer1";
private static final String STATIC_LIB_CONSUMER2_APK = "CtsStaticSharedLibConsumerApp2.apk";
private static final String STATIC_LIB_CONSUMER2_PKG = "android.os.lib.consumer2";
+ private static final String STATIC_LIB_NATIVE_CONSUMER_APK
+ = "CtsStaticSharedNativeLibConsumer.apk";
+ private static final String STATIC_LIB_NATIVE_CONSUMER_PKG
+ = "android.os.lib.consumer";
+
private CompatibilityBuildHelper mBuildHelper;
@Override
@@ -401,6 +416,37 @@
}
}
+ public void testLoadCodeFromNativeLib() throws Exception {
+ getDevice().uninstallPackage(STATIC_LIB_NATIVE_CONSUMER_PKG);
+ getDevice().uninstallPackage(STATIC_LIB_NATIVE_PROVIDER_PKG);
+ try {
+ // Install library
+ assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
+ STATIC_LIB_NATIVE_PROVIDER_APK), false, false));
+ // Install the library client
+ assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
+ STATIC_LIB_NATIVE_CONSUMER_APK), false, false));
+ // Ensure the client can load native code from the library
+ runDeviceTests(STATIC_LIB_NATIVE_CONSUMER_PKG,
+ "android.os.lib.consumer.UseSharedLibraryTest",
+ "testLoadNativeCode");
+ } finally {
+ getDevice().uninstallPackage(STATIC_LIB_NATIVE_CONSUMER_PKG);
+ getDevice().uninstallPackage(STATIC_LIB_NATIVE_PROVIDER_PKG);
+ }
+ }
+
+ public void testLoadCodeFromNativeLibMultiArchViolation() throws Exception {
+ getDevice().uninstallPackage(STATIC_LIB_NATIVE_PROVIDER_PKG1);
+ try {
+ // Cannot install the library with native code if not multi-arch
+ assertNotNull(getDevice().installPackage(mBuildHelper.getTestFile(
+ STATIC_LIB_NATIVE_PROVIDER_APK1), false, false));
+ } finally {
+ getDevice().uninstallPackage(STATIC_LIB_NATIVE_PROVIDER_PKG1);
+ }
+ }
+
private void runDeviceTests(String packageName, String testClassName,
String testMethodName) throws DeviceNotAvailableException {
RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName,
diff --git a/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/Android.mk b/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/Android.mk
new file mode 100644
index 0000000..da53850
--- /dev/null
+++ b/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/Android.mk
@@ -0,0 +1,64 @@
+#
+# 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_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-test
+
+LOCAL_JNI_SHARED_LIBRARIES := libstaticsharednativelibconsumerjni
+
+LOCAL_PACKAGE_NAME := CtsStaticSharedNativeLibConsumer
+
+LOCAL_MULTILIB := both
+
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+
+#########################################################################
+# Build JNI Shared Library
+#########################################################################
+
+LOCAL_PATH:= $(LOCAL_PATH)/jni
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_CFLAGS := -Wall -Wextra -Werror
+
+LOCAL_SRC_FILES := $(call all-cpp-files-under)
+
+LOCAL_SHARED_LIBRARIES := liblog \
+ libstaticsharednativelibprovider
+
+LOCAL_CXX_STL := none
+
+LOCAL_C_INCLUDES += \
+ $(JNI_H_INCLUDE) \
+ $(LOCAL_PATH)/../CtsStaticSharedNativeLibProvider/native/version.h
+
+LOCAL_MODULE := libstaticsharednativelibconsumerjni
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/AndroidManifest.xml b/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/AndroidManifest.xml
new file mode 100755
index 0000000..34c0403
--- /dev/null
+++ b/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?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.os.lib.consumer"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
+
+ <application>
+ <uses-static-library
+ android:name="foo.bar.lib"
+ android:version="1"
+ android:certDigest="E4:95:82:FF:3A:0A:A4:C5:58:9F:C5:FE:AA:C6:B7:D6:E7:57:19:9D:D0:C6:74:2D:F7:BF:37:C2:FF:EF:95:F5">
+ </uses-static-library>
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.os.lib.consumer"/>
+
+</manifest>
diff --git a/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/jni/version.cpp b/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/jni/version.cpp
new file mode 100644
index 0000000..56835a0
--- /dev/null
+++ b/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/jni/version.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright 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 <utils/Log.h>
+
+#include "../../StaticSharedNativeLibProvider/native/version.h"
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+static jint android_os_lib_consumer_UseSharedLibraryTest_getVersion(JNIEnv*, jclass) {
+ return StaticSharedLib::android_os_lib_provider_getVersion();
+}
+
+static int registerNativeMethods(JNIEnv* env, const char* className,
+ JNINativeMethod* gMethods, int numMethods) {
+ jclass clazz;
+ clazz = env->FindClass(className);
+ if (clazz == NULL) {
+ ALOGE("Native registration unable to find class '%s'", className);
+ return JNI_FALSE;
+ }
+ if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
+ ALOGE("RegisterNatives failed for '%s'", className);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
+ JNIEnv *env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ return -1;
+ }
+
+ static JNINativeMethod gMethods[] = {
+ { "getVersion", "()I", (void*) android_os_lib_consumer_UseSharedLibraryTest_getVersion }
+ };
+
+ registerNativeMethods(env, "android/os/lib/consumer/UseSharedLibraryTest",
+ gMethods, ARRAY_SIZE(gMethods));
+
+ return JNI_VERSION_1_6;
+}
+
diff --git a/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/src/android/os/lib/consumer/UseSharedLibraryTest.java b/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/src/android/os/lib/consumer/UseSharedLibraryTest.java
new file mode 100644
index 0000000..20a3d30
--- /dev/null
+++ b/hostsidetests/os/test-apps/StaticSharedNativeLibConsumer/src/android/os/lib/consumer/UseSharedLibraryTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.os.lib.consumer;
+
+import static org.junit.Assert.assertSame;
+
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class UseSharedLibraryTest {
+ static {
+ System.loadLibrary("staticsharednativelibconsumerjni");
+ }
+
+ @Test
+ public void testLoadNativeCode() throws Exception {
+ assertSame(1, getVersion());
+ }
+
+ private static native int getVersion();
+}
diff --git a/hostsidetests/os/test-apps/StaticSharedNativeLibProvider/Android.mk b/hostsidetests/os/test-apps/StaticSharedNativeLibProvider/Android.mk
new file mode 100644
index 0000000..bc09dc4
--- /dev/null
+++ b/hostsidetests/os/test-apps/StaticSharedNativeLibProvider/Android.mk
@@ -0,0 +1,63 @@
+#
+# 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_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JNI_SHARED_LIBRARIES := libstaticsharednativelibprovider
+
+LOCAL_PACKAGE_NAME := CtsStaticSharedNativeLibProvider
+
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_AAPT_FLAGS := --shared-lib
+
+LOCAL_EXPORT_PACKAGE_RESOURCES := true
+
+LOCAL_MULTILIB := both
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-b
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+
+#########################################################################
+# Build Shared Library
+#########################################################################
+
+LOCAL_PATH:= $(LOCAL_PATH)/native
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_CFLAGS := -Wall -Wextra -Werror
+
+LOCAL_SRC_FILES := $(call all-cpp-files-under)
+
+LOCAL_MODULE := libstaticsharednativelibprovider
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/native/version.h
+
+LOCAL_CXX_STL := none
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/hostsidetests/os/test-apps/StaticSharedNativeLibProvider/AndroidManifest.xml b/hostsidetests/os/test-apps/StaticSharedNativeLibProvider/AndroidManifest.xml
new file mode 100755
index 0000000..0ad054a
--- /dev/null
+++ b/hostsidetests/os/test-apps/StaticSharedNativeLibProvider/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?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.os.lib.provider"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <application
+ android:multiArch="true"
+ android:hasCode="false">
+ <static-library android:name="foo.bar.lib" android:version="1"/>
+ </application>
+</manifest>
diff --git a/hostsidetests/os/test-apps/StaticSharedNativeLibProvider/native/version.cpp b/hostsidetests/os/test-apps/StaticSharedNativeLibProvider/native/version.cpp
new file mode 100644
index 0000000..b29792d
--- /dev/null
+++ b/hostsidetests/os/test-apps/StaticSharedNativeLibProvider/native/version.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright 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 "version.h"
+
+namespace StaticSharedLib {
+ int android_os_lib_provider_getVersion() {
+ return 1;
+ }
+}
diff --git a/hostsidetests/os/test-apps/StaticSharedNativeLibProvider/native/version.h b/hostsidetests/os/test-apps/StaticSharedNativeLibProvider/native/version.h
new file mode 100644
index 0000000..9a48f0b
--- /dev/null
+++ b/hostsidetests/os/test-apps/StaticSharedNativeLibProvider/native/version.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 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.
+ */
+
+namespace StaticSharedLib {
+ int android_os_lib_provider_getVersion();
+}
diff --git a/hostsidetests/os/test-apps/StaticSharedNativeLibProvider1/Android.mk b/hostsidetests/os/test-apps/StaticSharedNativeLibProvider1/Android.mk
new file mode 100644
index 0000000..0abc351d
--- /dev/null
+++ b/hostsidetests/os/test-apps/StaticSharedNativeLibProvider1/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_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JNI_SHARED_LIBRARIES := libstaticsharednativelibprovider
+
+LOCAL_PACKAGE_NAME := CtsStaticSharedNativeLibProvider1
+
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_AAPT_FLAGS := --shared-lib
+
+LOCAL_EXPORT_PACKAGE_RESOURCES := true
+
+LOCAL_MULTILIB := both
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-b
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/os/test-apps/StaticSharedNativeLibProvider1/AndroidManifest.xml b/hostsidetests/os/test-apps/StaticSharedNativeLibProvider1/AndroidManifest.xml
new file mode 100755
index 0000000..9050112
--- /dev/null
+++ b/hostsidetests/os/test-apps/StaticSharedNativeLibProvider1/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?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.os.lib.provider"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <application
+ android:hasCode="false">
+ <static-library android:name="foo.bar.lib" android:version="1"/>
+ </application>
+</manifest>
diff --git a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
index eb18aed..74ead54 100755
--- a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
+++ b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
@@ -35,7 +35,7 @@
public class ComparisonTask implements Callable<Pair<String, File>> {
private static final String TAG = "ComparisonTask";
- private static final int IMAGE_THRESHOLD = 4;
+ private static final int IMAGE_THRESHOLD = 8;
/** Neutral gray for blending colors. */
private static final int GRAY = 0xFF808080;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
index 7d2f7e2..07d4721 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
@@ -54,7 +54,9 @@
*/
final class CannedFillResponse {
+ private final ResponseType mResponseType;
private final List<CannedDataset> mDatasets;
+ private final String mFailureMessage;
private final int mSaveType;
private final String[] mRequiredSavableIds;
private final String[] mOptionalSavableIds;
@@ -69,7 +71,9 @@
private final int mFlags;
private CannedFillResponse(Builder builder) {
+ mResponseType = builder.mResponseType;
mDatasets = builder.mDatasets;
+ mFailureMessage = builder.mFailureMessage;
mRequiredSavableIds = builder.mRequiredSavableIds;
mOptionalSavableIds = builder.mOptionalSavableIds;
mSaveDescription = builder.mSaveDescription;
@@ -88,7 +92,23 @@
* Constant used to pass a {@code null} response to the
* {@link FillCallback#onSuccess(FillResponse)} method.
*/
- static final CannedFillResponse NO_RESPONSE = new Builder().build();
+ static final CannedFillResponse NO_RESPONSE =
+ new Builder(ResponseType.NULL).build();
+
+ /**
+ * Constant used to emulate a timeout by not calling any method on {@link FillCallback}.
+ */
+ static final CannedFillResponse DO_NOT_REPLY_RESPONSE =
+ new Builder(ResponseType.TIMEOUT).build();
+
+
+ String getFailureMessage() {
+ return mFailureMessage;
+ }
+
+ ResponseType getResponseType() {
+ return mResponseType;
+ }
/**
* Creates a new response, replacing the dataset field ids by the real ids from the assist
@@ -132,10 +152,12 @@
@Override
public String toString() {
- return "CannedFillResponse: [datasets=" + mDatasets
+ return "CannedFillResponse: [type=" + mResponseType
+ + ",datasets=" + mDatasets
+ ", requiredSavableIds=" + Arrays.toString(mRequiredSavableIds)
+ ", optionalSavableIds=" + Arrays.toString(mOptionalSavableIds)
- + ", mFlags=" + mFlags
+ + ", flags=" + mFlags
+ + ", failureMessage=" + mFailureMessage
+ ", saveDescription=" + mSaveDescription
+ ", hasPresentation=" + (mPresentation != null)
+ ", hasAuthentication=" + (mAuthentication != null)
@@ -144,8 +166,16 @@
+ "]";
}
+ enum ResponseType {
+ NORMAL,
+ NULL,
+ TIMEOUT
+ }
+
static class Builder {
private final List<CannedDataset> mDatasets = new ArrayList<>();
+ private final ResponseType mResponseType;
+ private String mFailureMessage;
private String[] mRequiredSavableIds;
private String[] mOptionalSavableIds;
private String mSaveDescription;
@@ -159,7 +189,16 @@
private IntentSender mNegativeActionListener;
private int mFlags;
+ public Builder(ResponseType type) {
+ mResponseType = type;
+ }
+
+ public Builder() {
+ this(ResponseType.NORMAL);
+ }
+
public Builder addDataset(CannedDataset dataset) {
+ assertWithMessage("already set failure").that(mFailureMessage).isNull();
mDatasets.add(dataset);
return this;
}
@@ -231,8 +270,7 @@
/**
* Sets the negative action spec.
*/
- public Builder setNegativeAction(int style,
- IntentSender listener) {
+ public Builder setNegativeAction(int style, IntentSender listener) {
mNegativeActionStyle = style;
mNegativeActionListener = listener;
return this;
@@ -241,6 +279,15 @@
public CannedFillResponse build() {
return new CannedFillResponse(this);
}
+
+ /**
+ * Sets the response to call {@link FillCallback#onFailure(CharSequence)}.
+ */
+ public Builder returnFailure(String message) {
+ assertWithMessage("already added datasets").that(mDatasets).isEmpty();
+ mFailureMessage = message;
+ return this;
+ }
}
/**
diff --git a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
index eca8970..81e3387 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
@@ -16,11 +16,12 @@
package android.autofillservice.cts;
-import static android.autofillservice.cts.CannedFillResponse.NO_RESPONSE;
+import static android.autofillservice.cts.CannedFillResponse.ResponseType.NULL;
+import static android.autofillservice.cts.CannedFillResponse.ResponseType.TIMEOUT;
import static android.autofillservice.cts.Helper.CONNECTION_TIMEOUT_MS;
import static android.autofillservice.cts.Helper.FILL_TIMEOUT_MS;
-import static android.autofillservice.cts.Helper.SAVE_TIMEOUT_MS;
import static android.autofillservice.cts.Helper.IDLE_UNBIND_TIMEOUT_MS;
+import static android.autofillservice.cts.Helper.SAVE_TIMEOUT_MS;
import static android.autofillservice.cts.Helper.dumpAutofillService;
import static android.autofillservice.cts.Helper.dumpStructure;
@@ -39,11 +40,11 @@
import android.service.autofill.SaveCallback;
import android.util.Log;
+import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
-import java.util.List;
/**
* Implementation of {@link AutofillService} used in the tests.
@@ -326,12 +327,24 @@
dumpStructure("onFillRequest() without response", contexts);
throw new RetryableException("No CannedResponse");
}
- if (response == NO_RESPONSE) {
+ if (response.getResponseType() == NULL) {
Log.d(TAG, "onFillRequest(): replying with null");
callback.onSuccess(null);
return;
}
+ if (response.getResponseType() == TIMEOUT) {
+ Log.d(TAG, "onFillRequest(): not replying at all");
+ return;
+ }
+
+ final String failureMessage = response.getFailureMessage();
+ if (failureMessage != null) {
+ Log.v(TAG, "onFillRequest(): failureMessage = " + failureMessage);
+ callback.onFailure(failureMessage);
+ return;
+ }
+
final FillResponse fillResponse = response.asFillResponse(
(id) -> Helper.findNodeByResourceId(contexts, id));
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index ac82d89..686a056 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -19,6 +19,8 @@
import static android.app.Activity.RESULT_CANCELED;
import static android.app.Activity.RESULT_OK;
import static android.autofillservice.cts.CannedFillResponse.NO_RESPONSE;
+import static android.autofillservice.cts.CheckoutActivity.ID_CC_NUMBER;
+import static android.autofillservice.cts.CannedFillResponse.DO_NOT_REPLY_RESPONSE;
import static android.autofillservice.cts.Helper.ID_PASSWORD;
import static android.autofillservice.cts.Helper.ID_PASSWORD_LABEL;
import static android.autofillservice.cts.Helper.ID_USERNAME;
@@ -68,6 +70,7 @@
import android.graphics.Color;
import android.os.Bundle;
import android.service.autofill.FillEventHistory;
+import android.service.autofill.FillResponse;
import android.service.autofill.SaveInfo;
import android.support.test.rule.ActivityTestRule;
import android.support.test.uiautomator.UiObject2;
@@ -2726,6 +2729,212 @@
}
@Test
+ public void checkFillSelectionIsResetAfterReturningNull() throws Exception {
+ enableService();
+
+ // First reset
+ sReplier.addResponse(new CannedFillResponse.Builder().addDataset(
+ new CannedDataset.Builder()
+ .setField(ID_USERNAME, "username")
+ .setPresentation(createPresentation("dataset1"))
+ .build())
+ .build());
+ mActivity.onUsername(View::requestFocus);
+ sReplier.getNextFillRequest();
+ sUiBot.selectDataset("dataset1");
+
+ eventually(() -> {
+ // Verify fill selection
+ FillEventHistory selection = InstrumentedAutoFillService.peekInstance()
+ .getFillEventHistory();
+ assertThat(selection.getClientState()).isNull();
+
+ assertThat(selection.getEvents().size()).isEqualTo(1);
+ FillEventHistory.Event event = selection.getEvents().get(0);
+ assertThat(event.getType()).isEqualTo(TYPE_DATASET_SELECTED);
+ assertThat(event.getDatasetId()).isNull();
+ });
+
+ // Second request
+ sReplier.addResponse(NO_RESPONSE);
+ mActivity.onPassword(View::requestFocus);
+ sReplier.getNextFillRequest();
+ sUiBot.assertNoDatasets();
+
+ eventually(() -> {
+ // Verify fill selection
+ FillEventHistory selection = InstrumentedAutoFillService.peekInstance()
+ .getFillEventHistory();
+ assertThat(selection).isNull();
+ });
+ }
+
+ @Test
+ public void checkFillSelectionIsResetAfterReturningError() throws Exception {
+ enableService();
+
+ // First reset
+ sReplier.addResponse(new CannedFillResponse.Builder().addDataset(
+ new CannedDataset.Builder()
+ .setField(ID_USERNAME, "username")
+ .setPresentation(createPresentation("dataset1"))
+ .build())
+ .build());
+ mActivity.onUsername(View::requestFocus);
+ waitUntilConnected();
+ sReplier.getNextFillRequest();
+ sUiBot.selectDataset("dataset1");
+
+ eventually(() -> {
+ // Verify fill selection
+ FillEventHistory selection = InstrumentedAutoFillService.peekInstance()
+ .getFillEventHistory();
+ assertThat(selection.getClientState()).isNull();
+
+ assertThat(selection.getEvents().size()).isEqualTo(1);
+ FillEventHistory.Event event = selection.getEvents().get(0);
+ assertThat(event.getType()).isEqualTo(TYPE_DATASET_SELECTED);
+ assertThat(event.getDatasetId()).isNull();
+ });
+
+ // Second request
+ sReplier.addResponse(new CannedFillResponse.Builder().returnFailure("D'OH!").build());
+ mActivity.onPassword(View::requestFocus);
+ sReplier.getNextFillRequest();
+ sUiBot.assertNoDatasets();
+
+ eventually(() -> {
+ // Verify fill selection
+ FillEventHistory selection = InstrumentedAutoFillService.peekInstance()
+ .getFillEventHistory();
+ assertThat(selection).isNull();
+ });
+ }
+
+ @Test
+ public void checkFillSelectionIsResetAfterTimeout() throws Exception {
+ enableService();
+
+ // First reset
+ sReplier.addResponse(new CannedFillResponse.Builder().addDataset(
+ new CannedDataset.Builder()
+ .setField(ID_USERNAME, "username")
+ .setPresentation(createPresentation("dataset1"))
+ .build())
+ .build());
+ mActivity.onUsername(View::requestFocus);
+ waitUntilConnected();
+ sReplier.getNextFillRequest();
+ sUiBot.selectDataset("dataset1");
+
+ eventually(() -> {
+ // Verify fill selection
+ FillEventHistory selection = InstrumentedAutoFillService.peekInstance()
+ .getFillEventHistory();
+ assertThat(selection.getClientState()).isNull();
+
+ assertThat(selection.getEvents().size()).isEqualTo(1);
+ FillEventHistory.Event event = selection.getEvents().get(0);
+ assertThat(event.getType()).isEqualTo(TYPE_DATASET_SELECTED);
+ assertThat(event.getDatasetId()).isNull();
+ });
+
+ // Second request
+ sReplier.addResponse(DO_NOT_REPLY_RESPONSE);
+ mActivity.onPassword(View::requestFocus);
+ sReplier.getNextFillRequest();
+ waitUntilDisconnected();
+
+ eventually(() -> {
+ // Verify fill selection
+ FillEventHistory selection = InstrumentedAutoFillService.peekInstance()
+ .getFillEventHistory();
+ assertThat(selection).isNull();
+ });
+ }
+
+ private Bundle getBundle(String key, String value) {
+ final Bundle bundle = new Bundle();
+ bundle.putString(key, value);
+ return bundle;
+ }
+
+ /**
+ * Tests the following scenario:
+ *
+ * <ol>
+ * <li>Activity A is launched.
+ * <li>Activity A triggers autofill.
+ * <li>Activity B is launched.
+ * <li>Activity B triggers autofill.
+ * <li>User goes back to Activity A.
+ * <li>User triggers save on Activity A - at this point, service should have stats of
+ * activity B, and stats for activity A should have beeen discarded.
+ * </ol>
+ */
+ @Test
+ public void checkFillSelectionFromPreviousSessionIsDiscarded() throws Exception {
+ enableService();
+
+ // Launch activity A
+ sReplier.addResponse(new CannedFillResponse.Builder()
+ .setExtras(getBundle("activity", "A"))
+ .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_USERNAME, ID_PASSWORD)
+ .build());
+
+ // Trigger autofill on activity A
+ mActivity.onUsername(View::requestFocus);
+ waitUntilConnected();
+ sReplier.getNextFillRequest();
+
+ // Verify fill selection for Activity A
+ FillEventHistory selectionA = InstrumentedAutoFillService.peekInstance()
+ .getFillEventHistory();
+ assertThat(selectionA.getClientState().getString("activity")).isEqualTo("A");
+ assertThat(selectionA.getEvents()).isNull();
+
+ // Launch activity B
+ getContext().startActivity(new Intent(getContext(), CheckoutActivity.class));
+
+ // Trigger autofill on activity B
+ sReplier.addResponse(new CannedFillResponse.Builder()
+ .setExtras(getBundle("activity", "B"))
+ .addDataset(new CannedDataset.Builder()
+ .setField(ID_CC_NUMBER, "4815162342")
+ .setPresentation(createPresentation("datasetB"))
+ .build())
+ .build());
+ sUiBot.focusByRelativeId(ID_CC_NUMBER);
+ sReplier.getNextFillRequest();
+
+ // Verify fill selection for Activity B
+ final FillEventHistory selectionB = InstrumentedAutoFillService.peekInstance()
+ .getFillEventHistory();
+ assertThat(selectionB.getClientState().getString("activity")).isEqualTo("B");
+ assertThat(selectionB.getEvents()).isNull();
+
+ // Now switch back to A...
+ sUiBot.pressBack(); // dismiss keyboard
+ sUiBot.pressBack(); // dismiss task
+ // ...and trigger save
+ // Set credentials...
+ mActivity.onUsername((v) -> v.setText("malkovich"));
+ mActivity.onPassword((v) -> v.setText("malkovich"));
+ final String expectedMessage = getWelcomeMessage("malkovich");
+ final String actualMessage = mActivity.tapLogin();
+ assertWithMessage("Wrong welcome msg").that(actualMessage).isEqualTo(expectedMessage);
+ sUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
+ sReplier.getNextSaveRequest();
+
+ // Finally, make sure history is right
+ final FillEventHistory finalSelection = InstrumentedAutoFillService.peekInstance()
+ .getFillEventHistory();
+ assertThat(finalSelection.getClientState().getString("activity")).isEqualTo("B");
+ assertThat(finalSelection.getEvents()).isNull();
+
+ }
+
+ @Test
public void testIsServiceEnabled() throws Exception {
disableService();
final AutofillManager afm = mActivity.getAutofillManager();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 97f073a..281071e 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -205,8 +205,15 @@
* Gets the text set on a view.
*/
String getTextById(String id) {
- UiObject2 view = waitForObject(By.res(id));
- return view.getText();
+ final UiObject2 obj = waitForObject(By.res(id));
+ return obj.getText();
+ }
+
+ /**
+ * Focus in the view with the given resource id.
+ */
+ void focusByRelativeId(String id) {
+ waitForObject(By.res(mPackageName, id)).click();
}
/**
diff --git a/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
index 83386da..34d29e5 100644
--- a/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
@@ -59,7 +59,7 @@
private static final int FRAME_TIMEOUT_MS = 1000;
private static final int NUM_FRAMES_VERIFIED = 30;
private static final int NUM_TEST_PATTERN_FRAMES_VERIFIED = 60;
- private static final float FRAME_DURATION_ERROR_MARGIN = 0.005f; // 0.5 percent error margin.
+ private static final float FRAME_DURATION_ERROR_MARGIN = 0.01f; // 1 percent error margin.
private static final int PREPARE_TIMEOUT_MS = 10000; // 10 s
@Override
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
index df0a8a1f..8c60231 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
@@ -80,7 +80,7 @@
protected static final String DEBUG_FILE_NAME_BASE =
Environment.getExternalStorageDirectory().getPath();
protected static final int WAIT_FOR_RESULT_TIMEOUT_MS = 3000;
- protected static final float FRAME_DURATION_ERROR_MARGIN = 0.005f; // 0.5 percent error margin.
+ protected static final float FRAME_DURATION_ERROR_MARGIN = 0.01f; // 1 percent error margin.
protected static final int NUM_RESULTS_WAIT_TIMEOUT = 100;
protected static final int NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY = 8;
protected static final int MIN_FRAME_DURATION_ERROR_MARGIN = 100; // ns
diff --git a/tests/tests/nativehardware/jni/AHardwareBufferTest.cpp b/tests/tests/nativehardware/jni/AHardwareBufferTest.cpp
index adb9a91..f0cbd0c 100644
--- a/tests/tests/nativehardware/jni/AHardwareBufferTest.cpp
+++ b/tests/tests/nativehardware/jni/AHardwareBufferTest.cpp
@@ -255,4 +255,29 @@
AHardwareBuffer_release(buffer);
}
+void AHardwareBufferTest::testAHardwareBufferSupportsLayeredBuffersForVr(JNIEnv* env) {
+ AHardwareBuffer* buffer = NULL;
+ AHardwareBuffer_Desc desc = {};
+
+ desc.width = 2;
+ desc.height = 4;
+ desc.layers = 2;
+ desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
+ desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
+ int res = AHardwareBuffer_allocate(&desc, &buffer);
+ ASSERT_EQ(NO_ERROR, res);
+ ASSERT_EQ(std::string(), CheckAHardwareBufferMatchesDesc(buffer, desc));
+ AHardwareBuffer_release(buffer);
+ buffer = NULL;
+
+ desc.width = 4;
+ desc.height = 12;
+ desc.layers = 3;
+ desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
+ desc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
+ res = AHardwareBuffer_allocate(&desc, &buffer);
+ ASSERT_EQ(NO_ERROR, res);
+ ASSERT_EQ(std::string(), CheckAHardwareBufferMatchesDesc(buffer, desc));
+}
+
} // namespace android
diff --git a/tests/tests/nativehardware/jni/AHardwareBufferTest.h b/tests/tests/nativehardware/jni/AHardwareBufferTest.h
index 7f39f57..45a7bcb 100644
--- a/tests/tests/nativehardware/jni/AHardwareBufferTest.h
+++ b/tests/tests/nativehardware/jni/AHardwareBufferTest.h
@@ -36,6 +36,7 @@
void testAHardwareBuffer_describe_Succeeds(JNIEnv *env);
void testAHardwareBuffer_SendAndRecv_Succeeds(JNIEnv *env);
void testAHardwareBuffer_Lock_and_Unlock_Succeed(JNIEnv *env);
+ void testAHardwareBufferSupportsLayeredBuffersForVr(JNIEnv *env);
};
} // namespace android
diff --git a/tests/tests/nativehardware/jni/android_hardware_cts_AHardwareBufferNativeTest.cpp b/tests/tests/nativehardware/jni/android_hardware_cts_AHardwareBufferNativeTest.cpp
index afe17d6..30850c7 100644
--- a/tests/tests/nativehardware/jni/android_hardware_cts_AHardwareBufferNativeTest.cpp
+++ b/tests/tests/nativehardware/jni/android_hardware_cts_AHardwareBufferNativeTest.cpp
@@ -37,7 +37,7 @@
delete reinterpret_cast<AHardwareBufferTest*>(instance);
}
-void test(JNIEnv* env, jclass, jlong instance) {
+void test(JNIEnv* env, jclass, jlong instance, jboolean vrHighPerformanceSupported) {
AHardwareBufferTest *test = reinterpret_cast<AHardwareBufferTest*>(instance);
ASSERT_NOT_NULL(test);
@@ -64,12 +64,18 @@
ALOGI("testAHardwareBuffer_Lock_and_Unlock_Succeed");
test->testAHardwareBuffer_Lock_and_Unlock_Succeed(env);
RETURN_ON_EXCEPTION();
+
+ if (vrHighPerformanceSupported == JNI_TRUE) {
+ ALOGI("testAHardwareBuffer_Lock_and_Unlock_Succeed");
+ test->testAHardwareBufferSupportsLayeredBuffersForVr(env);
+ RETURN_ON_EXCEPTION();
+ }
}
JNINativeMethod gMethods[] = {
{"nativeSetUp", "()J", (void *)setUp},
{"nativeTearDown", "(J)V", (void *)tearDown},
- {"nativeTest", "(J)V", (void *)test},
+ {"nativeTest", "(JZ)V", (void *)test},
};
} // namespace
diff --git a/tests/tests/nativehardware/src/android/hardware/cts/AHardwareBufferNativeTest.java b/tests/tests/nativehardware/src/android/hardware/cts/AHardwareBufferNativeTest.java
index 883ca3f..94b25fb 100644
--- a/tests/tests/nativehardware/src/android/hardware/cts/AHardwareBufferNativeTest.java
+++ b/tests/tests/nativehardware/src/android/hardware/cts/AHardwareBufferNativeTest.java
@@ -16,6 +16,7 @@
package android.hardware.cts;
+import android.content.pm.PackageManager;
import android.test.AndroidTestCase;
/**
@@ -26,7 +27,7 @@
public class AHardwareBufferNativeTest extends AndroidTestCase {
protected native long nativeSetUp();
protected native void nativeTearDown(long instance);
- private native void nativeTest(long instance);
+ private native void nativeTest(long instance, boolean vrHighPerformanceSupported);
private long mNativeInstance;
static {
@@ -46,6 +47,8 @@
}
public void testNative() throws AssertionError {
- nativeTest(mNativeInstance);
+ PackageManager pm = getContext().getPackageManager();
+ nativeTest(mNativeInstance, pm.hasSystemFeature(
+ PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE));
}
}
diff --git a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
index b951378..cd6dbb2 100644
--- a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -789,24 +789,40 @@
/** Verify that accept_ra_rt_info_min_plen exists and is set to the expected value */
public void testAcceptRaRtInfoMinPlen() throws Exception {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+ Log.i(TAG, "testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent cannot execute unless device supports WiFi");
+ return;
+ }
Scanner s = makeWifiSysctlScanner("accept_ra_rt_info_min_plen");
assertEquals(IPV6_WIFI_ACCEPT_RA_RT_INFO_MIN_PLEN, s.nextInt());
}
/** Verify that accept_ra_rt_info_max_plen exists and is set to the expected value */
public void testAcceptRaRtInfoMaxPlen() throws Exception {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+ Log.i(TAG, "testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent cannot execute unless device supports WiFi");
+ return;
+ }
Scanner s = makeWifiSysctlScanner("accept_ra_rt_info_max_plen");
assertEquals(IPV6_WIFI_ACCEPT_RA_RT_INFO_MAX_PLEN, s.nextInt());
}
/** Verify that router_solicitations exists and is set to the expected value */
public void testRouterSolicitations() throws Exception {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+ Log.i(TAG, "testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent cannot execute unless device supports WiFi");
+ return;
+ }
Scanner s = makeWifiSysctlScanner("router_solicitations");
assertEquals(IPV6_WIFI_ROUTER_SOLICITATIONS, s.nextInt());
}
/** Verify that router_solicitation_max_interval exists and is in an acceptable interval */
public void testRouterSolicitationMaxInterval() throws Exception {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+ Log.i(TAG, "testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent cannot execute unless device supports WiFi");
+ return;
+ }
Scanner s = makeWifiSysctlScanner("router_solicitation_max_interval");
int interval = s.nextInt();
// Verify we're in the interval [15 minutes, 60 minutes]. Lower values may adversely
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index f667015..ea63f78 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -583,6 +583,10 @@
* @throws Exception
*/
public void testAddPasspointConfigWithUserCredential() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
testAddPasspointConfig(generatePasspointConfig(generateUserCredential()));
}
@@ -593,6 +597,10 @@
* @throws Exception
*/
public void testAddPasspointConfigWithCertCredential() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
testAddPasspointConfig(generatePasspointConfig(generateCertCredential()));
}
@@ -603,6 +611,10 @@
* @throws Exception
*/
public void testAddPasspointConfigWithSimCredential() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
testAddPasspointConfig(generatePasspointConfig(generateSimCredential()));
}
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowTest.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowTest.java
index 03bbd32..731dbfb 100644
--- a/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowTest.java
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceActivityFlowTest.java
@@ -134,26 +134,22 @@
assertInitialState();
- // Workaround for some focus bug in the framework that would ruin screenshot test.
- mTestUtils.tapOnViewWithText(mActivity.getTitle().toString());
-
CharSequence title = mActivity.getTitle();
- // Take screenshot
- Bitmap before = mTestUtils.takeScreenshot();
-
tapOnPrefs2Header();
assertHeadersHidden();
pressBack();
assertHeadersShown();
+ // Verify that no headers are focused.
+ assertHeadersNotFocused();
+
// Verify that the title was properly restored.
assertEquals(title, mActivity.getTitle());
- // Compare screenshots
- Bitmap after = mTestUtils.takeScreenshot();
- assertScreenshotsAreEqual(before, after);
+ // Verify that everthing restores back to initial state again.
+ assertInitialState();
}
void backPressToExitInner() {
@@ -317,14 +313,14 @@
false /* noHeaders */, INITIAL_TITLE_RES_ID);
assertInitialStateForFragment();
- String testTitle = mActivity.getResources().getString(INITIAL_TITLE_RES_ID);
if (mIsMultiPane) {
+ String testTitle = mActivity.getResources().getString(INITIAL_TITLE_RES_ID);
// Title should not be shown.
assertTextHidden(testTitle);
} else {
// Title should be shown.
- assertTextShown(testTitle);
+ assertTitleShown();
}
}
@@ -389,8 +385,7 @@
assertPanelPrefs1Hidden();
assertPanelPrefs2Shown();
- String testTitle = mActivity.getResources().getString(INITIAL_TITLE_RES_ID);
- assertTextShown(testTitle);
+ assertTitleShown();
}
/**
@@ -742,6 +737,11 @@
assertTextShown(PREFS2_HEADER_TITLE);
}
+ private void assertHeadersNotFocused() {
+ assertFalse(mTestUtils.isTextFocused(PREFS1_HEADER_TITLE));
+ assertFalse(mTestUtils.isTextFocused(PREFS2_HEADER_TITLE));
+ }
+
private void assertHeadersHidden() {
// We check '&' instead of each individual separately because these headers are also part
// of individual preference panels breadcrumbs so it would fail for one.
@@ -781,6 +781,14 @@
assertTrue(mTestUtils.isTextHidden(text));
}
+ private void assertTitleShown() {
+ if (!mTestUtils.isOnWatchUiMode()) {
+ // On watch, activity title is not shown by default.
+ String testTitle = mActivity.getResources().getString(INITIAL_TITLE_RES_ID);
+ assertTextShown(testTitle);
+ }
+ }
+
private void recreate() {
runOnUiThread(() -> mActivity.recreate());
SystemClock.sleep(1000);
diff --git a/tests/tests/preference2/src/android/preference2/cts/TestUtils.java b/tests/tests/preference2/src/android/preference2/cts/TestUtils.java
index 04e0ed9..6fdeff4 100644
--- a/tests/tests/preference2/src/android/preference2/cts/TestUtils.java
+++ b/tests/tests/preference2/src/android/preference2/cts/TestUtils.java
@@ -19,13 +19,16 @@
import android.app.Activity;
import android.app.Instrumentation;
import android.app.UiAutomation;
+import android.app.UiModeManager;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiScrollable;
import android.support.test.uiautomator.UiSelector;
import com.android.compatibility.common.util.SystemUtil;
@@ -50,33 +53,63 @@
}
Bitmap takeScreenshot() {
+ // Only take screenshot once the screen is stable enough.
+ device.waitForIdle();
+
Bitmap bt = mAutomation.takeScreenshot();
// Crop-out the top bar where current time is displayed since any time change would
// introduce flakiness (we are cutting 5% of the screen height).
int yToCut = bt.getHeight() / 20;
- // Crop the right side for scrollbar which might or might not be visible.
- int xToCut = bt.getWidth() / 20;
+ // Crop the right side for scrollbar which might or might not be visible. But on
+ // watch, the scroll bar is a curve and occupies 20% of the screen on the right
+ // hand side.
+ int xToCut = isOnWatchUiMode() ? bt.getWidth() / 5 : bt.getWidth() / 20;
bt = Bitmap.createBitmap(
bt, 0, yToCut, bt.getWidth() - xToCut, bt.getHeight() - yToCut);
+
return bt;
}
- void tapOnViewWithText(String text) {
- UiObject obj = device.findObject(new UiSelector().textMatches(text));
- try {
- obj.click();
- } catch (UiObjectNotFoundException e) {
- throw new AssertionError("View with text '" + text + "' was not found!", e);
+ void tapOnViewWithText(String searchText) {
+ if (searchText == null) {
+ return;
}
- device.waitForIdle();
+
+ try {
+ // If the current UI has shown text, just click on it.
+ UiObject text = new UiObject(new UiSelector().text(searchText));
+ if (text.exists() || text.waitForExists(1000)) {
+ text.click();
+ return;
+ }
+
+ // Otherwise, if it is scrollable, scroll to where the text is and tap.
+ UiScrollable textScroll = new UiScrollable(new UiSelector().scrollable(true));
+
+ textScroll.scrollIntoView(new UiSelector().text(searchText));
+ text = new UiObject(new UiSelector().text(searchText));
+ text.click();
+ } catch (UiObjectNotFoundException e) {
+ throw new AssertionError("View with text '" + searchText + "' was not found!", e);
+ }
}
- boolean isTextShown(String text) {
- UiObject obj = device.findObject(new UiSelector().textMatches(text));
- if (obj.exists()) {
+ boolean isTextShown(String searchText) {
+ if (searchText == null) {
+ return false;
+ }
+
+ UiObject text = new UiObject(new UiSelector().text(searchText));
+ if (text.exists() || text.waitForExists(1000)) {
return true;
}
- return obj.waitForExists(1000);
+
+ UiScrollable textScroll = new UiScrollable(new UiSelector().scrollable(true));
+ try {
+ return textScroll.scrollIntoView(new UiSelector().text(searchText));
+ } catch (UiObjectNotFoundException e) {
+ return false;
+ }
}
boolean isTextHidden(String text) {
@@ -87,6 +120,21 @@
return obj.waitUntilGone(1000);
}
+ boolean isTextFocused(String text) {
+ UiObject obj = device.findObject(new UiSelector().textMatches(text));
+ try {
+ return obj.isFocused();
+ } catch(UiObjectNotFoundException e) {
+ return false;
+ }
+ }
+
+ boolean isOnWatchUiMode() {
+ Context context = mInstrumentation.getTargetContext();
+ UiModeManager uiModeManager = context.getSystemService(UiModeManager.class);
+ return uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_WATCH;
+ }
+
void getMultiWindowFocus(Context context) {
// Get window focus (otherwise back press would close multi-window instead of firing to the
// Activity and also the automator would fail to find objects on the screen.
diff --git a/tests/tests/print/src/android/print/cts/BasePrintTest.java b/tests/tests/print/src/android/print/cts/BasePrintTest.java
index 355637b..ce2dc65 100644
--- a/tests/tests/print/src/android/print/cts/BasePrintTest.java
+++ b/tests/tests/print/src/android/print/cts/BasePrintTest.java
@@ -191,9 +191,6 @@
sInstrumentation = InstrumentationRegistry.getInstrumentation();
sUiDevice = UiDevice.getInstance(sInstrumentation);
- assumeTrue(sInstrumentation.getContext().getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_PRINTING));
-
// Make sure we start with a clean slate.
Log.d(LOG_TAG, "clearPrintSpoolerData()");
clearPrintSpoolerData();
@@ -237,6 +234,18 @@
sAnimatiorDurationScaleBefore = Float.NaN;
}
+ Log.d(LOG_TAG, "setUpClass() done");
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ Log.d(LOG_TAG, "setUp()");
+
+ sInstrumentation = InstrumentationRegistry.getInstrumentation();
+
+ assumeTrue(sInstrumentation.getContext().getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_PRINTING));
+
final PrintManager printManager = sInstrumentation.getContext()
.getSystemService(PrintManager.class);
final List<PrintServiceInfo> services = printManager.getPrintServices(
@@ -256,15 +265,6 @@
+ Settings.Secure.DISABLED_PRINT_SERVICES + " " + builder);
}
- Log.d(LOG_TAG, "setUpClass() done");
- }
-
- @Before
- public void setUp() throws Exception {
- Log.d(LOG_TAG, "setUp()");
-
- sInstrumentation = InstrumentationRegistry.getInstrumentation();
-
// Initialize the latches.
Log.d(LOG_TAG, "init counters");
mCancelOperationCounter = new CallCounter();
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
index d8a80d2..6d597a6 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
@@ -172,6 +172,12 @@
+ pkg + " " + android.Manifest.permission.ACCESS_COARSE_LOCATION);
getInstrumentation().getUiAutomation().executeShellCommand("pm grant "
+ pkg + " " + android.Manifest.permission.ACCESS_FINE_LOCATION);
+ getInstrumentation().getUiAutomation().executeShellCommand("pm grant "
+ + pkg + " " + android.Manifest.permission.RECORD_AUDIO);
+ getInstrumentation().getUiAutomation().executeShellCommand("pm grant "
+ + pkg + " " + android.Manifest.permission.READ_EXTERNAL_STORAGE);
+ getInstrumentation().getUiAutomation().executeShellCommand("pm grant "
+ + pkg + " " + android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
mActivity.startActivityForResult(intent, REQUEST_CODE);
@@ -197,6 +203,8 @@
SystemClock.sleep(5 * DateUtils.SECOND_IN_MILLIS);
maybeClick(new UiSelector().resourceId(pkg + ":id/shutter_button"));
mDevice.waitForIdle();
+ maybeClick(new UiSelector().resourceId(pkg + ":id/done_button"));
+ mDevice.waitForIdle();
result = mActivity.getResult(15, TimeUnit.SECONDS);
Log.d(TAG, "Second pass result was " + result);
@@ -218,6 +226,7 @@
+ "respond to the CAMERA and DPAD_CENTER keycodes", result);
assertTrue("exists", target.exists());
+ assertTrue("has data", target.length() > 65536);
// At the very least we expect photos generated by the device to have
// sane baseline EXIF data
@@ -230,7 +239,7 @@
private static void assertAttribute(ExifInterface exif, String tag) {
final String res = exif.getAttribute(tag);
if (res == null || res.length() == 0) {
- fail("Expected valid EXIF tag for tag " + tag);
+ Log.d(TAG, "Expected valid EXIF tag for tag " + tag);
}
}
diff --git a/tests/tests/view/src/android/view/cts/View_DefaultFocusHighlightTest.java b/tests/tests/view/src/android/view/cts/View_DefaultFocusHighlightTest.java
index b019fb1..7f062ad 100644
--- a/tests/tests/view/src/android/view/cts/View_DefaultFocusHighlightTest.java
+++ b/tests/tests/view/src/android/view/cts/View_DefaultFocusHighlightTest.java
@@ -52,6 +52,11 @@
@Test
public void testSettersAndGetters() {
Activity activity = mActivityRule.getActivity();
+ if (!activity.getResources().getBoolean(
+ com.android.internal.R.bool.config_useDefaultFocusHighlight)) {
+ // Skip the test when config_useDefaultFocusHighlight is false
+ return;
+ }
View view = activity.findViewById(R.id.view);
ListView listView = (ListView) activity.findViewById(R.id.listview);
@@ -82,6 +87,11 @@
@Test
public void testInflating() {
Activity activity = mActivityRule.getActivity();
+ if (!activity.getResources().getBoolean(
+ com.android.internal.R.bool.config_useDefaultFocusHighlight)) {
+ // Skip the test when config_useDefaultFocusHighlight is false
+ return;
+ }
View view = activity.findViewById(R.id.view_to_inflate);
ListView listView = (ListView) activity.findViewById(R.id.listview_to_inflate);
@@ -101,6 +111,12 @@
@Test
public void testIsDefaultFocusHighlightNeeded() {
Activity activity = mActivityRule.getActivity();
+ if (!activity.getResources().getBoolean(
+ com.android.internal.R.bool.config_useDefaultFocusHighlight)) {
+ // Skip the test when config_useDefaultFocusHighlight is false
+ return;
+ }
+
final Button button = (Button) activity.findViewById(R.id.button_to_test_highlight_needed);
final ImageView imageView =
(ImageView) activity.findViewById(R.id.image_view_to_test_highlight_needed);
diff --git a/tests/tests/widget/res/layout/linearlayout_layout.xml b/tests/tests/widget/res/layout/linearlayout_layout.xml
index e4f881f..9c59fbf 100644
--- a/tests/tests/widget/res/layout/linearlayout_layout.xml
+++ b/tests/tests/widget/res/layout/linearlayout_layout.xml
@@ -14,238 +14,243 @@
* 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:id="@+id/linearlayout_root"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/linearlayout_root"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
<LinearLayout
- android:id="@+id/linear_horizontal"
- android:layout_width="wrap_content"
- android:layout_height="100dip"
- android:orientation="horizontal"
- android:background="#888">
-
- <TextView
- android:id="@+id/gravity_top"
- android:layout_width="wrap_content"
- android:layout_height="50dip"
- android:layout_gravity="top"
- android:background="#0F0"
- android:text="@string/horizontal_text_1" />
-
- <TextView
- android:id="@+id/gravity_center_vertical"
- android:layout_width="wrap_content"
- android:layout_height="50dip"
- android:layout_gravity="center_vertical"
- android:background="#0F0"
- android:text="@string/horizontal_text_2" />
-
- <TextView
- android:id="@+id/gravity_bottom"
- android:layout_width="wrap_content"
- android:layout_height="50dip"
- android:layout_gravity="bottom"
- android:background="#0F0"
- android:text="@string/horizontal_text_3" />
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/linear_vertical"
- android:layout_width="100dip"
+ android:id="@+id/linearlayout_root"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical"
- android:background="#F00">
+ android:orientation="vertical">
- <TextView
- android:id="@+id/gravity_left"
+ <LinearLayout
+ android:id="@+id/linear_horizontal"
android:layout_width="wrap_content"
- android:layout_height="20dip"
- android:layout_gravity="left"
- android:background="#0F0"
- android:text="@string/vertical_text_1" />
+ android:layout_height="100dip"
+ android:orientation="horizontal"
+ android:background="#888">
- <TextView
- android:id="@+id/gravity_center_horizontal"
- android:layout_width="wrap_content"
- android:layout_height="20dip"
- android:layout_gravity="center_horizontal"
- android:background="#00F"
- android:text="@string/vertical_text_2" />
+ <TextView
+ android:id="@+id/gravity_top"
+ android:layout_width="wrap_content"
+ android:layout_height="50dip"
+ android:layout_gravity="top"
+ android:background="#0F0"
+ android:text="@string/horizontal_text_1" />
- <TextView
- android:id="@+id/gravity_right"
- android:layout_width="wrap_content"
- android:layout_height="20dip"
- android:layout_gravity="right"
- android:background="#0F0"
- android:text="@string/vertical_text_3" />
- </LinearLayout>
+ <TextView
+ android:id="@+id/gravity_center_vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="50dip"
+ android:layout_gravity="center_vertical"
+ android:background="#0F0"
+ android:text="@string/horizontal_text_2" />
- <LinearLayout
- android:id="@+id/linear_weightsum"
- android:layout_width="100dip"
- android:layout_height="100dip"
- android:orientation="horizontal"
- android:weightSum="1.0"
- android:baselineAligned="false"
- android:background="#888">
+ <TextView
+ android:id="@+id/gravity_bottom"
+ android:layout_width="wrap_content"
+ android:layout_height="50dip"
+ android:layout_gravity="bottom"
+ android:background="#0F0"
+ android:text="@string/horizontal_text_3" />
+ </LinearLayout>
- <TextView
- android:id="@+id/weight_0_2"
- android:layout_width="0dip"
+ <LinearLayout
+ android:id="@+id/linear_vertical"
+ android:layout_width="100dip"
android:layout_height="wrap_content"
- android:layout_weight="0.2"
- android:background="#00F"
- android:text="@string/horizontal_text_1" />
+ android:orientation="vertical"
+ android:background="#F00">
- <TextView
- android:id="@+id/weight_0_5"
- android:layout_width="0dip"
+ <TextView
+ android:id="@+id/gravity_left"
+ android:layout_width="wrap_content"
+ android:layout_height="20dip"
+ android:layout_gravity="left"
+ android:background="#0F0"
+ android:text="@string/vertical_text_1" />
+
+ <TextView
+ android:id="@+id/gravity_center_horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="20dip"
+ android:layout_gravity="center_horizontal"
+ android:background="#00F"
+ android:text="@string/vertical_text_2" />
+
+ <TextView
+ android:id="@+id/gravity_right"
+ android:layout_width="wrap_content"
+ android:layout_height="20dip"
+ android:layout_gravity="right"
+ android:background="#0F0"
+ android:text="@string/vertical_text_3" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/linear_weightsum"
+ android:layout_width="100dip"
+ android:layout_height="100dip"
+ android:orientation="horizontal"
+ android:weightSum="1.0"
+ android:baselineAligned="false"
+ android:background="#888">
+
+ <TextView
+ android:id="@+id/weight_0_2"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.2"
+ android:background="#00F"
+ android:text="@string/horizontal_text_1" />
+
+ <TextView
+ android:id="@+id/weight_0_5"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.5"
+ android:background="#F00"
+ android:text="@string/horizontal_text_2" />
+
+ <TextView
+ android:id="@+id/weight_0_3"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.3"
+ android:background="#00F"
+ android:text="@string/horizontal_text_3" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/linear_weightsum_vertical"
+ android:layout_width="100dip"
+ android:layout_height="100dip"
+ android:orientation="vertical"
+ android:weightSum="1.0"
+ android:baselineAligned="false"
+ android:background="#888">
+
+ <TextView
+ android:id="@+id/weight_0_1"
+ android:layout_width="wrap_content"
+ android:layout_height="0dip"
+ android:layout_weight="0.1"
+ android:background="#00F"
+ android:text="@string/vertical_text_1" />
+
+ <TextView
+ android:id="@+id/weight_0_4"
+ android:layout_width="wrap_content"
+ android:layout_height="0dip"
+ android:layout_weight="0.4"
+ android:background="#F00"
+ android:text="@string/vertical_text_2" />
+
+ <TextView
+ android:id="@+id/weight_0_5"
+ android:layout_width="wrap_content"
+ android:layout_height="0dip"
+ android:layout_weight="0.5"
+ android:background="#00F"
+ android:text="@string/vertical_text_3" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/linear_baseline_aligned_child_index"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_weight="0.5"
- android:background="#F00"
- android:text="@string/horizontal_text_2" />
+ android:orientation="vertical"
+ android:baselineAlignedChildIndex="1"
+ android:background="#F00">
- <TextView
- android:id="@+id/weight_0_3"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_weight="0.3"
- android:background="#00F"
- android:text="@string/horizontal_text_3" />
+ <TextView
+ android:id="@+id/textview1"
+ android:layout_width="wrap_content"
+ android:layout_height="20dip"
+ android:layout_gravity="left"
+ android:background="#0F0"
+ android:text="@string/vertical_text_1" />
+
+ <TextView
+ android:id="@+id/textview2"
+ android:layout_width="wrap_content"
+ android:layout_height="20dip"
+ android:layout_gravity="center_horizontal"
+ android:background="#00F"
+ android:text="@string/vertical_text_2" />
+
+ <TextView
+ android:id="@+id/textview3"
+ android:layout_width="wrap_content"
+ android:layout_height="20dip"
+ android:layout_gravity="right"
+ android:background="#0F0"
+ android:text="@string/vertical_text_3" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/linear_vertical_with_divider"
+ android:layout_width="100px"
+ android:layout_height="100px"
+ android:orientation="vertical"
+ android:background="#FF0"
+ android:showDividers="middle"
+ android:divider="@drawable/linear_layout_divider_red"
+ android:dividerPadding="@dimen/linear_layout_divider_padding">
+
+ <View
+ android:id="@+id/child1"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="0.5"
+ android:background="#00F" />
+
+ <View
+ android:id="@+id/child2"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="0.5"
+ android:background="#0F0" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/linear_horizontal_with_divider"
+ android:layout_width="100px"
+ android:layout_height="100px"
+ android:orientation="horizontal"
+ android:background="#FF0"
+ android:showDividers="middle"
+ android:divider="@drawable/linear_layout_divider_red"
+ android:dividerPadding="@dimen/linear_layout_divider_padding">
+
+ <View
+ android:id="@+id/child1"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="0.5"
+ android:background="#00F" />
+
+ <View
+ android:id="@+id/child2"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="0.5"
+ android:background="#0F0" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/linear_empty"
+ android:layout_width="100px"
+ android:layout_height="100px" />
+
+ <view
+ class="android.widget.cts.LinearLayoutTest$MockLinearLayout"
+ android:id="@+id/linear_custom"
+ android:layout_width="100px"
+ android:layout_height="100px" />
</LinearLayout>
-
- <LinearLayout
- android:id="@+id/linear_weightsum_vertical"
- android:layout_width="100dip"
- android:layout_height="100dip"
- android:orientation="vertical"
- android:weightSum="1.0"
- android:baselineAligned="false"
- android:background="#888">
-
- <TextView
- android:id="@+id/weight_0_1"
- android:layout_width="wrap_content"
- android:layout_height="0dip"
- android:layout_weight="0.1"
- android:background="#00F"
- android:text="@string/vertical_text_1" />
-
- <TextView
- android:id="@+id/weight_0_4"
- android:layout_width="wrap_content"
- android:layout_height="0dip"
- android:layout_weight="0.4"
- android:background="#F00"
- android:text="@string/vertical_text_2" />
-
- <TextView
- android:id="@+id/weight_0_5"
- android:layout_width="wrap_content"
- android:layout_height="0dip"
- android:layout_weight="0.5"
- android:background="#00F"
- android:text="@string/vertical_text_3" />
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/linear_baseline_aligned_child_index"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:baselineAlignedChildIndex="1"
- android:background="#F00">
-
- <TextView
- android:id="@+id/textview1"
- android:layout_width="wrap_content"
- android:layout_height="20dip"
- android:layout_gravity="left"
- android:background="#0F0"
- android:text="@string/vertical_text_1" />
-
- <TextView
- android:id="@+id/textview2"
- android:layout_width="wrap_content"
- android:layout_height="20dip"
- android:layout_gravity="center_horizontal"
- android:background="#00F"
- android:text="@string/vertical_text_2" />
-
- <TextView
- android:id="@+id/textview3"
- android:layout_width="wrap_content"
- android:layout_height="20dip"
- android:layout_gravity="right"
- android:background="#0F0"
- android:text="@string/vertical_text_3" />
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/linear_vertical_with_divider"
- android:layout_width="100px"
- android:layout_height="100px"
- android:orientation="vertical"
- android:background="#FF0"
- android:showDividers="middle"
- android:divider="@drawable/linear_layout_divider_red"
- android:dividerPadding="@dimen/linear_layout_divider_padding">
-
- <View
- android:id="@+id/child1"
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="0.5"
- android:background="#00F" />
-
- <View
- android:id="@+id/child2"
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="0.5"
- android:background="#0F0" />
-
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/linear_horizontal_with_divider"
- android:layout_width="100px"
- android:layout_height="100px"
- android:orientation="horizontal"
- android:background="#FF0"
- android:showDividers="middle"
- android:divider="@drawable/linear_layout_divider_red"
- android:dividerPadding="@dimen/linear_layout_divider_padding">
-
- <View
- android:id="@+id/child1"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:layout_weight="0.5"
- android:background="#00F" />
-
- <View
- android:id="@+id/child2"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:layout_weight="0.5"
- android:background="#0F0" />
-
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/linear_empty"
- android:layout_width="100px"
- android:layout_height="100px" />
-
- <view
- class="android.widget.cts.LinearLayoutTest$MockLinearLayout"
- android:id="@+id/linear_custom"
- android:layout_width="100px"
- android:layout_height="100px" />
-</LinearLayout>
+</ScrollView>
diff --git a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
index f2d70ec..c4a4070 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
@@ -41,6 +41,7 @@
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
@@ -142,6 +143,11 @@
mListView = (ListView) activity.findViewById(R.id.listview_default);
}
+ private boolean isWatch() {
+ return (mContext.getResources().getConfiguration().uiMode
+ & Configuration.UI_MODE_TYPE_WATCH) == Configuration.UI_MODE_TYPE_WATCH;
+ }
+
@Test
@UiThreadTest
public void testAccessFastScrollEnabled_UiThread() {
@@ -959,32 +965,43 @@
mActivityRule.runOnUiThread(() -> mListView.setItemChecked(2, true));
verifyCheckedState(new long[] { 2 });
- verify(mMultiChoiceModeListener, times(1)).onItemCheckedStateChanged(
- any(ActionMode.class), eq(2), eq(2L), eq(true));
+ if (!isWatch()) {
+ verify(mMultiChoiceModeListener, times(1)).onItemCheckedStateChanged(
+ any(ActionMode.class), eq(2), eq(2L), eq(true));
+ }
reset(mMultiChoiceModeListener);
mActivityRule.runOnUiThread(() -> mListView.setItemChecked(4, true));
verifyCheckedState(new long[] { 2, 4 });
- verify(mMultiChoiceModeListener, times(1)).onItemCheckedStateChanged(
- any(ActionMode.class), eq(4), eq(4L), eq(true));
+ if (!isWatch()) {
+ verify(mMultiChoiceModeListener, times(1)).onItemCheckedStateChanged(
+ any(ActionMode.class), eq(4), eq(4L), eq(true));
+ }
reset(mMultiChoiceModeListener);
mActivityRule.runOnUiThread(() -> mListView.setItemChecked(2, false));
verifyCheckedState(new long[] { 4 });
- verify(mMultiChoiceModeListener, times(1)).onItemCheckedStateChanged(
- any(ActionMode.class), eq(2), eq(2L), eq(false));
+ if (!isWatch()) {
+ verify(mMultiChoiceModeListener, times(1)).onItemCheckedStateChanged(
+ any(ActionMode.class), eq(2), eq(2L), eq(false));
+ }
reset(mMultiChoiceModeListener);
mActivityRule.runOnUiThread(() -> mListView.setItemChecked(4, false));
verifyCheckedState(new long[] {});
mListView.setMultiChoiceModeListener(mMultiChoiceModeListener);
- verify(mMultiChoiceModeListener, times(1)).onItemCheckedStateChanged(
- any(ActionMode.class), eq(4), eq(4L), eq(false));
+ if (!isWatch()) {
+ verify(mMultiChoiceModeListener, times(1)).onItemCheckedStateChanged(
+ any(ActionMode.class), eq(4), eq(4L), eq(false));
+ }
}
@LargeTest
@Test
public void testMultiSelectionWithLongPressAndTaps() throws Throwable {
+ if (isWatch()) {
+ return; // watch type devices do not support multichoice action mode
+ }
configureMultiChoiceModalState();
final int firstVisiblePosition = mListView.getFirstVisiblePosition();
diff --git a/tests/tests/widget/src/android/widget/cts/CalendarViewTest.java b/tests/tests/widget/src/android/widget/cts/CalendarViewTest.java
index 57181f7..e66b1d9 100644
--- a/tests/tests/widget/src/android/widget/cts/CalendarViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/CalendarViewTest.java
@@ -220,8 +220,8 @@
() -> calendarView.setDate(calendar.getTime().getTime(), false, true));
mInstrumentation.waitForIdleSync();
- // Get bounds of 09/23/2008
- calendar.set(Calendar.DAY_OF_MONTH, 23);
+ // Get bounds of 09/07/2008
+ calendar.set(Calendar.DAY_OF_MONTH, 7);
final Rect dayBounds = new Rect();
final boolean getDayBoundsSuccess = calendarView.getBoundsForDate(
calendar.getTime().getTime(), dayBounds);
@@ -231,13 +231,13 @@
verifyZeroInteractions(mockDateChangeListener);
}
- // Use instrumentation to emulate a tap on 09/23/2008
+ // Use instrumentation to emulate a tap on 09/07/2008
CtsTouchUtils.emulateTapOnView(mInstrumentation, calendarView,
dayBounds.left + dayBounds.width() / 2,
dayBounds.top + dayBounds.height() / 2);
verify(mockDateChangeListener, times(1)).onSelectedDayChange(calendarView,
- 2008, Calendar.SEPTEMBER, 23);
+ 2008, Calendar.SEPTEMBER, 7);
if (onlyAllowOneChangeEvent) {
verifyNoMoreInteractions(mockDateChangeListener);
}
diff --git a/tests/tests/widget/src/android/widget/cts/NumberPickerTest.java b/tests/tests/widget/src/android/widget/cts/NumberPickerTest.java
index 4d25740..3fb141e 100644
--- a/tests/tests/widget/src/android/widget/cts/NumberPickerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/NumberPickerTest.java
@@ -28,6 +28,7 @@
import static org.mockito.Mockito.verifyZeroInteractions;
import android.app.Instrumentation;
+import android.content.res.Configuration;
import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
@@ -292,6 +293,11 @@
verifyZeroInteractions(mockValueChangeListener);
}
+ private boolean isWatch() {
+ return (mActivity.getResources().getConfiguration().uiMode
+ & Configuration.UI_MODE_TYPE_WATCH) == Configuration.UI_MODE_TYPE_WATCH;
+ }
+
@Test
public void testInteractionWithSwipeDown() throws Throwable {
mActivityRule.runOnUiThread(() -> {
@@ -332,8 +338,10 @@
InOrder inOrder = inOrder(mockScrollListener);
inOrder.verify(mockScrollListener).onScrollStateChange(mNumberPicker,
NumberPicker.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
- inOrder.verify(mockScrollListener).onScrollStateChange(mNumberPicker,
- NumberPicker.OnScrollListener.SCROLL_STATE_FLING);
+ if (!isWatch()) {
+ inOrder.verify(mockScrollListener).onScrollStateChange(mNumberPicker,
+ NumberPicker.OnScrollListener.SCROLL_STATE_FLING);
+ }
inOrder.verify(mockScrollListener).onScrollStateChange(mNumberPicker,
NumberPicker.OnScrollListener.SCROLL_STATE_IDLE);
verifyNoMoreInteractions(mockScrollListener);
@@ -379,8 +387,10 @@
InOrder inOrder = inOrder(mockScrollListener);
inOrder.verify(mockScrollListener).onScrollStateChange(mNumberPicker,
NumberPicker.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
- inOrder.verify(mockScrollListener).onScrollStateChange(mNumberPicker,
- NumberPicker.OnScrollListener.SCROLL_STATE_FLING);
+ if (!isWatch()) {
+ inOrder.verify(mockScrollListener).onScrollStateChange(mNumberPicker,
+ NumberPicker.OnScrollListener.SCROLL_STATE_FLING);
+ }
inOrder.verify(mockScrollListener).onScrollStateChange(mNumberPicker,
NumberPicker.OnScrollListener.SCROLL_STATE_IDLE);
verifyNoMoreInteractions(mockScrollListener);
diff --git a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
index 4d60aaf..5ce73a8 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
@@ -281,7 +281,12 @@
for (int i = 0; i != menu.size(); i++) {
MenuItem item = menu.getItem(i);
- View itemView = menuItemList.getChildAt(i);
+ View itemView = null;
+ // On smaller screens, not all menu items will be visible.
+ if (i < menuItemList.getChildCount()) {
+ itemView = menuItemList.getChildAt(i);
+ assertNotNull(itemView);
+ }
if (i < 2) {
assertNotNull(item.getContentDescription());
@@ -290,9 +295,11 @@
assertNull(item.getContentDescription());
assertNull(item.getTooltipText());
}
- // Tooltips are not set on list-based menus.
- assertNull(itemView.getTooltipText());
- assertEquals(item.getContentDescription(), itemView.getContentDescription());
+ if (itemView != null) {
+ // Tooltips are not set on list-based menus.
+ assertNull(itemView.getTooltipText());
+ assertEquals(item.getContentDescription(), itemView.getContentDescription());
+ }
}
}
diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsWidgetTest.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsWidgetTest.java
index 9c47e69..0e2f5cf 100644
--- a/tests/tests/widget/src/android/widget/cts/RemoteViewsWidgetTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RemoteViewsWidgetTest.java
@@ -208,6 +208,9 @@
@After
public void teardown() {
+ if (!mHasAppWidgets) {
+ return;
+ }
mAppWidgetHost.deleteHost();
revokeBindAppWidgetPermission();
}
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 0c0fe03..4e71fdd 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -53,6 +53,7 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.graphics.Color;
@@ -7476,8 +7477,16 @@
// TODO: Test the floating toolbar content.
}
+ private boolean isWatch() {
+ return (mActivity.getResources().getConfiguration().uiMode
+ & Configuration.UI_MODE_TYPE_WATCH) == Configuration.UI_MODE_TYPE_WATCH;
+ }
+
@Test
public void testSmartSelection_dragSelection() throws Throwable {
+ if (isWatch()) {
+ return;
+ }
mTextView = findTextView(R.id.textview_text);
String text = "The president-elect, Filip, is coming to town tomorrow.";
int startIndex = text.indexOf("is coming to town");
diff --git a/tests/tests/widget/src/android/widget/cts/TimePickerTest.java b/tests/tests/widget/src/android/widget/cts/TimePickerTest.java
index 28f16be..c65da05 100644
--- a/tests/tests/widget/src/android/widget/cts/TimePickerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TimePickerTest.java
@@ -29,6 +29,7 @@
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
+import android.content.res.Configuration;
import android.os.Parcelable;
import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
@@ -300,8 +301,16 @@
assertEquals(Integer.valueOf(expectMinute), dest.getCurrentMinute());
}
+ private boolean isWatch() {
+ return (mActivity.getResources().getConfiguration().uiMode
+ & Configuration.UI_MODE_TYPE_WATCH) == Configuration.UI_MODE_TYPE_WATCH;
+ }
+
@Test
public void testKeyboardTabTraversalModeClock() throws Throwable {
+ if (isWatch()) {
+ return;
+ }
mTimePicker = (TimePicker) mActivity.findViewById(R.id.timepicker_clock);
mActivityRule.runOnUiThread(() -> mTimePicker.setIs24HourView(false));
@@ -325,6 +334,9 @@
@Test
public void testKeyboardTabTraversalModeSpinner() throws Throwable {
+ if (isWatch()) {
+ return;
+ }
mTimePicker = (TimePicker) mActivity.findViewById(R.id.timepicker_spinner);
mActivityRule.runOnUiThread(() -> mTimePicker.setIs24HourView(false));
@@ -348,6 +360,9 @@
@Test
public void testKeyboardInputModeClockAmPm() throws Throwable {
+ if (isWatch()) {
+ return;
+ }
final int initialHour = 6;
final int initialMinute = 59;
prepareForKeyboardInput(initialHour, initialMinute, false /* is24hFormat */,
@@ -423,6 +438,9 @@
@Test
public void testKeyboardInputModeClock24H() throws Throwable {
+ if (isWatch()) {
+ return;
+ }
final int initialHour = 6;
final int initialMinute = 59;
prepareForKeyboardInput(initialHour, initialMinute, true /* is24hFormat */,
@@ -472,6 +490,9 @@
@Test
public void testKeyboardInputModeSpinnerAmPm() throws Throwable {
+ if (isWatch()) {
+ return;
+ }
final int initialHour = 6;
final int initialMinute = 59;
prepareForKeyboardInput(initialHour, initialMinute, false /* is24hFormat */,
@@ -581,6 +602,9 @@
@Test
public void testKeyboardInputModeSpinner24H() throws Throwable {
+ if (isWatch()) {
+ return;
+ }
final int initialHour = 6;
final int initialMinute = 59;
prepareForKeyboardInput(initialHour, initialMinute, true /* is24hFormat */,
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
index 953c9e5..4fbaa8c 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -94,6 +94,9 @@
<option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.ConnectivityConstraintTest#testUnmeteredConstraintFails_withMobile" />
<option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.TimingConstraintsTest#testJobParameters_unexpiredDeadline" />
+ <!-- b/62616944 -->
+ <option name="compatibility:exclude-filter" value="CtsLibcoreJavaUtilCollectionsTestCases" />
+
<!-- b/17144778 -->
<option name="compatibility:exclude-filter" value="CtsMediaTestCases android.media.cts.ImageReaderDecoderTest#testHwAVCDecode360pForFlexibleYuv" />
<!-- b/23827982 -->
@@ -208,4 +211,11 @@
<!-- b/62481870 -->
<option name="compatibility:exclude-filter" value="CtsNativeMediaAAudioTestCases android.nativemedia.aaudio.AAudioOutputStreamCallbackTest#testPlayback" />
+
+ <!-- b/62844160 -->
+ <option name="compatibility:exclude-filter" value="CtsWidgetTestCases android.widget.cts.TextViewTest#testAutoSizeCallers_setText" />
+ <option name="compatibility:exclude-filter" value="CtsWidgetTestCases android.widget.cts.TextViewTest#testGetOffsetForPositionSingleLineLtr" />
+ <option name="compatibility:exclude-filter" value="CtsWidgetTestCases android.widget.cts.TextViewTest#testGetOffsetForPositionMultiLineLtr" />
+ <option name="compatibility:exclude-filter" value="CtsWidgetTestCases android.widget.cts.TextViewTest#testGetOffsetForPositionMultiLineRtl" />
+
</configuration>
diff --git a/tools/cts-tradefed/res/config/cts.xml b/tools/cts-tradefed/res/config/cts.xml
index 0e31afb..818004d 100644
--- a/tools/cts-tradefed/res/config/cts.xml
+++ b/tools/cts-tradefed/res/config/cts.xml
@@ -29,6 +29,11 @@
<!-- retain 200MB of logcat -->
<option name="max-tmp-logcat-file" value="209715200" />
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="settings put global package_verifier_enable 0" />
+ <option name="teardown-command" value="settings put global package_verifier_enable 1"/>
+ </target_preparer>
+
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.PropertyCheck">
<option name="property-name" value="ro.build.type" />
<option name="expected-value" value="user"/> <!-- Device should have user build -->