Merge "Remove InCallService requirement for dialer role."
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 9042e16..e2c1901 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -23,3 +23,5 @@
tests/tests/view/
tests/tests/widget/
common/device-side/util/
+
+ktlint_hook = ${REPO_ROOT}/prebuilts/ktlint/ktlint.py -f ${PREUPLOAD_FILES}
diff --git a/apps/CtsVerifier/res/layout/biometric_test_main.xml b/apps/CtsVerifier/res/layout/biometric_test_main.xml
index 75a42f9..476e355 100644
--- a/apps/CtsVerifier/res/layout/biometric_test_main.xml
+++ b/apps/CtsVerifier/res/layout/biometric_test_main.xml
@@ -20,28 +20,51 @@
android:padding="10dip"
>
- <Button android:id="@+id/biometric_start_test1_button"
+ <Button android:id="@+id/biometric_enroll_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_above="@+id/biometric_start_test_not_secured"
+ android:layout_centerHorizontal="true"
+ android:text="@string/biometric_enroll"
+ android:visibility="invisible"
+ />
+
+ <Button android:id="@+id/biometric_start_test_not_secured"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/biometric_start_test1"
/>
- <Button android:id="@+id/biometric_enroll_button"
+ <Button android:id="@+id/biometric_start_test_none_enrolled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_above="@+id/biometric_start_test2_button"
android:layout_centerHorizontal="true"
- android:text="@string/biometric_enroll"
+ android:layout_below="@+id/biometric_start_test_not_secured"
+ android:text="@string/biometric_start_test2"
+ android:visibility="invisible"
/>
- <Button android:id="@+id/biometric_start_test2_button"
+ <Button android:id="@+id/biometric_start_test_credential_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:text="@string/biometric_start_test2"
+ android:layout_below="@+id/biometric_start_test_none_enrolled"
+ android:layout_centerHorizontal="true"
+ android:text="@string/biometric_start_test3"
+ android:visibility="invisible"
/>
+ <Button android:id="@+id/biometric_start_test_authenticate_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/biometric_start_test_fallback_button"
+ android:layout_centerHorizontal="true"
+ android:text="@string/biometric_start_test4"
+ android:visibility="invisible"
+ />
+
+
+
<include android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 9143263..a6bb079 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -157,6 +157,8 @@
<string name="biometric_enroll">Enroll</string>
<string name="biometric_start_test1">Start Test 1</string>
<string name="biometric_start_test2">Start Test 2</string>
+ <string name="biometric_start_test3">Start Test 3</string>
+ <string name="biometric_start_test4">Start Test 4</string>
<!-- Strings for lock bound keys test -->
<string name="sec_lock_bound_key_test">Lock Bound Keys Test</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricTest.java
index 31b43b4..ac9c465 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricTest.java
@@ -17,6 +17,7 @@
package com.android.cts.verifier.biometrics;
import android.Manifest;
+import android.app.KeyguardManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -49,17 +50,29 @@
private static final String BIOMETRIC_ENROLL = "android.settings.BIOMETRIC_ENROLL";
private static final int BIOMETRIC_PERMISSION_REQUEST_CODE = 0;
- private static final int TEST_NONE_ENROLLED = 1;
- private static final int TEST_ENROLLED = 2;
+ // Test that BiometricPrompt setAllowDeviceCredentials returns ERROR_NO_DEVICE_CREDENTIAL when
+ // pin, pattern, password is not set.
+ private static final int TEST_NOT_SECURED = 1;
+ // Test that BiometricPrompt returns BIOMETRIC_ERROR_NO_BIOMETRICS when BiometricManager
+ // states BIOMETRIC_ERROR_NONE_ENROLLED.
+ private static final int TEST_NONE_ENROLLED = 2;
+ // Test that BiometricPrompt setAllowDeviceCredentials can authenticate when no biometrics are
+ // enrolled.
+ private static final int TEST_DEVICE_CREDENTIAL = 3;
+ // Test that authentication can succeed when biometrics are enrolled.
+ private static final int TEST_AUTHENTICATE = 4;
private BiometricManager mBiometricManager;
+ private KeyguardManager mKeyguardManager;
private Handler mHandler = new Handler(Looper.getMainLooper());
private CancellationSignal mCancellationSignal;
- private int mExpectedError;
private int mCurrentTest;
+
private Button mButtonEnroll;
- private Button mButtonTest1;
- private Button mButtonTest2;
+ private Button mButtonTestNotSecured;
+ private Button mButtonTestNoneEnrolled;
+ private Button mButtonTestCredential;
+ private Button mButtonTestAuthenticate;
private Executor mExecutor = (runnable) -> {
mHandler.post(runnable);
@@ -69,27 +82,45 @@
new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
- if (mCurrentTest == TEST_NONE_ENROLLED) {
- showToastAndLog("This should be impossible, please capture a bug report");
- } else if (mCurrentTest == TEST_ENROLLED) {
- showToastAndLog("Authenticated. You passed the test.");
+ if (mCurrentTest == TEST_NOT_SECURED) {
+ showToastAndLog("This should be impossible, please capture a bug report "
+ + mCurrentTest);
+ } else if (mCurrentTest == TEST_NONE_ENROLLED) {
+ showToastAndLog("This should be impossible, please capture a bug report"
+ + mCurrentTest);
+ } else if (mCurrentTest == TEST_DEVICE_CREDENTIAL) {
+ showToastAndLog("Please enroll a biometric and start the next test");
+ mButtonTestCredential.setEnabled(false);
+ mButtonEnroll.setVisibility(View.VISIBLE);
+ mButtonTestAuthenticate.setVisibility(View.VISIBLE);
+ } else if (mCurrentTest == TEST_AUTHENTICATE) {
+ showToastAndLog("You have passed the test!");
+ mButtonTestAuthenticate.setEnabled(false);
getPassButton().setEnabled(true);
}
}
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
- if (mCurrentTest == TEST_NONE_ENROLLED) {
- if (errorCode == mExpectedError) {
- mButtonTest1.setVisibility(View.INVISIBLE);
- mButtonTest2.setVisibility(View.VISIBLE);
- mButtonEnroll.setVisibility(View.VISIBLE);
- showToastAndLog("Please enroll a biometric and start the next test");
+ if (mCurrentTest == TEST_NOT_SECURED) {
+ if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL) {
+ showToastAndLog("Please start the next test");
+ mButtonTestNotSecured.setEnabled(false);
+ mButtonTestNoneEnrolled.setVisibility(View.VISIBLE);
} else {
- showToastAndLog("Expected: " + mExpectedError +
- " Actual: " + errorCode + " " + errString);
+ showToastAndLog("Error: " + errorCode + " " + errString);
}
- } else if (mCurrentTest == TEST_ENROLLED) {
+ } else if (mCurrentTest == TEST_NONE_ENROLLED) {
+ if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_NO_BIOMETRICS) {
+ mButtonTestNoneEnrolled.setEnabled(false);
+ mButtonTestCredential.setVisibility(View.VISIBLE);
+ showToastAndLog("Please start the next test");
+ } else {
+ showToastAndLog("Error: " + errorCode + " " + errString);
+ }
+ } else if (mCurrentTest == TEST_DEVICE_CREDENTIAL) {
+ showToastAndLog(errString.toString() + " Please try again");
+ } else if (mCurrentTest == TEST_AUTHENTICATE) {
showToastAndLog(errString.toString() + " Please try again");
}
}
@@ -108,11 +139,12 @@
getPassButton().setEnabled(false);
mBiometricManager = getApplicationContext().getSystemService(BiometricManager.class);
+ mKeyguardManager = getApplicationContext().getSystemService(KeyguardManager.class);
mButtonEnroll = findViewById(R.id.biometric_enroll_button);
- mButtonEnroll.setVisibility(View.INVISIBLE);
- mButtonTest1 = findViewById(R.id.biometric_start_test1_button);
- mButtonTest2 = findViewById(R.id.biometric_start_test2_button);
- mButtonTest2.setVisibility(View.INVISIBLE);
+ mButtonTestNoneEnrolled = findViewById(R.id.biometric_start_test_none_enrolled);
+ mButtonTestNotSecured = findViewById(R.id.biometric_start_test_not_secured);
+ mButtonTestAuthenticate = findViewById(R.id.biometric_start_test_authenticate_button);
+ mButtonTestCredential = findViewById(R.id.biometric_start_test_credential_button);
PackageManager pm = getApplicationContext().getPackageManager();
if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)
@@ -120,21 +152,28 @@
|| pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
requestPermissions(new String[]{Manifest.permission.USE_BIOMETRIC},
BIOMETRIC_PERMISSION_REQUEST_CODE);
- mButtonTest1.setEnabled(false);
- mButtonTest1.setOnClickListener((view) -> {
+
+ mButtonTestNotSecured.setEnabled(false);
+ mButtonTestNotSecured.setOnClickListener((view) -> {
+ startTest(TEST_NOT_SECURED);
+ });
+ mButtonTestNoneEnrolled.setOnClickListener((view) -> {
startTest(TEST_NONE_ENROLLED);
});
- mButtonTest2.setOnClickListener((view) -> {
- startTest(TEST_ENROLLED);
+ mButtonTestAuthenticate.setOnClickListener((view) -> {
+ startTest(TEST_AUTHENTICATE);
});
mButtonEnroll.setOnClickListener((view) -> {
final Intent intent = new Intent();
intent.setAction(BIOMETRIC_ENROLL);
startActivity(intent);
});
+ mButtonTestCredential.setOnClickListener((view) -> {
+ startTest(TEST_DEVICE_CREDENTIAL);
+ });
} else {
// NO biometrics available
- mButtonTest1.setEnabled(false);
+ mButtonTestNoneEnrolled.setEnabled(false);
getPassButton().setEnabled(true);
}
}
@@ -143,7 +182,7 @@
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] state) {
if (requestCode == BIOMETRIC_PERMISSION_REQUEST_CODE &&
state[0] == PackageManager.PERMISSION_GRANTED) {
- mButtonTest1.setEnabled(true);
+ mButtonTestNotSecured.setEnabled(true);
}
}
@@ -151,17 +190,29 @@
mCurrentTest = testType;
int result = mBiometricManager.canAuthenticate();
- if (testType == TEST_NONE_ENROLLED) {
+ if (testType == TEST_NOT_SECURED) {
+ if (mKeyguardManager.isDeviceSecure()) {
+ showToastAndLog("Please remove your pin/pattern/password and try again");
+ } else {
+ showBiometricPrompt(true /* allowCredential */);
+ }
+ } else if (testType == TEST_NONE_ENROLLED) {
if (result == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
- mExpectedError = BiometricPrompt.BIOMETRIC_ERROR_NO_BIOMETRICS;
- showBiometricPrompt();
+ showBiometricPrompt(false /* allowCredential */);
} else {
showToastAndLog("Error: " + result + " Please remove all biometrics and try again");
}
- } else if (testType == TEST_ENROLLED) {
+ } else if (testType == TEST_DEVICE_CREDENTIAL) {
+ if (!mKeyguardManager.isDeviceSecure()) {
+ showToastAndLog("Please set up a pin, pattern, or password and try again");
+ } else if (result != BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
+ showToastAndLog("Error: " + result + " Please remove all biometrics and try again");
+ } else {
+ showBiometricPrompt(true /* allowCredential */);
+ }
+ } else if (testType == TEST_AUTHENTICATE) {
if (result == BiometricManager.BIOMETRIC_SUCCESS) {
- mExpectedError = 0;
- showBiometricPrompt();
+ showBiometricPrompt(false /* allowCredential */);
} else {
showToastAndLog("Error: " + result +
" Please ensure at least one biometric is enrolled and try again");
@@ -171,10 +222,14 @@
}
}
- private void showBiometricPrompt() {
+ private void showBiometricPrompt(boolean allowCredential) {
BiometricPrompt.Builder builder = new BiometricPrompt.Builder(getApplicationContext())
- .setTitle("Please authenticate")
- .setNegativeButton("Cancel", mExecutor, mBiometricPromptButtonListener);
+ .setTitle("Please authenticate");
+ if (allowCredential) {
+ builder.setAllowDeviceCredential(true);
+ } else {
+ builder.setNegativeButton("Cancel", mExecutor, mBiometricPromptButtonListener);
+ }
BiometricPrompt bp = builder.build();
mCancellationSignal = new CancellationSignal();
bp.authenticate(mCancellationSignal, mExecutor, mAuthenticationCallback);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyChainTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyChainTestActivity.java
index fa88e32..d774823 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyChainTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyChainTestActivity.java
@@ -208,6 +208,11 @@
logStatus("Got right alias.");
try {
PrivateKey privateKey = KeyChain.getPrivateKey(KeyChainTestActivity.this, alias);
+ if (privateKey == null) {
+ logStatus("FAILED (key unavailable)");
+ return;
+ }
+
byte[] data = new String("hello").getBytes();
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initSign(privateKey);
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivitiesWatcher.java b/common/device-side/util/src/android/contentcaptureservice/cts/common/ActivitiesWatcher.java
similarity index 100%
rename from tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivitiesWatcher.java
rename to common/device-side/util/src/android/contentcaptureservice/cts/common/ActivitiesWatcher.java
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivityLauncher.java b/common/device-side/util/src/android/contentcaptureservice/cts/common/ActivityLauncher.java
similarity index 91%
rename from tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivityLauncher.java
rename to common/device-side/util/src/android/contentcaptureservice/cts/common/ActivityLauncher.java
index d844894..3e6a02c 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivityLauncher.java
+++ b/common/device-side/util/src/android/contentcaptureservice/cts/common/ActivityLauncher.java
@@ -25,6 +25,8 @@
/**
* Helper used to launch an activity and watch for its lifecycle events.
+ *
+ * @param <A> activity type
*/
public final class ActivityLauncher<A extends Activity> {
@@ -39,11 +41,17 @@
mLaunchIntent = new Intent(context, activityClass);
}
+ /**
+ * Gets a watcher for the activity lifecycle events.
+ */
@NonNull
public ActivityWatcher getWatcher() {
return mWatcher;
}
+ /**
+ * Launches the activity.
+ */
@NonNull
public A launchActivity() {
return mActivityTestRule.launchActivity(mLaunchIntent);
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/DoubleVisitor.java b/common/device-side/util/src/android/contentcaptureservice/cts/common/DoubleVisitor.java
similarity index 100%
rename from tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/DoubleVisitor.java
rename to common/device-side/util/src/android/contentcaptureservice/cts/common/DoubleVisitor.java
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/Visitor.java b/common/device-side/util/src/android/contentcaptureservice/cts/common/Visitor.java
similarity index 100%
rename from tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/Visitor.java
rename to common/device-side/util/src/android/contentcaptureservice/cts/common/Visitor.java
diff --git a/hostsidetests/appsecurity/test-apps/MediaStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/MediaStorageApp/Android.mk
index efb4bce..73946e0 100644
--- a/hostsidetests/appsecurity/test-apps/MediaStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp/Android.mk
@@ -19,6 +19,7 @@
LOCAL_MODULE_TAGS := tests
LOCAL_SDK_VERSION := test_current
LOCAL_STATIC_JAVA_LIBRARIES := \
+ compatibility-device-util \
android-support-test \
ub-uiautomator
diff --git a/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
index fa1ca7b..7d84684 100644
--- a/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/MediaStorageApp/src/com/android/cts/mediastorageapp/MediaStorageTest.java
@@ -16,6 +16,8 @@
package com.android.cts.mediastorageapp;
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -45,7 +47,6 @@
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashSet;
@@ -53,11 +54,13 @@
public class MediaStorageTest {
private Context mContext;
private ContentResolver mContentResolver;
+ private int mUserId;
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mContentResolver = mContext.getContentResolver();
+ mUserId = mContext.getUserId();
}
@Test
@@ -65,7 +68,7 @@
final Uri red = createImage(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
final Uri blue = createImage(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
- clearMediaOwner(blue);
+ clearMediaOwner(blue, mUserId);
// Since we have no permissions, we should only be able to see media
// that we've contributed
@@ -97,7 +100,7 @@
final Uri red = createImage(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
final Uri blue = createImage(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
- clearMediaOwner(blue);
+ clearMediaOwner(blue, mUserId);
// Holding read permission we can see items we don't own
final HashSet<Long> seen = new HashSet<>();
@@ -126,7 +129,7 @@
final Uri red = createImage(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
final Uri blue = createImage(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
- clearMediaOwner(blue);
+ clearMediaOwner(blue, mUserId);
// Holding read permission we can see items we don't own
final HashSet<Long> seen = new HashSet<>();
@@ -151,7 +154,7 @@
@Test
public void testMediaEscalation() throws Exception {
final Uri red = createImage(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
- clearMediaOwner(red);
+ clearMediaOwner(red, mUserId);
// Confirm that we get can take action to get write access
RecoverableSecurityException exception = null;
@@ -204,12 +207,10 @@
}
}
- private static void clearMediaOwner(Uri uri) throws IOException {
- try (InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(
- InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(
- "content update --uri " + uri + " --bind owner_package_name:n:"))) {
- while (is.read() != -1) {
- }
- }
+ private static void clearMediaOwner(Uri uri, int userId) throws IOException {
+ final String cmd = String.format(
+ "content update --uri %s --user %d --bind owner_package_name:n:",
+ uri, userId);
+ runShellCommand(InstrumentationRegistry.getInstrumentation(), cmd);
}
}
diff --git a/hostsidetests/atrace/AndroidTest.xml b/hostsidetests/atrace/AndroidTest.xml
index ecaa17a..d616f90 100644
--- a/hostsidetests/atrace/AndroidTest.xml
+++ b/hostsidetests/atrace/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS atrace host test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="uitoolkit" />
+ <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
<option name="jar" value="CtsAtraceHostTestCases.jar" />
<option name="runtime-hint" value="9m" />
diff --git a/hostsidetests/atrace/AtraceTestApp/AndroidManifest.xml b/hostsidetests/atrace/AtraceTestApp/AndroidManifest.xml
index cb57d14..06253cd 100644
--- a/hostsidetests/atrace/AtraceTestApp/AndroidManifest.xml
+++ b/hostsidetests/atrace/AtraceTestApp/AndroidManifest.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.cts.atracetestapp">
+ package="com.android.cts.atracetestapp"
+ android:targetSandboxVersion="2">
<!--
A simple app with a tracing section to test that apps tracing signals are
emitted by atrace.
diff --git a/hostsidetests/compilation/app/AndroidManifest.xml b/hostsidetests/compilation/app/AndroidManifest.xml
index 33fc3ab..cca9341 100755
--- a/hostsidetests/compilation/app/AndroidManifest.xml
+++ b/hostsidetests/compilation/app/AndroidManifest.xml
@@ -16,7 +16,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.cts.compilation">
+ package="android.compilation.cts">
<uses-sdk android:minSdkVersion="23" />
<application>
<activity android:name=".CompilationTargetActivity" >
diff --git a/hostsidetests/compilation/app/src/android/cts/compilation/CompilationTargetActivity.java b/hostsidetests/compilation/app/src/android/compilation/cts/CompilationTargetActivity.java
similarity index 99%
rename from hostsidetests/compilation/app/src/android/cts/compilation/CompilationTargetActivity.java
rename to hostsidetests/compilation/app/src/android/compilation/cts/CompilationTargetActivity.java
index 180b4c4..66ff046 100644
--- a/hostsidetests/compilation/app/src/android/cts/compilation/CompilationTargetActivity.java
+++ b/hostsidetests/compilation/app/src/android/compilation/cts/CompilationTargetActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.cts.compilation;
+package android.compilation.cts;
import android.app.Activity;
import android.os.AsyncTask;
diff --git a/hostsidetests/compilation/assets/CtsCompilationApp.apk b/hostsidetests/compilation/assets/CtsCompilationApp.apk
index 1764915..18c76d3 100644
--- a/hostsidetests/compilation/assets/CtsCompilationApp.apk
+++ b/hostsidetests/compilation/assets/CtsCompilationApp.apk
Binary files differ
diff --git a/hostsidetests/compilation/assets/README.txt b/hostsidetests/compilation/assets/README.txt
index aca7dff..0ce8006 100644
--- a/hostsidetests/compilation/assets/README.txt
+++ b/hostsidetests/compilation/assets/README.txt
@@ -6,6 +6,6 @@
$ adb install CtsCompilationApp.apk
# Now run the app manually for a couple of minutes, look for the profile:
-$ adb shell ls -l /data/misc/profiles/cur/0/android.cts.compilation/primary.prof
+$ adb shell ls -l /data/misc/profiles/cur/0/android.compilation.cts/primary.prof
# once the profile appears and is nonempty, grab it:
-$ adb pull /data/misc/profiles/cur/0/android.cts.compilation/primary.prof ./
+$ adb pull /data/misc/profiles/cur/0/android.compilation.cts/primary.prof ./
diff --git a/hostsidetests/compilation/assets/primary.prof.txt b/hostsidetests/compilation/assets/primary.prof.txt
index fd55262..63bbff8 100644
--- a/hostsidetests/compilation/assets/primary.prof.txt
+++ b/hostsidetests/compilation/assets/primary.prof.txt
@@ -1,103 +1,103 @@
-Landroid/cts/compilation/CompilationTargetActivity;
-SHLandroid/cts/compilation/CompilationTargetActivity;->m0()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m1()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m2()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m3()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m4()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m5()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m6()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m7()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m8()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m9()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m10()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m11()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m12()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m13()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m14()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m15()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m16()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m17()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m18()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m19()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m20()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m21()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m22()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m23()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m24()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m25()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m26()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m27()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m28()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m29()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m30()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m31()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m32()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m33()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m34()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m35()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m36()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m37()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m38()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m39()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m40()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m41()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m42()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m43()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m44()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m45()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m46()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m47()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m48()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m49()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m50()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m51()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m52()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m53()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m54()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m55()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m56()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m57()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m58()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m59()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m60()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m61()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m62()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m63()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m64()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m65()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m66()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m67()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m68()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m69()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m70()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m71()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m72()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m73()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m74()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m75()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m76()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m77()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m78()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m79()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m80()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m81()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m82()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m83()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m84()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m85()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m86()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m87()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m88()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m89()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m90()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m91()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m92()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m93()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m94()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m95()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m96()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m97()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m98()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m99()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m100()I
-SHLandroid/cts/compilation/CompilationTargetActivity;->m101()I
\ No newline at end of file
+Landroid/compilation/cts/CompilationTargetActivity;
+SHLandroid/compilation/cts/CompilationTargetActivity;->m0()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m1()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m2()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m3()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m4()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m5()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m6()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m7()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m8()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m9()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m10()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m11()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m12()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m13()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m14()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m15()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m16()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m17()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m18()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m19()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m20()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m21()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m22()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m23()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m24()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m25()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m26()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m27()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m28()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m29()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m30()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m31()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m32()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m33()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m34()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m35()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m36()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m37()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m38()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m39()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m40()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m41()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m42()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m43()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m44()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m45()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m46()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m47()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m48()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m49()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m50()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m51()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m52()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m53()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m54()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m55()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m56()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m57()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m58()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m59()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m60()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m61()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m62()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m63()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m64()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m65()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m66()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m67()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m68()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m69()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m70()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m71()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m72()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m73()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m74()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m75()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m76()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m77()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m78()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m79()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m80()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m81()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m82()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m83()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m84()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m85()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m86()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m87()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m88()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m89()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m90()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m91()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m92()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m93()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m94()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m95()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m96()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m97()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m98()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m99()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m100()I
+SHLandroid/compilation/cts/CompilationTargetActivity;->m101()I
\ No newline at end of file
diff --git a/hostsidetests/compilation/src/android/cts/compilation/AdbRootDependentCompilationTest.java b/hostsidetests/compilation/src/android/compilation/cts/AdbRootDependentCompilationTest.java
similarity index 98%
rename from hostsidetests/compilation/src/android/cts/compilation/AdbRootDependentCompilationTest.java
rename to hostsidetests/compilation/src/android/compilation/cts/AdbRootDependentCompilationTest.java
index 0f0e13b..d371a08 100644
--- a/hostsidetests/compilation/src/android/cts/compilation/AdbRootDependentCompilationTest.java
+++ b/hostsidetests/compilation/src/android/compilation/cts/AdbRootDependentCompilationTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.cts.compilation;
+package android.compilation.cts;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
@@ -51,7 +51,7 @@
* </ul>
*/
public class AdbRootDependentCompilationTest extends DeviceTestCase {
- private static final String APPLICATION_PACKAGE = "android.cts.compilation";
+ private static final String APPLICATION_PACKAGE = "android.compilation.cts";
enum ProfileLocation {
CUR("/data/misc/profiles/cur/0/" + APPLICATION_PACKAGE),
@@ -320,13 +320,13 @@
* been created by the compiler.
*/
private String getOdexFilePath() throws DeviceNotAvailableException {
- // Something like "package:/data/app/android.cts.compilation-1/base.apk"
+ // Something like "package:/data/app/android.compilation.cts-1/base.apk"
String pathSpec = executeSuShellAdbCommand(1, "pm", "path", APPLICATION_PACKAGE)[0];
Matcher matcher = Pattern.compile("^package:(.+/)base\\.apk$").matcher(pathSpec);
boolean found = matcher.find();
assertTrue("Malformed spec: " + pathSpec, found);
String apkDir = matcher.group(1);
- // E.g. /data/app/android.cts.compilation-1/oat/arm64/base.odex
+ // E.g. /data/app/android.compilation.cts-1/oat/arm64/base.odex
String result = executeSuShellAdbCommand(1, "find", apkDir, "-name", "base.odex")[0];
assertTrue("odex file not found: " + result, doesFileExist(result));
return result;
@@ -405,7 +405,7 @@
// For directories, it will print many outputs. Filter to first line which contains '.'
// The target line will look like
- // "u:object_r:shell_data_file:s0 /data/local/tmp/android.cts.compilation.primary.prof"
+ // "u:object_r:shell_data_file:s0 /data/local/tmp/android.compilation.cts.primary.prof"
// Remove the second word to only return "u:object_r:shell_data_file:s0".
return res[0].replaceAll("\\s+.*",""); // remove everything following the first whitespace
diff --git a/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DirectDelegatedCertInstallerTest.java b/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DirectDelegatedCertInstallerTest.java
index 59d386e..97ff034 100644
--- a/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DirectDelegatedCertInstallerTest.java
+++ b/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DirectDelegatedCertInstallerTest.java
@@ -184,8 +184,7 @@
// Test cleaning up the key.
assertThat(mDpm.removeKeyPair(null, alias)).isTrue();
- assertThrows(
- KeyChainException.class, () -> KeyChain.getPrivateKey(getContext(), alias));
+ assertThat(KeyChain.getPrivateKey(getContext(), alias)).isNull();
}
// Test that a key generation request succeeds when device identifiers are not requested.
diff --git a/tests/tests/theme/Android.mk b/hostsidetests/devicepolicy/app/ContentCaptureApp/Android.mk
similarity index 79%
rename from tests/tests/theme/Android.mk
rename to hostsidetests/devicepolicy/app/ContentCaptureApp/Android.mk
index ff8536b..1fb6251 100644
--- a/tests/tests/theme/Android.mk
+++ b/hostsidetests/devicepolicy/app/ContentCaptureApp/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2012 The Android Open Source Project
+# Copyright (C) 2019 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.
@@ -16,23 +16,22 @@
include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsThemeDeviceTestCases
-
# Don't include this package in any target.
LOCAL_MODULE_TAGS := optional
# When built, explicitly put it in the data partition.
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
-
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-
LOCAL_SRC_FILES := $(call all-java-files-under, src)
# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_SDK_VERSION := current
+LOCAL_PACKAGE_NAME := CtsDevicePolicyContentCaptureApp
+
+LOCAL_SDK_VERSION := system_current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := arcts cts vts general-tests
include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/ContentCaptureApp/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ContentCaptureApp/AndroidManifest.xml
new file mode 100644
index 0000000..a0d7b30
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ContentCaptureApp/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 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="com.android.cts.devicepolicy.contentcaptureapp" >
+
+ <application>
+ <activity android:name=".SimpleActivity" android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <service
+ android:name=".SimpleContentCaptureService"
+ android:permission="android.permission.BIND_CONTENT_CAPTURE_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.contentcapture.ContentCaptureService" />
+ </intent-filter>
+ </service>
+ </application>
+
+</manifest>
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/ContentCaptureApp/src/com/android/cts/devicepolicy/contentcaptureapp/SimpleActivity.java b/hostsidetests/devicepolicy/app/ContentCaptureApp/src/com/android/cts/devicepolicy/contentcaptureapp/SimpleActivity.java
new file mode 100644
index 0000000..5ed3bb2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ContentCaptureApp/src/com/android/cts/devicepolicy/contentcaptureapp/SimpleActivity.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.devicepolicy.contentcaptureapp;
+
+import android.app.Activity;
+import android.util.Log;
+import android.view.contentcapture.ContentCaptureManager;
+
+public class SimpleActivity extends Activity {
+
+ public static final String TAG = SimpleActivity.class.getSimpleName();
+
+ @Override
+ public void onStart() {
+ Log.d(TAG, "onStart(): userId=" + android.os.Process.myUserHandle().getIdentifier());
+ super.onStart();
+ final ContentCaptureManager mgr = getSystemService(ContentCaptureManager.class);
+ if (mgr == null) {
+ Log.e(TAG, "no manager");
+ return;
+ }
+ final boolean enabled = mgr.isContentCaptureEnabled();
+ Log.v(TAG, "enabled: " + enabled);
+ setResult(enabled ? 1 : 0);
+ finish();
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/ContentCaptureApp/src/com/android/cts/devicepolicy/contentcaptureapp/SimpleContentCaptureService.java b/hostsidetests/devicepolicy/app/ContentCaptureApp/src/com/android/cts/devicepolicy/contentcaptureapp/SimpleContentCaptureService.java
new file mode 100644
index 0000000..8d11d6a
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ContentCaptureApp/src/com/android/cts/devicepolicy/contentcaptureapp/SimpleContentCaptureService.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.devicepolicy.contentcaptureapp;
+
+import android.service.contentcapture.ContentCaptureService;
+import android.util.Log;
+import android.view.contentcapture.ContentCaptureContext;
+import android.view.contentcapture.ContentCaptureSessionId;
+
+public class SimpleContentCaptureService extends ContentCaptureService {
+
+ private static final String TAG = SimpleContentCaptureService.class.getSimpleName();
+
+ @Override
+ public void onConnected() {
+ Log.d(TAG, "onConnected()");
+ }
+
+ @Override
+ public void onDisconnected() {
+ Log.d(TAG, "onDisconnected()");
+ }
+
+ @Override
+ public void onCreateContentCaptureSession(ContentCaptureContext context,
+ ContentCaptureSessionId sessionId) {
+ Log.d(TAG, "onCreateContentCaptureSession(): " + sessionId);
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
index 5419611..7eb7546 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/latest/AndroidManifest.xml
@@ -74,6 +74,8 @@
<activity android:name="com.android.cts.deviceandprofileowner.AutofillActivity"/>
+ <activity android:name="com.android.cts.deviceandprofileowner.ContentCaptureActivity"/>
+
<activity android:name=".PrintActivity"/>
<activity
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ContentCaptureActivity.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ContentCaptureActivity.java
new file mode 100644
index 0000000..c2f27b7
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ContentCaptureActivity.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.deviceandprofileowner;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Wrapper class used to call the activity in the non-test APK and wait for its result.
+ */
+public class ContentCaptureActivity extends Activity {
+
+ public static final String CONTENT_CAPTURE_PACKAGE_NAME =
+ "com.android.cts.devicepolicy.contentcaptureapp";
+ public static final String CONTENT_CAPTURE_ACTIVITY_NAME = CONTENT_CAPTURE_PACKAGE_NAME
+ + ".SimpleActivity";
+
+ private final CountDownLatch mLatch = new CountDownLatch(1);
+ private boolean mEnabled;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ final Intent launchIntent = new Intent();
+ launchIntent.setComponent(
+ new ComponentName(CONTENT_CAPTURE_PACKAGE_NAME, CONTENT_CAPTURE_ACTIVITY_NAME));
+ startActivityForResult(launchIntent, 42);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ mEnabled = resultCode == 1;
+ mLatch.countDown();
+ }
+
+ public boolean isContentCaptureEnabled() throws InterruptedException {
+ final boolean called = mLatch.await(2, TimeUnit.SECONDS);
+ if (!called) {
+ throw new IllegalStateException(CONTENT_CAPTURE_PACKAGE_NAME
+ + " didn't finish in 2 seconds");
+ }
+ finish();
+ return mEnabled;
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ContentCaptureRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ContentCaptureRestrictionsTest.java
new file mode 100644
index 0000000..95b953b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ContentCaptureRestrictionsTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.deviceandprofileowner;
+
+import static android.os.UserManager.DISALLOW_CONTENT_CAPTURE;
+import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
+
+import static com.android.cts.deviceandprofileowner.ContentCaptureActivity.CONTENT_CAPTURE_ACTIVITY_NAME;
+import static com.android.cts.deviceandprofileowner.ContentCaptureActivity.CONTENT_CAPTURE_PACKAGE_NAME;
+
+import android.content.Intent;
+
+public class ContentCaptureRestrictionsTest extends BaseDeviceAdminTest {
+
+ // TODO(b/123540602): use @TestAPI to get max duration constant from ContentCaptureManager
+ private static final int MAX_TIME_TEMPORARY_SERVICE_CAN_BE_SET= 12000;
+
+ private static final int SLEEP_TIME_WAITING_FOR_SERVICE_CONNECTION_MS = 100;
+
+ private static final String SERVICE_NAME =
+ "com.android.cts.devicepolicy.contentcapture/.SimpleContentCaptureService";
+
+ int mUserId;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mUserId = getInstrumentation().getContext().getUserId();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ try {
+ disableService();
+ } finally {
+ mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+ DISALLOW_CONTENT_CAPTURE);
+ }
+ super.tearDown();
+ }
+
+ public void testDisallowContentCapture_allowed() throws Exception {
+ enableService();
+
+ final boolean enabledBefore = launchActivityAndGetEnabled();
+ assertTrue(enabledBefore);
+
+ mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, DISALLOW_CONTENT_CAPTURE);
+
+ // Must try a couple times because it will be disabled asynchronously.
+ for (int i = 1; i <= 5; i++) {
+ final boolean disabledAfter = !launchActivityAndGetEnabled();
+ if (disabledAfter) {
+ return;
+ }
+ Thread.sleep(100);
+ }
+ fail("Not disabled after 2.5s");
+ }
+
+ private boolean launchActivityAndGetEnabled() throws Exception {
+ final Intent launchIntent = new Intent();
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ launchIntent.setClassName(CONTENT_CAPTURE_PACKAGE_NAME, CONTENT_CAPTURE_ACTIVITY_NAME);
+ final ContentCaptureActivity activity = launchActivity(
+ "com.android.cts.deviceandprofileowner", ContentCaptureActivity.class, null);
+ return activity.isContentCaptureEnabled();
+ }
+
+ private void enableService() throws Exception {
+ runShellCommand("cmd content_capture set temporary-service %d %s %d", mUserId,
+ SERVICE_NAME, MAX_TIME_TEMPORARY_SERVICE_CAN_BE_SET);
+ // TODO: ideally it should wait until the service's onConnected() is called, but that
+ // would be too complicated
+ Thread.sleep(SLEEP_TIME_WAITING_FOR_SERVICE_CONNECTION_MS);
+ }
+
+ private void disableService() {
+ runShellCommand("cmd content_capture set temporary-service %d", mUserId);
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DevicePolicyLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DevicePolicyLoggingTest.java
index 189c619..c6f2f7b 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DevicePolicyLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DevicePolicyLoggingTest.java
@@ -95,6 +95,11 @@
UserManager.DISALLOW_AUTOFILL);
mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
UserManager.DISALLOW_AUTOFILL);
+
+ mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
+ UserManager.DISALLOW_CONTENT_CAPTURE);
+ mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+ UserManager.DISALLOW_CONTENT_CAPTURE);
}
public void testSetSecureSettingLogged()
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/KeyManagementTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/KeyManagementTest.java
index 85b2903..302523b 100755
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/KeyManagementTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/KeyManagementTest.java
@@ -715,15 +715,9 @@
}
}
- private void assertGranted(String alias, boolean expected) throws InterruptedException {
- boolean granted = false;
- try {
- granted = (KeyChain.getPrivateKey(mActivity, alias) != null);
- } catch (KeyChainException e) {
- if (expected) {
- e.printStackTrace();
- }
- }
+ private void assertGranted(String alias, boolean expected)
+ throws InterruptedException, KeyChainException {
+ boolean granted = (KeyChain.getPrivateKey(mActivity, alias) != null);
assertWithMessage("Grant for alias: \"" + alias + "\"").that(granted).isEqualTo(expected);
}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java
index 0534f2a..63c5380 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java
@@ -58,6 +58,7 @@
UserManager.DISALLOW_SET_USER_ICON,
UserManager.DISALLOW_BLUETOOTH,
UserManager.DISALLOW_AUTOFILL,
+ UserManager.DISALLOW_CONTENT_CAPTURE,
UserManager.DISALLOW_UNIFIED_PASSWORD,
};
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java
index 5c9700e..233a23d 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java
@@ -45,6 +45,7 @@
UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
UserManager.DISALLOW_SET_USER_ICON,
UserManager.DISALLOW_AUTOFILL,
+ UserManager.DISALLOW_CONTENT_CAPTURE,
UserManager.DISALLOW_UNIFIED_PASSWORD,
};
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PrivateDnsPolicyTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PrivateDnsPolicyTest.java
index 8e51bc3..3dd79c8 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PrivateDnsPolicyTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PrivateDnsPolicyTest.java
@@ -135,4 +135,26 @@
DUMMY_PRIVATE_DNS_HOST,
DevicePolicyManager.PRIVATE_DNS_SET_ERROR_HOST_NOT_SERVING);
}
+
+ public void testCanSetModeDespiteUserRestriction() {
+ // First set a specific host and assert that applied.
+ callSetGlobalPrivateDnsExpectingResult(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME,
+ VALID_PRIVATE_DNS_HOST,
+ DevicePolicyManager.PRIVATE_DNS_SET_SUCCESS);
+ assertThat(
+ mDevicePolicyManager.getGlobalPrivateDnsMode(getWho())).isEqualTo(
+ PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+
+ // Set a user restriction
+ setUserRestriction(UserManager.DISALLOW_CONFIG_PRIVATE_DNS, true);
+
+ // Next, set the mode to automatic and confirm that has applied.
+ callSetGlobalPrivateDnsExpectingResult(PRIVATE_DNS_MODE_OPPORTUNISTIC, null,
+ DevicePolicyManager.PRIVATE_DNS_SET_SUCCESS);
+
+ assertThat(
+ mDevicePolicyManager.getGlobalPrivateDnsMode(getWho())).isEqualTo(
+ PRIVATE_DNS_MODE_OPPORTUNISTIC);
+ assertThat(mDevicePolicyManager.getGlobalPrivateDnsHost(getWho())).isNull();
+ }
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 260b730..7620734 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -115,6 +115,10 @@
private static final String AUTOFILL_APP_PKG = "com.android.cts.devicepolicy.autofillapp";
private static final String AUTOFILL_APP_APK = "CtsDevicePolicyAutofillApp.apk";
+ private static final String CONTENT_CAPTURE_APP_PKG =
+ "com.android.cts.devicepolicy.contentcaptureapp";
+ private static final String CONTENT_CAPTURE_APP_APK = "CtsDevicePolicyContentCaptureApp.apk";
+
protected static final String ASSIST_APP_PKG = "com.android.cts.devicepolicy.assistapp";
protected static final String ASSIST_APP_APK = "CtsDevicePolicyAssistApp.apk";
@@ -855,8 +859,8 @@
if (!mHasFeature) {
return;
}
- boolean mHasAutofill = hasDeviceFeature("android.software.autofill");
- if (!mHasAutofill) {
+ boolean hasAutofill = hasDeviceFeature("android.software.autofill");
+ if (!hasAutofill) {
return;
}
installAppAsUser(AUTOFILL_APP_APK, mUserId);
@@ -865,6 +869,35 @@
"testDisallowAutofill_allowed");
}
+ // TODO(b/124127364): currently disabled becase ContentCaptureManager.isContentCaptureEnabled()
+ // doesn't return right value when the service is disabled after the activity already launched
+ public void disabledtestDisallowContentCapture_allowed() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+
+ boolean hasContentCapture = hasService("content_capture");
+ if (!hasContentCapture) {
+ return;
+ }
+ installAppAsUser(CONTENT_CAPTURE_APP_APK, mUserId);
+
+ setDefaultContentCaptureServiceEnabled(false);
+ try {
+ executeDeviceTestMethod(".ContentCaptureRestrictionsTest",
+ "testDisallowContentCapture_allowed");
+ } finally {
+ setDefaultContentCaptureServiceEnabled(true);
+ }
+ }
+
+ private void setDefaultContentCaptureServiceEnabled(boolean enabled)
+ throws Exception {
+ CLog.d("setDefaultServiceEnabled(" + mUserId + "): " + enabled);
+ getDevice().executeShellCommand(
+ "cmd content_capture set default-service-enabled " + mUserId + " " + enabled);
+ }
+
public void testSetMeteredDataDisabledPackages() throws Exception {
if (!mHasFeature) {
return;
@@ -1846,4 +1879,19 @@
getDevice().executeShellCommand(
restricted ? RESTRICT_BACKGROUND_ON_CMD : RESTRICT_BACKGROUND_OFF_CMD);
}
+
+ // TODO: copied from RequiredServiceRule, which is on compatibility-device-util
+ // (and we use compatibility-host-util)
+ public boolean hasService(String service) {
+ // TODO: ideally should call SystemServiceManager directly, but we would need to open
+ // some @Testing APIs for that.
+ String command = "service check " + service;
+ try {
+ String commandOutput = getDevice().executeShellCommand(command);
+ return !commandOutput.contains("not found");
+ } catch (Exception e) {
+ CLog.w("Exception running '" + command + "': " + e);
+ return false;
+ }
+ }
}
diff --git a/hostsidetests/edi/AndroidTest.xml b/hostsidetests/edi/AndroidTest.xml
index fdbe2cb..aea1030 100644
--- a/hostsidetests/edi/AndroidTest.xml
+++ b/hostsidetests/edi/AndroidTest.xml
@@ -18,6 +18,7 @@
<option name="config-descriptor:metadata" key="component" value="deviceinfo" />
<!-- Do no need to run instant mode for collecting information -->
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
<option name="jar" value="CtsEdiHostTestCases.jar" />
</test>
diff --git a/hostsidetests/sample/AndroidTest.xml b/hostsidetests/sample/AndroidTest.xml
index 0368682..0b49219 100644
--- a/hostsidetests/sample/AndroidTest.xml
+++ b/hostsidetests/sample/AndroidTest.xml
@@ -17,6 +17,7 @@
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="misc" />
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsSampleDeviceApp.apk" />
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index 3c0eaff..abb293b 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -544,6 +544,7 @@
if (statsdDisabled()) {
return;
}
+ if (!hasFeature(FEATURE_WATCH, false)) return;
final int atomTag = Atom.OVERLAY_STATE_CHANGED_FIELD_NUMBER;
Set<Integer> entered = new HashSet<>(
diff --git a/hostsidetests/systemui/app/src/android/systemui/cts/TestTileService.java b/hostsidetests/systemui/app/src/android/systemui/cts/TestTileService.java
index 4b26ca9..9840b19 100644
--- a/hostsidetests/systemui/app/src/android/systemui/cts/TestTileService.java
+++ b/hostsidetests/systemui/app/src/android/systemui/cts/TestTileService.java
@@ -53,14 +53,15 @@
@Override
public void onTileAdded() {
+ super.onTileAdded();
Log.i(TAG, TEST_PREFIX + "onTileAdded");
super.onTileAdded();
}
@Override
public void onTileRemoved() {
- Log.i(TAG, TEST_PREFIX + "onTileRemoved");
super.onTileRemoved();
+ Log.i(TAG, TEST_PREFIX + "onTileRemoved");
}
@Override
@@ -72,11 +73,11 @@
registerReceiver(mReceiver, filter);
// Set up some initial good state.
- getQsTile().setLabel(TAG);
- getQsTile().setContentDescription("CTS Test Tile");
- getQsTile().setIcon(Icon.createWithResource(this, android.R.drawable.ic_secure));
- getQsTile().setState(Tile.STATE_ACTIVE);
- getQsTile().updateTile();
+ super.getQsTile().setLabel(TAG);
+ super.getQsTile().setContentDescription("CTS Test Tile");
+ super.getQsTile().setIcon(Icon.createWithResource(this, android.R.drawable.ic_secure));
+ super.getQsTile().setState(Tile.STATE_ACTIVE);
+ super.getQsTile().updateTile();
}
@Override
@@ -90,9 +91,9 @@
public void onClick() {
super.onClick();
Log.i(TAG, TEST_PREFIX + "onClick");
- Log.i(TAG, TEST_PREFIX + "is_secure_" + isSecure());
- Log.i(TAG, TEST_PREFIX + "is_locked_" + isLocked());
- unlockAndRun(new Runnable() {
+ Log.i(TAG, TEST_PREFIX + "is_secure_" + super.isSecure());
+ Log.i(TAG, TEST_PREFIX + "is_locked_" + super.isLocked());
+ super.unlockAndRun(new Runnable() {
@Override
public void run() {
Log.i(TAG, TEST_PREFIX + "unlockAndRunRun");
@@ -101,7 +102,7 @@
}
private void handleStartActivity() {
- startActivityAndCollapse(new Intent(Settings.ACTION_SETTINGS)
+ super.startActivityAndCollapse(new Intent(Settings.ACTION_SETTINGS)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
@@ -110,7 +111,7 @@
final Dialog dialog = new Dialog(this);
dialog.setContentView(new FocusView(this, dialog));
try {
- showDialog(dialog);
+ super.showDialog(dialog);
} catch (Exception e) {
Log.i(TAG, TEST_PREFIX + "onWindowAddFailed", e);
}
diff --git a/hostsidetests/usage/AndroidTest.xml b/hostsidetests/usage/AndroidTest.xml
index 9ccc7e1..fc7f46e 100644
--- a/hostsidetests/usage/AndroidTest.xml
+++ b/hostsidetests/usage/AndroidTest.xml
@@ -17,6 +17,7 @@
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="framework" />
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsAppUsageTestApp.apk" />
diff --git a/tests/admin/AndroidTest.xml b/tests/admin/AndroidTest.xml
index c0b10fe..f99f8bf 100644
--- a/tests/admin/AndroidTest.xml
+++ b/tests/admin/AndroidTest.xml
@@ -22,6 +22,10 @@
<!-- Not testing features backed by native code, so only need to run against one ABI -->
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+ <target_preparer class="com.android.tradefed.targetprep.SwitchUserTargetPreparer">
+ <option name="user-type" value="system" />
+ </target_preparer>
+
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="install-arg" value="-t" />
diff --git a/tests/app/app/AndroidManifest.xml b/tests/app/app/AndroidManifest.xml
index 7f66a12..9ef2f3d 100644
--- a/tests/app/app/AndroidManifest.xml
+++ b/tests/app/app/AndroidManifest.xml
@@ -372,6 +372,16 @@
</intent-filter>
</service>
+ <service android:name="android.app.stubs.TestTileService"
+ android:exported="true"
+ android:label="TestTileService"
+ android:icon="@drawable/robot"
+ android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
+ <intent-filter>
+ <action android:name="android.service.quicksettings.action.QS_TILE" />
+ </intent-filter>
+ </service>
+
<activity android:name="android.app.stubs.AutomaticZenRuleActivity">
<intent-filter>
<action android:name="android.app.action.AUTOMATIC_ZEN_RULE" />
diff --git a/tests/app/app/src/android/app/stubs/TestTileService.java b/tests/app/app/src/android/app/stubs/TestTileService.java
new file mode 100644
index 0000000..d3c6db4
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/TestTileService.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 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.app.stubs;
+
+import android.content.ComponentName;
+import android.os.Debug;
+import android.service.quicksettings.TileService;
+
+public class TestTileService extends TileService {
+
+ public static final String TAG = "TestTileService";
+ public static final String PKG = "android.app.stubs";
+ public static final int ICON_ID = R.drawable.robot;
+
+ private static TestTileService sTestTileService = null;
+ boolean isConnected;
+
+ public static String getId() {
+ return String.format("%s/%s", TestTileService.class.getPackage().getName(),
+ TestTileService.class.getName());
+ }
+
+ public static ComponentName getComponentName() {
+ return new ComponentName(TestTileService.class.getPackage().getName(),
+ TestTileService.class.getName());
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ }
+
+ public static TileService getInstance() {
+ return sTestTileService;
+ }
+
+ public boolean isConnected() {
+ return isConnected;
+ }
+
+ @Override
+ public void onTileAdded() {
+ super.onTileAdded();
+ sTestTileService = this;
+ isConnected = true;
+ }
+
+ @Override
+ public void onTileRemoved() {
+ super.onTileRemoved();
+ isConnected = false;
+ sTestTileService = null;
+ }
+}
diff --git a/tests/app/src/android/app/cts/DownloadManagerTest.java b/tests/app/src/android/app/cts/DownloadManagerTest.java
index 76cd58c..98533ac 100644
--- a/tests/app/src/android/app/cts/DownloadManagerTest.java
+++ b/tests/app/src/android/app/cts/DownloadManagerTest.java
@@ -470,6 +470,8 @@
receiver.waitForDownloadComplete(SHORT_TIMEOUT, downloadId);
assertSuccessfulDownload(downloadId, downloadLocation);
final Uri downloadUri = mDownloadManager.getUriForDownloadedFile(downloadId);
+ mContext.grantUriPermission("com.android.shell", downloadUri,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION);
final Uri mediaStoreUri = getMediaStoreUri(downloadUri);
final ContentResolver contentResolver = mContext.getContentResolver();
assertArrayEquals(hash(contentResolver.openInputStream(downloadUri)),
@@ -502,6 +504,8 @@
"text/plain", downloadFile.getPath(), fileContents.getBytes().length, true);
assertTrue(downloadId >= 0);
final Uri downloadUri = mDownloadManager.getUriForDownloadedFile(downloadId);
+ mContext.grantUriPermission("com.android.shell", downloadUri,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION);
final Uri mediaStoreUri = getMediaStoreUri(downloadUri);
assertArrayEquals(hash(new FileInputStream(downloadFile)),
hash(mContext.getContentResolver().openInputStream(mediaStoreUri)));
@@ -555,6 +559,8 @@
assertEquals(testTitle, cursor.getString(0));
}
+ mContext.grantUriPermission("com.android.shell", downloadUri,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION);
final Uri mediaStoreUri = getMediaStoreUri(downloadUri);
final String newTitle = "New_title";
updateUri(mediaStoreUri, "_display_name", newTitle);
diff --git a/tests/app/src/android/app/cts/NotificationCarExtenderTest.java b/tests/app/src/android/app/cts/NotificationCarExtenderTest.java
new file mode 100644
index 0000000..20bf336
--- /dev/null
+++ b/tests/app/src/android/app/cts/NotificationCarExtenderTest.java
@@ -0,0 +1,138 @@
+ /*
+ * Copyright (C) 2019 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.app.cts;
+
+import android.app.Notification;
+import android.app.Notification.CarExtender;
+import android.app.Notification.CarExtender.Builder;
+import android.app.Notification.CarExtender.UnreadConversation;
+import android.app.PendingIntent;
+import android.app.RemoteInput;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.test.AndroidTestCase;
+
+public class NotificationCarExtenderTest extends AndroidTestCase {
+
+ private Context mContext;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mContext = getContext();
+ }
+
+ public void testCarExtender_EmptyConstructor() {
+ CarExtender extender = new Notification.CarExtender();
+ assertNotNull(extender);
+ assertEquals(Notification.COLOR_DEFAULT, extender.getColor());
+ assertEquals(null, extender.getLargeIcon());
+ assertEquals(null, extender.getUnreadConversation());
+ }
+
+ public void testCarExtender_Constructor() {
+ Notification notification = new Notification();
+ CarExtender extender = new Notification.CarExtender(notification);
+ assertNotNull(extender);
+ assertEquals(Notification.COLOR_DEFAULT, extender.getColor());
+ assertEquals(null, extender.getLargeIcon());
+ assertEquals(null, extender.getUnreadConversation());
+ }
+
+ public void testCarExtender() {
+ final int testColor = 11;
+ final Bitmap testIcon = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+ final UnreadConversation testConversation =
+ new Builder("testParticipant")
+ .addMessage("testMessage")
+ .setLatestTimestamp(System.currentTimeMillis())
+ .build();
+
+ CarExtender extender = new Notification.CarExtender()
+ .setColor(testColor)
+ .setLargeIcon(testIcon)
+ .setUnreadConversation(testConversation);
+
+ assertEquals(testColor, extender.getColor());
+ assertEquals(testIcon, extender.getLargeIcon());
+ assertEquals(testConversation, extender.getUnreadConversation());
+ }
+
+ public void testCarExtender_extend() {
+ final int testColor = 11;
+ final Bitmap testIcon = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+ final UnreadConversation testConversation =
+ new Builder("testParticipant")
+ .addMessage("testMessage")
+ .setLatestTimestamp(System.currentTimeMillis())
+ .build();
+ Notification.Builder notifBuilder = new Notification.Builder(mContext, "test id")
+ .setSmallIcon(1);
+ CarExtender extender = new Notification.CarExtender()
+ .setColor(testColor)
+ .setLargeIcon(testIcon)
+ .setUnreadConversation(testConversation);
+
+ extender.extend(notifBuilder);
+
+ Notification notification = notifBuilder.build();
+
+ CarExtender receiveCarExtender = new CarExtender(notification);
+
+ assertNotNull(receiveCarExtender);
+ assertEquals(testColor, receiveCarExtender.getColor());
+ assertEquals(testIcon, receiveCarExtender.getLargeIcon());
+ assertEquals(1, receiveCarExtender.getUnreadConversation().getMessages().length);
+ assertEquals(testConversation.getMessages().length,
+ receiveCarExtender.getUnreadConversation().getMessages().length);
+ assertEquals(testConversation.getMessages()[0],
+ receiveCarExtender.getUnreadConversation().getMessages()[0]);
+ }
+
+ public void testCarExtender_UnreadConversationAndBuilder() {
+ final long testTime = System.currentTimeMillis();
+ final String testMessage = "testMessage";
+ final String testParticipant = "testParticipant";
+ final Intent testIntent = new Intent("testIntent");
+ final PendingIntent testPendingIntent =
+ PendingIntent.getBroadcast(mContext, 0, testIntent,
+ PendingIntent.FLAG_CANCEL_CURRENT);
+ final PendingIntent testReplyPendingIntent =
+ PendingIntent.getBroadcast(mContext, 0, testIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ final RemoteInput testRemoteInput = new RemoteInput.Builder("key").build();
+
+ final UnreadConversation testConversation =
+ new Builder(testParticipant)
+ .setLatestTimestamp(testTime)
+ .addMessage(testMessage)
+ .setReadPendingIntent(testPendingIntent)
+ .setReplyAction(testReplyPendingIntent, testRemoteInput)
+ .build();
+
+ assertEquals(testTime, testConversation.getLatestTimestamp());
+ assertEquals(1, testConversation.getMessages().length);
+ assertEquals(testMessage, testConversation.getMessages()[0]);
+ assertEquals(testParticipant, testConversation.getParticipant());
+ assertEquals(1, testConversation.getParticipants().length);
+ assertEquals(testParticipant, testConversation.getParticipants()[0]);
+ assertEquals(testPendingIntent, testConversation.getReadPendingIntent());
+ assertEquals(testRemoteInput, testConversation.getRemoteInput());
+ assertEquals(testPendingIntent, testConversation.getReplyPendingIntent());
+ }
+}
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index 0dad0de..9949b56 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -1018,6 +1018,189 @@
}
}
+ public void testShowBadging_ranking() throws Exception {
+ if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
+ return;
+ }
+
+ final int originalBadging = Settings.Secure.getInt(
+ mContext.getContentResolver(), Settings.Secure.NOTIFICATION_BADGING);
+
+ SystemUtil.runWithShellPermissionIdentity(() ->
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.NOTIFICATION_BADGING, 1));
+ assertEquals(1, Settings.Secure.getInt(
+ mContext.getContentResolver(), Settings.Secure.NOTIFICATION_BADGING));
+
+ toggleListenerAccess(TestNotificationListener.getId(),
+ InstrumentationRegistry.getInstrumentation(), true);
+ Thread.sleep(500); // wait for listener to be allowed
+
+ mListener = TestNotificationListener.getInstance();
+ assertNotNull(mListener);
+ try {
+ sendNotification(1, R.drawable.black);
+ Thread.sleep(500); // wait for notification listener to receive notification
+ NotificationListenerService.RankingMap rankingMap = mListener.mRankingMap;
+ NotificationListenerService.Ranking outRanking =
+ new NotificationListenerService.Ranking();
+ for (String key : rankingMap.getOrderedKeys()) {
+ if (key.contains(mListener.getPackageName())) {
+ rankingMap.getRanking(key, outRanking);
+ assertTrue(outRanking.canShowBadge());
+ }
+ }
+
+ // turn off badging globally
+ SystemUtil.runWithShellPermissionIdentity(() ->
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.NOTIFICATION_BADGING, 0));
+
+ Thread.sleep(500); // wait for ranking update
+
+ rankingMap = mListener.mRankingMap;
+ outRanking = new NotificationListenerService.Ranking();
+ for (String key : rankingMap.getOrderedKeys()) {
+ if (key.contains(mListener.getPackageName())) {
+ assertFalse(outRanking.canShowBadge());
+ }
+ }
+
+ mListener.resetData();
+ } finally {
+ SystemUtil.runWithShellPermissionIdentity(() ->
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.NOTIFICATION_BADGING, originalBadging));
+ }
+ }
+
+ public void testGetSuppressedVisualEffectsOff_ranking() throws Exception {
+ if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
+ return;
+ }
+
+ toggleListenerAccess(TestNotificationListener.getId(),
+ InstrumentationRegistry.getInstrumentation(), true);
+ Thread.sleep(500); // wait for listener to be allowed
+
+ mListener = TestNotificationListener.getInstance();
+ assertNotNull(mListener);
+
+ final int notificationId = 1;
+ sendNotification(notificationId, R.drawable.black);
+ Thread.sleep(500); // wait for notification listener to receive notification
+
+ NotificationListenerService.RankingMap rankingMap = mListener.mRankingMap;
+ NotificationListenerService.Ranking outRanking =
+ new NotificationListenerService.Ranking();
+
+ for (String key : rankingMap.getOrderedKeys()) {
+ if (key.contains(mListener.getPackageName())) {
+ rankingMap.getRanking(key, outRanking);
+
+ // check notification key match
+ assertEquals(0, outRanking.getSuppressedVisualEffects());
+ }
+ }
+ }
+
+ public void testGetSuppressedVisualEffects_ranking() throws Exception {
+ if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
+ return;
+ }
+
+ final int originalFilter = mNotificationManager.getCurrentInterruptionFilter();
+ try {
+ toggleListenerAccess(TestNotificationListener.getId(),
+ InstrumentationRegistry.getInstrumentation(), true);
+ Thread.sleep(500); // wait for listener to be allowed
+
+ mListener = TestNotificationListener.getInstance();
+ assertNotNull(mListener);
+
+ toggleNotificationPolicyAccess(mContext.getPackageName(),
+ InstrumentationRegistry.getInstrumentation(), true);
+ if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) {
+ mNotificationManager.setNotificationPolicy(new NotificationManager.Policy(0, 0, 0,
+ SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_PEEK));
+ } else {
+ mNotificationManager.setNotificationPolicy(new NotificationManager.Policy(0, 0, 0,
+ SUPPRESSED_EFFECT_SCREEN_ON));
+ }
+ mNotificationManager.setInterruptionFilter(
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY);
+
+ final int notificationId = 1;
+ // update notification
+ sendNotification(notificationId, R.drawable.black);
+ Thread.sleep(500); // wait for notification listener to receive notification
+
+ NotificationListenerService.RankingMap rankingMap = mListener.mRankingMap;
+ NotificationListenerService.Ranking outRanking =
+ new NotificationListenerService.Ranking();
+
+ for (String key : rankingMap.getOrderedKeys()) {
+ if (key.contains(mListener.getPackageName())) {
+ rankingMap.getRanking(key, outRanking);
+
+ if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) {
+ assertEquals(SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_PEEK,
+ outRanking.getSuppressedVisualEffects());
+ } else {
+ assertEquals(SUPPRESSED_EFFECT_SCREEN_ON,
+ outRanking.getSuppressedVisualEffects());
+ }
+ }
+ }
+ } finally {
+ // reset notification policy
+ mNotificationManager.setInterruptionFilter(originalFilter);
+ }
+
+ }
+
+ public void testKeyChannelGroupOverrideImportanceExplanation_ranking() throws Exception {
+ if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
+ return;
+ }
+
+ toggleListenerAccess(TestNotificationListener.getId(),
+ InstrumentationRegistry.getInstrumentation(), true);
+ Thread.sleep(500); // wait for listener to be allowed
+
+ mListener = TestNotificationListener.getInstance();
+ assertNotNull(mListener);
+
+ final int notificationId = 1;
+ sendNotification(notificationId, R.drawable.black);
+ Thread.sleep(500); // wait for notification listener to receive notification
+
+ NotificationListenerService.RankingMap rankingMap = mListener.mRankingMap;
+ NotificationListenerService.Ranking outRanking =
+ new NotificationListenerService.Ranking();
+
+ StatusBarNotification sbn = findPostedNotification(notificationId);
+
+ // check that the key and channel ids are the same in the ranking as the posted notification
+ for (String key : rankingMap.getOrderedKeys()) {
+ if (key.contains(mListener.getPackageName())) {
+ rankingMap.getRanking(key, outRanking);
+
+ // check notification key match
+ assertEquals(sbn.getKey(), outRanking.getKey());
+
+ // check notification channel ids match
+ assertEquals(sbn.getNotification().getChannelId(), outRanking.getChannel().getId());
+
+ // check override group key match
+ assertEquals(sbn.getOverrideGroupKey(), outRanking.getOverrideGroupKey());
+
+ // check importance explanation isn't null
+ assertNotNull(outRanking.getImportanceExplanation());
+ }
+ }
+ }
+
public void testNotify_blockedChannel() throws Exception {
mNotificationManager.cancelAll();
diff --git a/tests/app/src/android/app/cts/TileServiceTest.java b/tests/app/src/android/app/cts/TileServiceTest.java
new file mode 100644
index 0000000..7daab1a
--- /dev/null
+++ b/tests/app/src/android/app/cts/TileServiceTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2019 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.app.cts;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.UiAutomation;
+import android.app.stubs.TestTileService;
+import android.os.Debug;
+import android.os.Looper;
+import android.os.ParcelFileDescriptor;
+import android.service.quicksettings.Tile;
+import android.service.quicksettings.TileService;
+import android.support.test.InstrumentationRegistry;
+import android.test.AndroidTestCase;
+
+import junit.framework.Assert;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class TileServiceTest extends AndroidTestCase {
+ final String TAG = TileServiceTest.class.getSimpleName();
+
+ private TileService mTileService;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ toggleServiceAccess(TestTileService.getComponentName().flattenToString(), false);
+ Thread.sleep(200); // wait for service to be unbound
+ assertNull(TestTileService.getInstance());
+ }
+
+ public void testCreateTileService() {
+ final TileService tileService = new TileService();
+ }
+
+ public void testLocked_deviceNotLocked() throws Exception {
+ if (!TileService.isQuickSettingsSupported()) return;
+ startTileService();
+ assertFalse(mTileService.isLocked());
+ }
+
+ public void testSecure_deviceNotSecure() throws Exception {
+ if (!TileService.isQuickSettingsSupported()) return;
+ startTileService();
+ assertFalse(mTileService.isSecure());
+ }
+
+ public void testTile_hasCorrectIcon() throws Exception {
+ if (!TileService.isQuickSettingsSupported()) return;
+ startTileService();
+ Tile tile = mTileService.getQsTile();
+ assertEquals(TestTileService.ICON_ID, tile.getIcon().getResId());
+ }
+
+ public void testShowDialog() throws Exception {
+ if (!TileService.isQuickSettingsSupported()) return;
+ Looper.prepare();
+ Dialog dialog = new AlertDialog.Builder(mContext).create();
+ startTileService();
+ clickTile(TestTileService.getComponentName().flattenToString());
+
+ mTileService.showDialog(dialog);
+
+ assertTrue(dialog.isShowing());
+ dialog.dismiss();
+ }
+
+ public void testUnlockAndRun_phoneIsUnlockedActivityIsRun() throws Exception {
+ if (!TileService.isQuickSettingsSupported()) return;
+ startTileService();
+ assertFalse(mTileService.isLocked());
+
+ TestRunnable testRunnable = new TestRunnable();
+
+ mTileService.unlockAndRun(testRunnable);
+ Thread.sleep(100); // wait for activity to run
+ assertTrue(testRunnable.hasRan);
+ }
+
+ private void startTileService() throws Exception {
+ toggleServiceAccess(TestTileService.getComponentName().flattenToString(), true);
+ Thread.sleep(200); // wait for service to be bound
+ mTileService = TestTileService.getInstance();
+ assertNotNull(mTileService);
+ }
+
+ private void toggleServiceAccess(String componentName, boolean on) throws Exception {
+
+ String command = " cmd statusbar " + (on ? "add-tile " : "remove-tile ")
+ + componentName;
+
+ runCommand(command);
+ }
+
+ private void clickTile(String componentName) throws Exception {
+ runCommand(" cmd statusbar click-tile " + componentName);
+ }
+
+ private void runCommand(String command) throws IOException {
+ UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+ // Execute command
+ try (ParcelFileDescriptor fd = uiAutomation.executeShellCommand(command)) {
+ Assert.assertNotNull("Failed to execute shell command: " + command, fd);
+ // Wait for the command to finish by reading until EOF
+ try (InputStream in = new FileInputStream(fd.getFileDescriptor())) {
+ byte[] buffer = new byte[4096];
+ while (in.read(buffer) > 0) {}
+ } catch (IOException e) {
+ throw new IOException("Could not read stdout of command: " + command, e);
+ }
+ } finally {
+ uiAutomation.destroy();
+ }
+ }
+
+ class TestRunnable implements Runnable {
+ boolean hasRan = false;
+
+ @Override
+ public void run() {
+ hasRan = true;
+ }
+ }
+}
diff --git a/tests/app/src/android/app/cts/WallpaperManagerTest.java b/tests/app/src/android/app/cts/WallpaperManagerTest.java
index cc1d479..1bd90a5 100644
--- a/tests/app/src/android/app/cts/WallpaperManagerTest.java
+++ b/tests/app/src/android/app/cts/WallpaperManagerTest.java
@@ -243,6 +243,63 @@
assertDesiredDimension(new Point(w, min.y / 2), new Point(w, min.y / 2));
}
+ @Test
+ public void wallpaperColors_primary() {
+ Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(tmpWallpaper);
+ canvas.drawColor(Color.RED);
+
+ try {
+ mWallpaperManager.setBitmap(tmpWallpaper);
+ WallpaperColors colors = mWallpaperManager.getWallpaperColors(
+ WallpaperManager.FLAG_SYSTEM);
+
+ // Check that primary color is almost red
+ Color primary = colors.getPrimaryColor();
+ final float delta = 0.1f;
+ Assert.assertEquals("red", 1f, primary.red(), delta);
+ Assert.assertEquals("green", 0f, primary.green(), delta);
+ Assert.assertEquals("blue", 0f, primary.blue(), delta);
+
+ Assert.assertNull(colors.getSecondaryColor());
+ Assert.assertNull(colors.getTertiaryColor());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ tmpWallpaper.recycle();
+ }
+ }
+
+
+ @Test
+ public void wallpaperColors_secondary() {
+ Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(tmpWallpaper);
+ canvas.drawColor(Color.RED);
+ // Make 20% of the wallpaper BLUE so that secondary color is BLUE
+ canvas.clipRect(0, 0, 100, 20);
+ canvas.drawColor(Color.BLUE);
+
+ try {
+ mWallpaperManager.setBitmap(tmpWallpaper);
+ WallpaperColors colors = mWallpaperManager.getWallpaperColors(
+ WallpaperManager.FLAG_SYSTEM);
+
+ // Check that the secondary color is almost blue
+ Color secondary = colors.getSecondaryColor();
+ final float delta = 0.1f;
+ Assert.assertEquals("red", 0f, secondary.red(), delta);
+ Assert.assertEquals("green", 0f, secondary.green(), delta);
+ Assert.assertEquals("blue", 1f, secondary.blue(), delta);
+
+ Assert.assertNull(colors.getTertiaryColor());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ tmpWallpaper.recycle();
+ }
+ }
+
private void assertDesiredDimension(Point suggestedSize, Point expectedSize) {
mWallpaperManager.suggestDesiredDimensions(suggestedSize.x, suggestedSize.y);
Point actualSize = new Point(mWallpaperManager.getDesiredMinimumWidth(),
diff --git a/tests/app/src/android/app/cts/WearableExtenderTest.java b/tests/app/src/android/app/cts/WearableExtenderTest.java
new file mode 100644
index 0000000..eb3e5d8
--- /dev/null
+++ b/tests/app/src/android/app/cts/WearableExtenderTest.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2019 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.app.cts;
+
+import android.app.Notification;
+import android.app.Notification.Action;
+import android.app.Notification.WearableExtender;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+import android.view.Gravity;
+import java.util.ArrayList;
+import java.util.List;
+
+public class WearableExtenderTest extends AndroidTestCase {
+
+ private Context mContext;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mContext = getContext();
+ }
+
+ public void testWearableExtender() {
+ final String bridgeTag = "bridge_tag";
+ final String dismissalId = "dismissal_id";
+ final int contentActionIndex = 2;
+ final Bitmap background = Bitmap.createBitmap(10, 10, Config.ARGB_8888);
+ PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ Notification page1 = new Notification.Builder(mContext, "test id")
+ .setSmallIcon(1)
+ .setContentTitle("page1")
+ .build();
+ Notification page2 = new Notification.Builder(mContext, "test id")
+ .setSmallIcon(1)
+ .setContentTitle("page2")
+ .build();
+ List<Notification> pages = new ArrayList<>();
+ pages.add(page2);
+ final int gravity = Gravity.LEFT;
+ final int icon = 3;
+ final int height = 4;
+ final int size = 5;
+ final int timeout = 6;
+
+ WearableExtender extender = new WearableExtender()
+ .setStartScrollBottom(true)
+ .setContentIntentAvailableOffline(true)
+ .setHintContentIntentLaunchesActivity(true)
+ .setBridgeTag(bridgeTag)
+ .setDismissalId(dismissalId)
+ .setContentAction(contentActionIndex)
+ // deprecated methods follow
+ .setBackground(background)
+ .setGravity(gravity)
+ .setContentIcon(icon)
+ .setContentIconGravity(gravity)
+ .setCustomContentHeight(height)
+ .setCustomSizePreset(size)
+ .setDisplayIntent(pendingIntent)
+ .setHintAmbientBigPicture(true)
+ .setHintAvoidBackgroundClipping(true)
+ .setHintHideIcon(true)
+ .setHintScreenTimeout(timeout)
+ .setHintShowBackgroundOnly(true)
+ .addPage(page1)
+ .clearPages()
+ .addPages(pages);
+
+ assertTrue(extender.getStartScrollBottom());
+ assertTrue(extender.getContentIntentAvailableOffline());
+ assertTrue(extender.getHintContentIntentLaunchesActivity());
+ assertEquals(bridgeTag, extender.getBridgeTag());
+ assertEquals(dismissalId, extender.getDismissalId());
+ assertEquals(contentActionIndex, extender.getContentAction());
+ // deprecated methods follow
+ assertEquals(background, extender.getBackground());
+ assertEquals(gravity, extender.getGravity());
+ assertEquals(icon, extender.getContentIcon());
+ assertEquals(gravity, extender.getContentIconGravity());
+ assertEquals(height, extender.getCustomContentHeight());
+ assertEquals(size, extender.getCustomSizePreset());
+ assertEquals(pendingIntent, extender.getDisplayIntent());
+ assertTrue(extender.getHintAmbientBigPicture());
+ assertTrue(extender.getHintAvoidBackgroundClipping());
+ assertTrue(extender.getHintHideIcon());
+ assertEquals(timeout, extender.getHintScreenTimeout());
+ assertTrue(extender.getHintShowBackgroundOnly());
+ assertEquals(1, extender.getPages().size());
+ assertEquals(page2, extender.getPages().get(0));
+ }
+
+ public void testWearableExtenderActions() {
+ Notification.Action a = newActionBuilder().build();
+ Notification.Action b = newActionBuilder().build();
+ Notification.Action c = newActionBuilder().build();
+ List<Action> actions = new ArrayList<>();
+ actions.add(b);
+ actions.add(c);
+
+ WearableExtender extender = new WearableExtender()
+ .addAction(a)
+ .addActions(actions)
+ .setContentAction(1);
+
+ assertEquals(3, extender.getActions().size());
+ assertEquals(b, extender.getActions().get(extender.getContentAction()));
+ }
+
+ public void testWearableExtender_clearActions() {
+ WearableExtender extender = new WearableExtender()
+ .addAction(newActionBuilder().build());
+
+ extender.clearActions();
+
+ assertEquals(0, extender.getActions().size());
+ }
+
+ public void testWearableExtender_clone() {
+ final String bridgeTag = "bridge_tag";
+ final String dismissalId = "dismissal_id";
+ final int contentActionIndex = 2;
+ WearableExtender original = new WearableExtender()
+ .addAction(newActionBuilder().build())
+ .setStartScrollBottom(true)
+ .setContentIntentAvailableOffline(true)
+ .setHintContentIntentLaunchesActivity(true)
+ .setBridgeTag(bridgeTag)
+ .setDismissalId(dismissalId)
+ .setContentAction(contentActionIndex);
+
+ // WHEN the enter is cloned
+ WearableExtender clone = original.clone();
+ // and WHEN the original is modified
+ original.clearActions();
+
+ assertTrue(clone.getStartScrollBottom());
+ assertTrue(clone.getContentIntentAvailableOffline());
+ assertTrue(clone.getHintContentIntentLaunchesActivity());
+ assertEquals(bridgeTag, clone.getBridgeTag());
+ assertEquals(dismissalId, clone.getDismissalId());
+ assertEquals(contentActionIndex, clone.getContentAction());
+ assertEquals(1, clone.getActions().size());
+ }
+
+ public void testWearableExtender_extend() {
+ final String title = "test_title";
+ final String bridgeTag = "bridge_tag";
+ final String dismissalId = "dismissal_id";
+ final int contentActionIndex = 2;
+ Notification.Builder notifBuilder = new Notification.Builder(mContext, "test id")
+ .setSmallIcon(1)
+ .setContentTitle(title);
+ WearableExtender extender = new WearableExtender()
+ .addAction(newActionBuilder().build())
+ .setStartScrollBottom(true)
+ .setContentIntentAvailableOffline(true)
+ .setHintContentIntentLaunchesActivity(true)
+ .setBridgeTag(bridgeTag)
+ .setDismissalId(dismissalId)
+ .setContentAction(contentActionIndex);
+
+ extender.extend(notifBuilder);
+
+ WearableExtender result = new WearableExtender(notifBuilder.build());
+ assertTrue(result.getStartScrollBottom());
+ assertTrue(result.getContentIntentAvailableOffline());
+ assertTrue(result.getHintContentIntentLaunchesActivity());
+ assertEquals(bridgeTag, result.getBridgeTag());
+ assertEquals(dismissalId, result.getDismissalId());
+ assertEquals(contentActionIndex, result.getContentAction());
+ assertEquals(1, result.getActions().size());
+ }
+
+ public void testWriteToParcel() {
+ final String bridgeTag = "bridge_tag";
+ final String dismissalId = "dismissal_id";
+ final int contentActionIndex = 2;
+ Notification.Action action = newActionBuilder().build();
+ final Bitmap background = Bitmap.createBitmap(10, 10, Config.ARGB_8888);
+ PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ Notification page1 = new Notification.Builder(mContext, "test id")
+ .setSmallIcon(1)
+ .setContentTitle("page1")
+ .build();
+ Notification page2 = new Notification.Builder(mContext, "test id")
+ .setSmallIcon(1)
+ .setContentTitle("page2")
+ .build();
+ List<Notification> pages = new ArrayList<>();
+ pages.add(page2);
+ final int gravity = Gravity.LEFT;
+ final int icon = 3;
+ final int height = 4;
+ final int size = 5;
+ final int timeout = 6;
+
+ Notification notif = new Notification.Builder(mContext, "test id")
+ .setSmallIcon(1)
+ .setContentTitle("test_title")
+ .extend(new Notification.WearableExtender()
+ .setStartScrollBottom(true)
+ .setContentIntentAvailableOffline(true)
+ .setHintContentIntentLaunchesActivity(true)
+ .setBridgeTag(bridgeTag)
+ .setDismissalId(dismissalId)
+ .addAction(action)
+ .setContentAction(contentActionIndex)
+ // deprecated methods follow
+ .setBackground(background)
+ .setGravity(gravity)
+ .setContentIcon(icon)
+ .setContentIconGravity(gravity)
+ .setCustomContentHeight(height)
+ .setCustomSizePreset(size)
+ .setDisplayIntent(pendingIntent)
+ .setHintAmbientBigPicture(true)
+ .setHintAvoidBackgroundClipping(true)
+ .setHintHideIcon(true)
+ .setHintScreenTimeout(timeout)
+ .setHintShowBackgroundOnly(true)
+ .addPage(page1))
+ .build();
+
+ Parcel parcel = Parcel.obtain();
+ notif.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ Notification result = new Notification(parcel);
+
+ WearableExtender extender = new WearableExtender(result);
+ assertTrue(extender.getStartScrollBottom());
+ assertTrue(extender.getContentIntentAvailableOffline());
+ assertTrue(extender.getHintContentIntentLaunchesActivity());
+ assertEquals(bridgeTag, extender.getBridgeTag());
+ assertEquals(dismissalId, extender.getDismissalId());
+ assertEquals(contentActionIndex, extender.getContentAction());
+ assertEquals(1, extender.getActions().size());
+ // deprecated methods follow
+ assertNotNull(extender.getBackground());
+ assertEquals(gravity, extender.getGravity());
+ assertEquals(icon, extender.getContentIcon());
+ assertEquals(gravity, extender.getContentIconGravity());
+ assertEquals(height, extender.getCustomContentHeight());
+ assertEquals(size, extender.getCustomSizePreset());
+ assertEquals(pendingIntent, extender.getDisplayIntent());
+ assertTrue(extender.getHintAmbientBigPicture());
+ assertTrue(extender.getHintAvoidBackgroundClipping());
+ assertTrue(extender.getHintHideIcon());
+ assertEquals(timeout, extender.getHintScreenTimeout());
+ assertTrue(extender.getHintShowBackgroundOnly());
+ assertEquals(1, extender.getPages().size());
+ }
+
+ private static Notification.Action.Builder newActionBuilder() {
+ return new Notification.Action.Builder(0, "title", null);
+ }
+}
\ No newline at end of file
diff --git a/tests/autofillservice/Android.mk b/tests/autofillservice/Android.mk
index 5d74e87..3b8ff6c 100644
--- a/tests/autofillservice/Android.mk
+++ b/tests/autofillservice/Android.mk
@@ -29,6 +29,7 @@
ctstestrunner \
truth-prebuilt \
ub-uiautomator \
+ CtsMockInputMethodLib \
testng # TODO: remove once Android migrates to JUnit 4.12, which provide assertThrows
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/autofillservice/AndroidTest.xml b/tests/autofillservice/AndroidTest.xml
index 53ab5ff..d59e349 100644
--- a/tests/autofillservice/AndroidTest.xml
+++ b/tests/autofillservice/AndroidTest.xml
@@ -24,6 +24,16 @@
<option name="test-file-name" value="CtsAutoFillServiceTestCases.apk" />
</target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <!--
+ MockIME always needs to be installed as a full package, even when CTS is running
+ for instant apps.
+ -->
+ <option name="force-install-mode" value="FULL"/>
+ <option name="test-file-name" value="CtsMockInputMethod.apk" />
+ </target_preparer>
+
<!-- TODO: preparer below should be enabled only when running as cts-instant -->
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="run-command" value="cmd autofill set bind-instant-service-allowed true" />
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java b/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java
index cb98b54..92821a3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java
@@ -53,7 +53,7 @@
}
@Test
- @AppModeFull // testDatasetAuthTwoFields() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDatasetAuthTwoFields() is enough")
public void testDatasetAuthTwoFieldsUserCancelsFirstAttempt() throws Exception {
datasetAuthTwoFields(true);
}
@@ -136,7 +136,7 @@
}
@Test
- @AppModeFull // testDatasetAuthTwoFields() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDatasetAuthTwoFields() is enough")
public void testDatasetAuthTwoFieldsReplaceResponse() throws Exception {
// Set service.
enableService();
@@ -198,7 +198,7 @@
}
@Test
- @AppModeFull // testDatasetAuthTwoFields() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDatasetAuthTwoFields() is enough")
public void testDatasetAuthTwoFieldsNoValues() throws Exception {
// Set service.
enableService();
@@ -242,7 +242,7 @@
}
@Test
- @AppModeFull // testDatasetAuthTwoFields() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDatasetAuthTwoFields() is enough")
public void testDatasetAuthTwoDatasets() throws Exception {
// Set service.
enableService();
@@ -297,13 +297,13 @@
}
@Test
- @AppModeFull // testDatasetAuthTwoFields() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDatasetAuthTwoFields() is enough")
public void testDatasetAuthMixedSelectAuth() throws Exception {
datasetAuthMixedTest(true);
}
@Test
- @AppModeFull // testDatasetAuthTwoFields() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDatasetAuthTwoFields() is enough")
public void testDatasetAuthMixedSelectNonAuth() throws Exception {
datasetAuthMixedTest(false);
}
@@ -363,7 +363,7 @@
}
@Test
- @AppModeFull // testDatasetAuthFilteringUsingRegex() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDatasetAuthFilteringUsingRegex() is enough")
public void testDatasetAuthNoFiltering() throws Exception {
// Set service.
enableService();
@@ -421,7 +421,7 @@
}
@Test
- @AppModeFull // testDatasetAuthFilteringUsingRegex() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDatasetAuthFilteringUsingRegex() is enough")
public void testDatasetAuthFilteringUsingAutofillValue() throws Exception {
// Set service.
enableService();
@@ -577,13 +577,13 @@
}
@Test
- @AppModeFull // testDatasetAuthFilteringUsingRegex() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDatasetAuthFilteringUsingRegex() is enough")
public void testDatasetAuthMixedFilteringSelectAuth() throws Exception {
datasetAuthMixedFilteringTest(true);
}
@Test
- @AppModeFull // testDatasetAuthFilteringUsingRegex() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDatasetAuthFilteringUsingRegex() is enough")
public void testDatasetAuthMixedFilteringSelectNonAuth() throws Exception {
datasetAuthMixedFilteringTest(false);
}
@@ -668,13 +668,13 @@
}
@Test
- @AppModeFull // testDatasetAuthClientStateSetOnIntentOnly() is enough to test ephemeral apps
+ @AppModeFull(reason = "testDatasetAuthClientStateSetOnIntentOnly() is enough")
public void testDatasetAuthClientStateSetOnFillResponseOnly() throws Exception {
fillDatasetAuthWithClientState(ClientStateLocation.FILL_RESPONSE_ONLY);
}
@Test
- @AppModeFull // testDatasetAuthClientStateSetOnIntentOnly() is enough to test ephemeral apps
+ @AppModeFull(reason = "testDatasetAuthClientStateSetOnIntentOnly() is enough")
public void testDatasetAuthClientStateSetOnIntentAndFillResponse() throws Exception {
fillDatasetAuthWithClientState(ClientStateLocation.BOTH);
}
@@ -743,7 +743,7 @@
}
@Test
- @AppModeFull // testFillResponseAuthBothFields() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testFillResponseAuthBothFields() is enough")
public void testFillResponseAuthBothFieldsUserCancelsFirstAttempt() throws Exception {
fillResponseAuthBothFields(true);
}
@@ -837,7 +837,7 @@
}
@Test
- @AppModeFull // testFillResponseAuthBothFields() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testFillResponseAuthBothFields() is enough")
public void testFillResponseAuthJustOneField() throws Exception {
// Set service.
enableService();
@@ -902,7 +902,7 @@
}
@Test
- @AppModeFull // testFillResponseAuthBothFields() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testFillResponseAuthBothFields() is enough")
public void testFillResponseAuthWhenAppCallsCancel() throws Exception {
// Set service.
enableService();
@@ -955,13 +955,13 @@
}
@Test
- @AppModeFull // testFillResponseAuthBothFields() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testFillResponseAuthBothFields() is enough")
public void testFillResponseAuthServiceHasNoDataButCanSave() throws Exception {
fillResponseAuthServiceHasNoDataTest(true);
}
@Test
- @AppModeFull // testFillResponseAuthBothFields() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testFillResponseAuthBothFields() is enough")
public void testFillResponseAuthServiceHasNoData() throws Exception {
fillResponseAuthServiceHasNoDataTest(false);
}
@@ -1034,13 +1034,13 @@
}
@Test
- @AppModeFull // testFillResponseAuthClientStateSetOnIntentOnly() is enough to test ephemeral
+ @AppModeFull(reason = "testFillResponseAuthClientStateSetOnIntentOnly() is enough")
public void testFillResponseAuthClientStateSetOnFillResponseOnly() throws Exception {
fillResponseAuthWithClientState(ClientStateLocation.FILL_RESPONSE_ONLY);
}
@Test
- @AppModeFull // testFillResponseAuthClientStateSetOnIntentOnly() is enough to test ephemeral
+ @AppModeFull(reason = "testFillResponseAuthClientStateSetOnIntentOnly() is enough")
public void testFillResponseAuthClientStateSetOnIntentAndFillResponse() throws Exception {
fillResponseAuthWithClientState(ClientStateLocation.BOTH);
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
index 6997453..40d1e4e 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
@@ -19,7 +19,6 @@
import static android.autofillservice.cts.Helper.getContext;
import static android.autofillservice.cts.InstrumentedAutoFillService.SERVICE_NAME;
import static android.content.Context.CLIPBOARD_SERVICE;
-import static android.provider.Settings.Global.AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS;
import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
@@ -39,9 +38,7 @@
import com.android.compatibility.common.util.RequiredFeatureRule;
import com.android.compatibility.common.util.RetryRule;
import com.android.compatibility.common.util.SafeCleanerRule;
-import com.android.compatibility.common.util.SettingsStateChangerRule;
import com.android.compatibility.common.util.SettingsStateKeeperRule;
-import com.android.compatibility.common.util.SettingsUtils;
import com.android.compatibility.common.util.TestNameUtils;
import org.junit.Before;
@@ -205,10 +202,11 @@
// mRetryRule should be closest to the main test as possible
.around(mRetryRule)
//
- // Augmented Autofill should be disabled by default
- .around(new SettingsStateChangerRule(sContext, SettingsUtils.NAMESPACE_GLOBAL,
- AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS,
- Integer.toString(getSmartSuggestionMode())))
+ // TODO(b/124006095): must use DeviceConfig rule
+// // Augmented Autofill should be disabled by default
+// .around(new SettingsStateChangerRule(sContext, SettingsUtils.NAMESPACE_GLOBAL,
+// AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS,
+// Integer.toString(getSmartSuggestionMode())))
//
// Finally, let subclasses add their own rules (like ActivityTestRule)
.around(getMainTestRule());
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutofillValueTest.java b/tests/autofillservice/src/android/autofillservice/cts/AutofillValueTest.java
index 3a0c294..cabdee3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutofillValueTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutofillValueTest.java
@@ -51,7 +51,7 @@
* redundant tests and add more tests (like triggering autofill using different views) to
* CheckoutActivityTest.
*/
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class AutofillValueTest
extends AutoFillServiceTestCase.AutoActivityLaunch<AllAutofillableViewsActivity> {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/BatchUpdatesTest.java b/tests/autofillservice/src/android/autofillservice/cts/BatchUpdatesTest.java
index 805db4e..73817f6 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/BatchUpdatesTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/BatchUpdatesTest.java
@@ -32,7 +32,7 @@
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class BatchUpdatesTest {
private final BatchUpdates.Builder mBuilder = new BatchUpdates.Builder();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CharSequenceTransformationTest.java b/tests/autofillservice/src/android/autofillservice/cts/CharSequenceTransformationTest.java
index 004928a..646aa61 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CharSequenceTransformationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CharSequenceTransformationTest.java
@@ -38,7 +38,7 @@
import java.util.regex.Pattern;
@RunWith(AndroidJUnit4.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class CharSequenceTransformationTest {
@Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CheckoutActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/CheckoutActivityTest.java
index ac181ec..dead535 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CheckoutActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CheckoutActivityTest.java
@@ -115,7 +115,7 @@
}
@Test
- @AppModeFull // testAutofill() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofill() is enough")
public void testAutofillDynamicAdapter() throws Exception {
// Set activity.
mActivity.onCcExpiration((v) -> v.setAdapter(new ArrayAdapter<String>(getContext(),
@@ -158,7 +158,7 @@
// TODO: this should be a pure unit test exercising onProvideAutofillStructure(),
// but that would require creating a custom ViewStructure.
@Test
- @AppModeFull // Unit test
+ @AppModeFull(reason = "Unit test")
public void testGetAutofillOptionsSorted() throws Exception {
// Set service.
enableService();
@@ -248,13 +248,13 @@
}
@Test
- @AppModeFull // Service-specific test
+ @AppModeFull(reason = "Service-specific test")
public void testCustomizedSaveUi() throws Exception {
customizedSaveUi(false);
}
@Test
- @AppModeFull // Service-specific test
+ @AppModeFull(reason = "Service-specific test")
public void testCustomizedSaveUiWithContentDescription() throws Exception {
customizedSaveUi(true);
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CompositeUserDataTest.java b/tests/autofillservice/src/android/autofillservice/cts/CompositeUserDataTest.java
index bb429d4..a00e0d3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CompositeUserDataTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CompositeUserDataTest.java
@@ -33,7 +33,7 @@
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class CompositeUserDataTest {
private final String mShortValue = Strings.repeat("k", UserData.getMinValueLength() - 1);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionDateTest.java b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionDateTest.java
index 49e772d..13896aa 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionDateTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionDateTest.java
@@ -37,7 +37,7 @@
import java.util.Calendar;
-@AppModeFull // Service-specific test
+@AppModeFull(reason = "Service-specific test")
public class CustomDescriptionDateTest
extends AutoFillServiceTestCase.AutoActivityLaunch<DatePickerSpinnerActivity> {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionTest.java b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionTest.java
index 2f48835..2abde4f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionTest.java
@@ -46,7 +46,7 @@
import java.util.function.BiFunction;
import java.util.regex.Pattern;
-@AppModeFull // Service-specific test
+@AppModeFull(reason = "Service-specific test")
public class CustomDescriptionTest extends AbstractLoginActivityTestCase {
/**
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionUnitTest.java b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionUnitTest.java
index 39f3a58..5b3f62d 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionUnitTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionUnitTest.java
@@ -38,7 +38,7 @@
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class CustomDescriptionUnitTest {
private final CustomDescription.Builder mBuilder =
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java b/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java
index 85e07ba..9a2138a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java
@@ -17,14 +17,27 @@
package android.autofillservice.cts;
import static android.autofillservice.cts.Helper.ID_USERNAME;
+import static android.autofillservice.cts.Timeouts.MOCK_IME_TIMEOUT_MS;
import static com.android.compatibility.common.util.ShellUtils.sendKeyEvent;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.editorMatcher;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectBindInput;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectCommand;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent;
import android.autofillservice.cts.CannedFillResponse.CannedDataset;
import android.content.IntentSender;
+import android.os.Process;
import android.platform.test.annotations.AppModeFull;
+import android.support.test.InstrumentationRegistry;
+import android.view.View;
import android.widget.EditText;
+import com.android.cts.mockime.ImeCommand;
+import com.android.cts.mockime.ImeEventStream;
+import com.android.cts.mockime.ImeSettings;
+import com.android.cts.mockime.MockImeSession;
+
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -103,7 +116,7 @@
}
@Test
- public void testFilter_usingKeyboard() throws Exception {
+ public void testFilter_injectingEvents() throws Exception {
final String aa = "Two A's";
final String ab = "A and B";
final String b = "Only B";
@@ -159,7 +172,78 @@
}
@Test
- @AppModeFull // testFilter() is enough to test ephemeral apps support
+ public void testFilter_usingKeyboard() throws Exception {
+ final String aa = "Two A's";
+ final String ab = "A and B";
+ final String b = "Only B";
+
+ enableService();
+
+ // Set expectations.
+ sReplier.addResponse(new CannedFillResponse.Builder()
+ .addDataset(new CannedDataset.Builder()
+ .setField(ID_USERNAME, "aa")
+ .setPresentation(createPresentation(aa))
+ .build())
+ .addDataset(new CannedDataset.Builder()
+ .setField(ID_USERNAME, "ab")
+ .setPresentation(createPresentation(ab))
+ .build())
+ .addDataset(new CannedDataset.Builder()
+ .setField(ID_USERNAME, "b")
+ .setPresentation(createPresentation(b))
+ .build())
+ .build());
+
+ final String marker = mActivity.getMarker();
+
+ try (MockImeSession mockImeSession = MockImeSession.create(
+ mContext, InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+ new ImeSettings.Builder())) {
+ final ImeEventStream stream = mockImeSession.openEventStream();
+
+ // Trigger auto-fill.
+ mActivity.onUsername(View::requestFocus);
+
+ // Wait until the MockIme gets bound to the TestActivity.
+ expectBindInput(stream, Process.myPid(), MOCK_IME_TIMEOUT_MS);
+ expectEvent(stream, editorMatcher("onStartInput", marker), MOCK_IME_TIMEOUT_MS);
+
+ sReplier.getNextFillRequest();
+
+ // With no filter text all datasets should be shown
+ mUiBot.assertDatasets(aa, ab, b);
+
+ // Only two datasets start with 'a'
+ final ImeCommand cmd1 = mockImeSession.callCommitText("a", 1);
+ expectCommand(stream, cmd1, MOCK_IME_TIMEOUT_MS);
+
+ mUiBot.assertDatasets(aa, ab);
+
+ // Only one dataset start with 'aa'
+ final ImeCommand cmd2 = mockImeSession.callCommitText("a", 1);
+ expectCommand(stream, cmd2, MOCK_IME_TIMEOUT_MS);
+
+ mUiBot.assertDatasets(aa);
+
+ // Only two datasets start with 'a'
+ sendKeyEvent("KEYCODE_DEL"); // TODO: add new method on MockIme for it
+ mUiBot.assertDatasets(aa, ab);
+ // With no filter text all datasets should be shown
+ sendKeyEvent("KEYCODE_DEL"); // TODO: add new method on MockIme for it
+ mUiBot.assertDatasets(aa, ab, b);
+
+ // No dataset start with 'aaa'
+ final MyAutofillCallback callback = mActivity.registerCallback();
+ final ImeCommand cmd3 = mockImeSession.callCommitText("aaa", 1);
+ expectCommand(stream, cmd3, MOCK_IME_TIMEOUT_MS);
+ callback.assertUiHiddenEvent(mActivity.getUsername());
+ mUiBot.assertNoDatasets();
+ }
+ }
+
+ @Test
+ @AppModeFull(reason = "testFilter() is enough")
public void testFilter_nullValuesAlwaysMatched() throws Exception {
final String aa = "Two A's";
final String ab = "A and B";
@@ -212,7 +296,7 @@
}
@Test
- @AppModeFull // testFilter() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testFilter() is enough")
public void testFilter_differentPrefixes() throws Exception {
final String a = "aaa";
final String b = "bra";
@@ -254,7 +338,7 @@
}
@Test
- @AppModeFull // testFilter() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testFilter() is enough")
public void testFilter_usingRegex() throws Exception {
// Dataset presentations.
final String aa = "Two A's";
@@ -310,7 +394,7 @@
}
@Test
- @AppModeFull // testFilter() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testFilter() is enough")
public void testFilter_disabledUsingNullRegex() throws Exception {
// Dataset presentations.
final String unfilterable = "Unfilterabled";
@@ -373,7 +457,7 @@
}
@Test
- @AppModeFull // testFilter() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testFilter() is enough")
public void testFilter_mixPlainAndRegex() throws Exception {
final String plain = "Plain";
final String regexPlain = "RegexPlain";
@@ -425,7 +509,7 @@
}
@Test
- @AppModeFull // testFilter_usingKeyboard() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testFilter_usingKeyboard() is enough")
public void testFilter_mixPlainAndRegex_usingKeyboard() throws Exception {
final String plain = "Plain";
final String regexPlain = "RegexPlain";
@@ -477,16 +561,19 @@
}
@Test
+ @AppModeFull(reason = "testFilter() is enough")
public void testFilter_resetFilter_chooseFirst() throws Exception {
resetFilterTest(1);
}
@Test
+ @AppModeFull(reason = "testFilter() is enough")
public void testFilter_resetFilter_chooseSecond() throws Exception {
resetFilterTest(2);
}
@Test
+ @AppModeFull(reason = "testFilter() is enough")
public void testFilter_resetFilter_chooseThird() throws Exception {
resetFilterTest(3);
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DatasetTest.java b/tests/autofillservice/src/android/autofillservice/cts/DatasetTest.java
index 2554a5b..5202f52 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DatasetTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DatasetTest.java
@@ -34,7 +34,7 @@
import java.util.regex.Pattern;
@RunWith(AndroidJUnit4.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class DatasetTest {
private final AutofillId mId = new AutofillId(42);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DatePickerCalendarActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/DatePickerCalendarActivityTest.java
index 35f3b73..decc4b7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DatePickerCalendarActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DatePickerCalendarActivityTest.java
@@ -18,7 +18,7 @@
import android.platform.test.annotations.AppModeFull;
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class DatePickerCalendarActivityTest extends DatePickerTestCase<DatePickerCalendarActivity> {
@Override
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DatePickerSpinnerActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/DatePickerSpinnerActivityTest.java
index 291d5aa..4b63e10 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DatePickerSpinnerActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DatePickerSpinnerActivityTest.java
@@ -18,7 +18,7 @@
import android.platform.test.annotations.AppModeFull;
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class DatePickerSpinnerActivityTest extends DatePickerTestCase<DatePickerSpinnerActivity> {
@Override
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DateTransformationTest.java b/tests/autofillservice/src/android/autofillservice/cts/DateTransformationTest.java
index 8f2d0ee..c6385ed 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DateTransformationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DateTransformationTest.java
@@ -39,7 +39,7 @@
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class DateTransformationTest {
@Mock private ValueFinder mValueFinder;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DateValueSanitizerTest.java b/tests/autofillservice/src/android/autofillservice/cts/DateValueSanitizerTest.java
index 6f59302..f30aaf0 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DateValueSanitizerTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DateValueSanitizerTest.java
@@ -34,7 +34,7 @@
import java.util.Date;
@RunWith(AndroidJUnit4.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class DateValueSanitizerTest {
private static final String TAG = "DateValueSanitizerTest";
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java b/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
index 77f5efd..49a43fe 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
@@ -207,7 +207,7 @@
}
@Test
- @AppModeFull // testDisableApp() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDisableApp() is enough")
public void testDisableAppThenWaitToReenableIt() throws Exception {
// Set service.
enableService();
@@ -233,7 +233,7 @@
}
@Test
- @AppModeFull // testDisableApp() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDisableApp() is enough")
public void testDisableAppThenResetServiceToReenableIt() throws Exception {
enableService();
sReplier.addResponse(new CannedFillResponse.Builder()
@@ -277,7 +277,7 @@
}
@Test
- @AppModeFull // testDisableActivity() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDisableActivity() is enough")
public void testDisableActivityThenWaitToReenableIt() throws Exception {
// Set service.
enableService();
@@ -306,7 +306,7 @@
}
@Test
- @AppModeFull // testDisableActivity() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testDisableActivity() is enough")
public void testDisableActivityThenResetServiceToReenableIt() throws Exception {
enableService();
sReplier.addResponse(new CannedFillResponse.Builder()
diff --git a/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java b/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java
index 5f81df2..20a184f 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java
@@ -44,7 +44,7 @@
import java.util.List;
-@AppModeFull // Service-specific test
+@AppModeFull(reason = "Service-specific test")
public class FieldsClassificationTest extends AbstractGridActivityTestCase {
@ClassRule
diff --git a/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java b/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java
index 2e1ae0d..2c6bfe5 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java
@@ -63,7 +63,7 @@
/**
* Test that uses {@link LoginActivity} to test {@link FillEventHistory}.
*/
-@AppModeFull // Service-specific test
+@AppModeFull(reason = "Service-specific test")
public class FillEventHistoryTest extends AbstractLoginActivityTestCase {
@Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/FillResponseTest.java b/tests/autofillservice/src/android/autofillservice/cts/FillResponseTest.java
index f0b7bad..adae5f7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/FillResponseTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/FillResponseTest.java
@@ -40,7 +40,7 @@
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class FillResponseTest {
private final AutofillId mAutofillId = new AutofillId(42);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/ImageTransformationTest.java b/tests/autofillservice/src/android/autofillservice/cts/ImageTransformationTest.java
index f0f5470..317c3fa 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/ImageTransformationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/ImageTransformationTest.java
@@ -37,7 +37,7 @@
import java.util.regex.Pattern;
@RunWith(AndroidJUnit4.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class ImageTransformationTest {
@Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/InitializedCheckoutActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/InitializedCheckoutActivityTest.java
index 974f0cc..43000cc 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/InitializedCheckoutActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/InitializedCheckoutActivityTest.java
@@ -35,7 +35,7 @@
/**
* Test case for an activity containing non-TextField views with initial values set on XML.
*/
-@AppModeFull // CheckoutActivityTest() is enough to test ephemeral apps support
+@AppModeFull(reason = "CheckoutActivityTest() is enough")
public class InitializedCheckoutActivityTest
extends AutoFillServiceTestCase.AutoActivityLaunch<InitializedCheckoutActivity> {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
index 939792c..4cebbb2 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
+import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
@@ -55,6 +56,8 @@
public static final String BACKDOOR_USERNAME = "LemmeIn";
public static final String BACKDOOR_PASSWORD_SUBSTRING = "pass";
+ private static final String TEST_MARKER_PREFIX = "android.autofillservice.cts.LoginActivity";
+
private LinearLayout mUsernameContainer;
private TextView mUsernameLabel;
private EditText mUsernameEditText;
@@ -71,6 +74,9 @@
private CountDownLatch mLoginLatch;
private String mLoginMessage;
+ private final String mTestMarker = TEST_MARKER_PREFIX + "/"
+ + SystemClock.elapsedRealtimeNanos();
+
/**
* Gets the expected welcome message for a given username.
*/
@@ -78,6 +84,13 @@
return String.format(WELCOME_TEMPLATE, username);
}
+ /**
+ * Gets the marker used on MockIME-based tests.
+ */
+ String getMarker() {
+ return mTestMarker;
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -90,6 +103,8 @@
mCancelButton = findViewById(R.id.cancel);
mUsernameLabel = findViewById(R.id.username_label);
mUsernameEditText = findViewById(R.id.username);
+ Log.d(TAG, "marker: " + mTestMarker);
+ mUsernameEditText.setPrivateImeOptions(mTestMarker);
mPasswordLabel = findViewById(R.id.password_label);
mPasswordEditText = findViewById(R.id.password);
mOutput = findViewById(R.id.output);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index 371a4a1..d5325f7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -134,13 +134,13 @@
}
@Test
- @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutoFillOneDataset() is enough")
public void testAutofillManuallyAfterServiceReturnedNoDatasets() throws Exception {
autofillAfterServiceReturnedNoDatasets(true);
}
@Test
- @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutoFillOneDataset() is enough")
public void testAutofillAutomaticallyAfterServiceReturnedNoDatasets() throws Exception {
autofillAfterServiceReturnedNoDatasets(false);
}
@@ -187,13 +187,13 @@
}
@Test
- @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutoFillOneDataset() is enough")
public void testAutofillManuallyAndSaveAfterServiceReturnedNoDatasets() throws Exception {
autofillAndSaveAfterServiceReturnedNoDatasets(true);
}
@Test
- @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutoFillOneDataset() is enough")
public void testAutofillAutomaticallyAndSaveAfterServiceReturnedNoDatasets() throws Exception {
autofillAndSaveAfterServiceReturnedNoDatasets(false);
}
@@ -227,7 +227,7 @@
* workflow was requested.
*/
@Test
- @AppModeFull // testAutoFillNoDatasets() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutoFillNoDatasets() is enough")
public void testMultipleIterationsAfterServiceReturnedNoDatasets() throws Exception {
// Set service.
enableService();
@@ -270,7 +270,7 @@
}
@Test
- @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillManuallyOneDataset() is enough")
public void testAutofillManuallyAlwaysCallServiceAgain() throws Exception {
// Set service.
enableService();
@@ -304,13 +304,13 @@
}
@Test
- @AppModeFull // testAutoFillOneDataset_withHeaderAndFooter() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDataset_withHeaderAndFooter() is enough")
public void testAutoFillOneDataset_withHeader() throws Exception {
autofillOneDatasetTest(BorderType.HEADER_ONLY);
}
@Test
- @AppModeFull // testAutoFillOneDataset_withHeaderAndFooter() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDataset_withHeaderAndFooter() is enough")
public void testAutoFillOneDataset_withFooter() throws Exception {
autofillOneDatasetTest(BorderType.FOOTER_ONLY);
}
@@ -382,6 +382,7 @@
@Test
+ @AppModeFull(reason = "testAutoFillOneDataset() is enough")
public void testAutofillAgainAfterOnFailure() throws Exception {
// Set service.
enableService();
@@ -501,7 +502,7 @@
}
@Test
- @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDataset() is enough")
public void testAutoFillTwoDatasetsSameNumberOfFields() throws Exception {
// Set service.
enableService();
@@ -540,13 +541,13 @@
}
@Test
- @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDataset() is enough")
public void testAutoFillTwoDatasetsUnevenNumberOfFieldsFillsAll() throws Exception {
autoFillTwoDatasetsUnevenNumberOfFieldsTest(true);
}
@Test
- @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDataset() is enough")
public void testAutoFillTwoDatasetsUnevenNumberOfFieldsFillsOne() throws Exception {
autoFillTwoDatasetsUnevenNumberOfFieldsTest(false);
}
@@ -598,7 +599,7 @@
}
@Test
- @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDataset() is enough")
public void testAutoFillDatasetWithoutFieldIsIgnored() throws Exception {
// Set service.
enableService();
@@ -792,7 +793,7 @@
}
@Test
- @AppModeFull // testAutofillCallbacks() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutofillCallbacks() is enough")
public void testAutofillCallbackDisabled() throws Exception {
// Set service.
disableService();
@@ -808,13 +809,13 @@
}
@Test
- @AppModeFull // testAutofillCallbacks() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutofillCallbacks() is enough")
public void testAutofillCallbackNoDatasets() throws Exception {
callbackUnavailableTest(NO_RESPONSE);
}
@Test
- @AppModeFull // testAutofillCallbacks() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutofillCallbacks() is enough")
public void testAutofillCallbackNoDatasetsButSaveInfo() throws Exception {
callbackUnavailableTest(new CannedFillResponse.Builder()
.setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_USERNAME, ID_PASSWORD)
@@ -1031,19 +1032,19 @@
}
@Test
- @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDataset() is enough")
public void testAutoFillMultipleDatasetsPickFirst() throws Exception {
multipleDatasetsTest(1);
}
@Test
- @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDataset() is enough")
public void testAutoFillMultipleDatasetsPickSecond() throws Exception {
multipleDatasetsTest(2);
}
@Test
- @AppModeFull // testAutoFillOneDataset() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDataset() is enough")
public void testAutoFillMultipleDatasetsPickThird() throws Exception {
multipleDatasetsTest(3);
}
@@ -1147,7 +1148,7 @@
* and password) and the dataset itself, and each dataset has the same number of fields.
*/
@Test
- @AppModeFull // testAutofillOneDatasetCustomPresentation() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutofillOneDatasetCustomPresentation() is enough")
public void testAutofillMultipleDatasetsCustomPresentations() throws Exception {
// Set service.
enableService();
@@ -1192,7 +1193,7 @@
* and password), and each dataset has the same number of fields.
*/
@Test
- @AppModeFull // testAutofillOneDatasetCustomPresentation() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutofillOneDatasetCustomPresentation() is enough")
public void testAutofillMultipleDatasetsCustomPresentationSameFields() throws Exception {
// Set service.
enableService();
@@ -1236,7 +1237,7 @@
* and password), but each dataset has a different number of fields.
*/
@Test
- @AppModeFull // testAutofillOneDatasetCustomPresentation() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutofillOneDatasetCustomPresentation() is enough")
public void testAutofillMultipleDatasetsCustomPresentationFirstDatasetMissingSecondField()
throws Exception {
// Set service.
@@ -1279,7 +1280,7 @@
* and password), but each dataset has a different number of fields.
*/
@Test
- @AppModeFull // testAutofillOneDatasetCustomPresentation() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutofillOneDatasetCustomPresentation() is enough")
public void testAutofillMultipleDatasetsCustomPresentationSecondDatasetMissingFirstField()
throws Exception {
// Set service.
@@ -1318,13 +1319,13 @@
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testSaveOnly() throws Exception {
saveOnlyTest(false);
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testSaveOnlyTriggeredManually() throws Exception {
saveOnlyTest(false);
}
@@ -1442,13 +1443,13 @@
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testSaveOnlyPreFilled() throws Exception {
saveOnlyTestPreFilled(false);
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testSaveOnlyTriggeredManuallyPreFilled() throws Exception {
saveOnlyTestPreFilled(true);
}
@@ -1507,7 +1508,7 @@
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testSaveOnlyTwoRequiredFieldsOnePrefilled() throws Exception {
enableService();
@@ -1554,7 +1555,7 @@
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testSaveOnlyOptionalField() throws Exception {
enableService();
@@ -1597,19 +1598,19 @@
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testSaveNoRequiredField_NoneFilled() throws Exception {
optionalOnlyTest(FilledFields.NONE);
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testSaveNoRequiredField_OneFilled() throws Exception {
optionalOnlyTest(FilledFields.USERNAME_ONLY);
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testSaveNoRequiredField_BothFilled() throws Exception {
optionalOnlyTest(FilledFields.BOTH);
}
@@ -1678,37 +1679,37 @@
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testGenericSave() throws Exception {
customizedSaveTest(SAVE_DATA_TYPE_GENERIC);
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testCustomizedSavePassword() throws Exception {
customizedSaveTest(SAVE_DATA_TYPE_PASSWORD);
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testCustomizedSaveAddress() throws Exception {
customizedSaveTest(SAVE_DATA_TYPE_ADDRESS);
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testCustomizedSaveCreditCard() throws Exception {
customizedSaveTest(SAVE_DATA_TYPE_CREDIT_CARD);
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testCustomizedSaveUsername() throws Exception {
customizedSaveTest(SAVE_DATA_TYPE_USERNAME);
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testCustomizedSaveEmailAddress() throws Exception {
customizedSaveTest(SAVE_DATA_TYPE_EMAIL_ADDRESS);
}
@@ -1797,7 +1798,7 @@
}
@Test
- @AppModeFull // Service-specific test
+ @AppModeFull(reason = "Service-specific test")
public void testDisableSelf() throws Exception {
enableService();
@@ -1904,7 +1905,7 @@
}
@Test
- @AppModeFull // Unit test
+ @AppModeFull(reason = "Unit test")
public void testGetTextInputType() throws Exception {
// Set service.
enableService();
@@ -1927,7 +1928,7 @@
}
@Test
- @AppModeFull // Unit test
+ @AppModeFull(reason = "Unit test")
public void testNoContainers() throws Exception {
// Set service.
enableService();
@@ -1995,6 +1996,7 @@
}
@Test
+ @AppModeFull(reason = "testAutoFillOneDataset() is enough")
public void testAutofillManuallyOneDatasetWhenClipboardFull() throws Exception {
// Set service.
enableService();
@@ -2031,13 +2033,13 @@
}
@Test
- @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillManuallyOneDataset() is enough")
public void testAutofillManuallyTwoDatasetsPickFirst() throws Exception {
autofillManuallyTwoDatasets(true);
}
@Test
- @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillManuallyOneDataset() is enough")
public void testAutofillManuallyTwoDatasetsPickSecond() throws Exception {
autofillManuallyTwoDatasets(false);
}
@@ -2081,7 +2083,7 @@
}
@Test
- @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillManuallyOneDataset() is enough")
public void testAutofillManuallyPartialField() throws Exception {
// Set service.
enableService();
@@ -2116,7 +2118,7 @@
}
@Test
- @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillManuallyOneDataset() is enough")
public void testAutofillManuallyAgainAfterAutomaticallyAutofilledBefore() throws Exception {
// Set service.
enableService();
@@ -2177,7 +2179,7 @@
}
@Test
- @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillManuallyOneDataset() is enough")
public void testAutofillManuallyAgainAfterManuallyAutofilledBefore() throws Exception {
// Set service.
enableService();
@@ -2450,13 +2452,13 @@
// TODO(b/70682223): add a new test to make sure service with BIND_AUTOFILL permission works
@Test
- @AppModeFull // Service-specific test
+ @AppModeFull(reason = "Service-specific test")
public void testServiceIsDisabledWhenNewServiceInfoIsInvalid() throws Exception {
serviceIsDisabledWhenNewServiceIsInvalid(BadAutofillService.SERVICE_NAME);
}
@Test
- @AppModeFull // Service-specific test
+ @AppModeFull(reason = "Service-specific test")
public void testServiceIsDisabledWhenNewServiceNameIsInvalid() throws Exception {
serviceIsDisabledWhenNewServiceIsInvalid("Y_U_NO_VALID");
}
@@ -2588,7 +2590,7 @@
}
@Test
- @AppModeFull // Unit test
+ @AppModeFull(reason = "Unit test")
public void testNewTextAttributes() throws Exception {
enableService();
sReplier.addResponse(NO_RESPONSE);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginWithStringsActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginWithStringsActivityTest.java
index bc8ed9f..e612161 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginWithStringsActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginWithStringsActivityTest.java
@@ -42,7 +42,7 @@
import org.junit.Test;
-@AppModeFull // LoginActivityTest is enough to test ephemeral apps support
+@AppModeFull(reason = "LoginActivityTest is enough")
public class LoginWithStringsActivityTest
extends AutoFillServiceTestCase.AutoActivityLaunch<LoginWithStringsActivity> {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LuhnChecksumValidatorTest.java b/tests/autofillservice/src/android/autofillservice/cts/LuhnChecksumValidatorTest.java
index 0da2208..590f1b9 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LuhnChecksumValidatorTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LuhnChecksumValidatorTest.java
@@ -32,7 +32,7 @@
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class LuhnChecksumValidatorTest {
@Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MultiScreenLoginTest.java b/tests/autofillservice/src/android/autofillservice/cts/MultiScreenLoginTest.java
index 3d042f1..eaf60ba 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/MultiScreenLoginTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/MultiScreenLoginTest.java
@@ -33,6 +33,7 @@
import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
import android.content.ComponentName;
import android.os.Bundle;
+import android.platform.test.annotations.AppModeFull;
import android.service.autofill.CharSequenceTransformation;
import android.service.autofill.SaveInfo;
import android.support.test.uiautomator.UiObject2;
@@ -47,6 +48,7 @@
/**
* Test case for the senario where a login screen is split in multiple activities.
*/
+@AppModeFull(reason = "Service-specific test")
public class MultiScreenLoginTest
extends AutoFillServiceTestCase.AutoActivityLaunch<UsernameOnlyActivity> {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivityTest.java
index d8b263a..885376a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/MultiWindowLoginActivityTest.java
@@ -41,7 +41,7 @@
import java.util.concurrent.TimeoutException;
-@AppModeFull // This test requires android.permission.MANAGE_ACTIVITY_STACKS
+@AppModeFull(reason = "This test requires android.permission.MANAGE_ACTIVITY_STACKS")
public class MultiWindowLoginActivityTest
extends AutoFillServiceTestCase.AutoActivityLaunch<MultiWindowLoginActivity> {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/OnClickActionTest.java b/tests/autofillservice/src/android/autofillservice/cts/OnClickActionTest.java
index a7918c9..0ebd0a4 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/OnClickActionTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/OnClickActionTest.java
@@ -46,7 +46,7 @@
/**
* Integration tests for the {@link OnClickAction} implementations.
*/
-@AppModeFull // Service-specific test
+@AppModeFull(reason = "Service-specific test")
public class OnClickActionTest
extends AutoFillServiceTestCase.AutoActivityLaunch<SimpleSaveActivity> {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivityTest.java
index fe49410..c9cec8b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/OptionalSaveActivityTest.java
@@ -46,7 +46,7 @@
* <li>Favorite Color: don't care - LOL
* </ul>
*/
-@AppModeFull // Service-specific test
+@AppModeFull(reason = "Service-specific test")
public class OptionalSaveActivityTest
extends AutoFillServiceTestCase.AutoActivityLaunch<OptionalSaveActivity> {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/PartitionedActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/PartitionedActivityTest.java
index 767c56d..6fd973e 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/PartitionedActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/PartitionedActivityTest.java
@@ -55,7 +55,7 @@
/**
* Test case for an activity containing multiple partitions.
*/
-@AppModeFull // Service-specific test
+@AppModeFull(reason = "Service-specific test")
public class PartitionedActivityTest extends AbstractGridActivityTestCase {
@Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/PreFilledLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/PreFilledLoginActivityTest.java
index c476722..fd392d5 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/PreFilledLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/PreFilledLoginActivityTest.java
@@ -35,7 +35,7 @@
/**
* Covers scenarios where the behavior is different because some fields were pre-filled.
*/
-@AppModeFull // LoginActivityTest is enough to test ephemeral apps support
+@AppModeFull(reason = "LoginActivityTest is enough")
public class PreFilledLoginActivityTest
extends AutoFillServiceTestCase.AutoActivityLaunch<PreFilledLoginActivity> {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/RegexValidatorTest.java b/tests/autofillservice/src/android/autofillservice/cts/RegexValidatorTest.java
index f0e68a6..cc26ec5 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/RegexValidatorTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/RegexValidatorTest.java
@@ -34,7 +34,7 @@
import java.util.regex.Pattern;
@RunWith(AndroidJUnit4.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class RegexValidatorTest {
@Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SaveInfoTest.java b/tests/autofillservice/src/android/autofillservice/cts/SaveInfoTest.java
index 1c009e9..4812574 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SaveInfoTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SaveInfoTest.java
@@ -36,7 +36,7 @@
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class SaveInfoTest {
private final AutofillId mId = new AutofillId(42);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/ServiceDisabledForSureTest.java b/tests/autofillservice/src/android/autofillservice/cts/ServiceDisabledForSureTest.java
index a27a5bd..2d5c722 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/ServiceDisabledForSureTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/ServiceDisabledForSureTest.java
@@ -22,6 +22,7 @@
import static com.google.common.truth.Truth.assertThat;
+import android.platform.test.annotations.AppModeFull;
import android.util.Log;
import android.view.autofill.AutofillManager;
@@ -31,6 +32,7 @@
/**
* Test case that guarantee the service is disabled before the activity launches.
*/
+@AppModeFull(reason = "Service-specific test")
public class ServiceDisabledForSureTest
extends AutoFillServiceTestCase.AutoActivityLaunch<OnCreateServiceStatusVerifierActivity> {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java b/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java
index b9bd41a..d93e3bde 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java
@@ -62,7 +62,7 @@
/**
* Test the lifecycle of a autofill session
*/
-@AppModeFull // This test requires android.permission.WRITE_EXTERNAL_STORAGE
+@AppModeFull(reason = "This test requires android.permission.WRITE_EXTERNAL_STORAGE")
public class SessionLifecycleTest extends AutoFillServiceTestCase.ManualActivityLaunch {
private static final String TAG = "SessionLifecycleTest";
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java b/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java
index 1ab9069..22ba3b9 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java
@@ -29,7 +29,7 @@
import org.junit.After;
import org.junit.Test;
-@AppModeFull // Service-specific test
+@AppModeFull(reason = "Service-specific test")
public class SettingsIntentTest
extends AutoFillServiceTestCase.AutoActivityLaunch<TrampolineForResultActivity> {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
index 93ff57b..cec472e 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
@@ -137,6 +137,7 @@
}
@Test
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testAutoFillOneDatasetAndSave_largeAssistStructure() throws Exception {
startActivity();
@@ -249,7 +250,7 @@
}
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testSave() throws Exception {
saveTest(false);
}
@@ -312,7 +313,7 @@
* Emulates an app dyanmically adding the password field after username is typed.
*/
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testPartitionedSave() throws Exception {
startActivity();
@@ -369,7 +370,7 @@
* Emulates an app using fragments to display username and password in 2 steps.
*/
@Test
- @AppModeFull // testAutoFillOneDatasetAndSave() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutoFillOneDatasetAndSave() is enough")
public void testDelayedSave() throws Exception {
startActivity();
@@ -941,7 +942,7 @@
}
@Test
- @AppModeFull // Service-specific test
+ @AppModeFull(reason = "Service-specific test")
public void testSelectedDatasetsAreSentOnSaveRequest() throws Exception {
startActivity();
@@ -1098,7 +1099,7 @@
}
@Test
- @AppModeFull // testSanitizeOnSaveWhenAppChangeValues() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testSanitizeOnSaveWhenAppChangeValues() is enough")
public void testSanitizeOnSaveNoChange() throws Exception {
startActivity();
@@ -1136,7 +1137,7 @@
}
@Test
- @AppModeFull // testSanitizeOnSaveWhenAppChangeValues() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testSanitizeOnSaveWhenAppChangeValues() is enough")
public void testDontSaveWhenSanitizedValueForRequiredFieldDidntChange() throws Exception {
startActivity();
@@ -1174,7 +1175,7 @@
}
@Test
- @AppModeFull // testSanitizeOnSaveWhenAppChangeValues() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testSanitizeOnSaveWhenAppChangeValues() is enough")
public void testDontSaveWhenSanitizedValueForOptionalFieldDidntChange() throws Exception {
startActivity();
@@ -1208,7 +1209,7 @@
}
@Test
- @AppModeFull // testSanitizeOnSaveWhenAppChangeValues() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testSanitizeOnSaveWhenAppChangeValues() is enough")
public void testDontSaveWhenRequiredFieldFailedSanitization() throws Exception {
startActivity();
@@ -1243,7 +1244,7 @@
}
@Test
- @AppModeFull // testSanitizeOnSaveWhenAppChangeValues() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testSanitizeOnSaveWhenAppChangeValues() is enough")
public void testDontSaveWhenOptionalFieldFailedSanitization() throws Exception {
startActivity();
@@ -1279,7 +1280,7 @@
}
@Test
- @AppModeFull // testSanitizeOnSaveWhenAppChangeValues() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testSanitizeOnSaveWhenAppChangeValues() is enough")
public void testDontSaveWhenInitialValueAndNoUserInputAndServiceDatasets() throws Throwable {
// Prepare activitiy.
startActivity();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/TextValueSanitizerTest.java b/tests/autofillservice/src/android/autofillservice/cts/TextValueSanitizerTest.java
index 2b6d5c6..1c9c246 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/TextValueSanitizerTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/TextValueSanitizerTest.java
@@ -31,7 +31,7 @@
import java.util.regex.Pattern;
@RunWith(AndroidJUnit4.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class TextValueSanitizerTest {
@Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/TimePickerClockActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/TimePickerClockActivityTest.java
index c7f3480..f07d994 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/TimePickerClockActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/TimePickerClockActivityTest.java
@@ -17,7 +17,7 @@
import android.platform.test.annotations.AppModeFull;
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class TimePickerClockActivityTest extends TimePickerTestCase<TimePickerClockActivity> {
@Override
diff --git a/tests/autofillservice/src/android/autofillservice/cts/TimePickerSpinnerActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/TimePickerSpinnerActivityTest.java
index a6ac44f..9245387 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/TimePickerSpinnerActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/TimePickerSpinnerActivityTest.java
@@ -17,7 +17,7 @@
import android.platform.test.annotations.AppModeFull;
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class TimePickerSpinnerActivityTest extends TimePickerTestCase<TimePickerSpinnerActivity> {
@Override
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java b/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java
index b65b91b..44027ef 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Timeouts.java
@@ -26,6 +26,8 @@
private static final long ONE_TIMEOUT_TO_RULE_THEN_ALL_MS = 20_000;
private static final long ONE_NAPTIME_TO_RULE_THEN_ALL_MS = 2_000;
+ static final long MOCK_IME_TIMEOUT_MS = 5_000;
+
/**
* Timeout until framework binds / unbinds from service.
*/
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java b/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java
index e0c2894..d0a675a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java
@@ -42,7 +42,7 @@
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class UserDataTest {
private static final Context sContext = InstrumentationRegistry.getContext();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/ValidatorTest.java b/tests/autofillservice/src/android/autofillservice/cts/ValidatorTest.java
index 85c6737..522fd98 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/ValidatorTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/ValidatorTest.java
@@ -37,7 +37,7 @@
/**
* Simple integration test to verify that the UI is only shown if the validator passes.
*/
-@AppModeFull // Service-specific test
+@AppModeFull(reason = "Service-specific test")
public class ValidatorTest extends AbstractLoginActivityTestCase {
@Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/ValidatorsTest.java b/tests/autofillservice/src/android/autofillservice/cts/ValidatorsTest.java
index bb4561b..63e2e3c 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/ValidatorsTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/ValidatorsTest.java
@@ -38,7 +38,7 @@
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class ValidatorsTest {
@Mock private Validator mInvalidValidator;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/ViewAttributesTest.java b/tests/autofillservice/src/android/autofillservice/cts/ViewAttributesTest.java
index 8c88928..5b9c646 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/ViewAttributesTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/ViewAttributesTest.java
@@ -37,7 +37,7 @@
import java.util.function.Consumer;
@RunWith(AndroidJUnit4.class)
-@AppModeFull // Unit test
+@AppModeFull(reason = "Unit test")
public class ViewAttributesTest
extends AutoFillServiceTestCase.AutoActivityLaunch<ViewAttributesTestActivity> {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java
index 72688f6..af21337 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityCompatModeTest.java
@@ -121,7 +121,7 @@
}
@Test
- @AppModeFull // testMultipleUrlBars_firstDoesNotExist() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testMultipleUrlBars_firstDoesNotExist() is enough")
public void testMultipleUrlBars_bothExist() throws Exception {
SettingsUtils.syncSet(sContext, NAMESPACE_GLOBAL, AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES,
SERVICE_PACKAGE + "[my_url_bar,my_url_bar2]");
@@ -148,7 +148,7 @@
}
@Test
- @AppModeFull // testMultipleUrlBars_firstDoesNotExist() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testMultipleUrlBars_firstDoesNotExist() is enough")
public void testFocusOnUrlBarIsIgnored() throws Throwable {
// Set service.
enableService();
@@ -170,7 +170,7 @@
}
@Test
- @AppModeFull // testMultipleUrlBars_firstDoesNotExist() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testMultipleUrlBars_firstDoesNotExist() is enough")
public void testUrlBarChangeIgnoredWhenServiceCanSave() throws Throwable {
// Set service.
enableService();
@@ -223,7 +223,7 @@
}
@Test
- @AppModeFull // testMultipleUrlBars_firstDoesNotExist() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testMultipleUrlBars_firstDoesNotExist() is enough")
public void testUrlBarChangeCancelSessionWhenServiceCannotSave() throws Throwable {
// Set service.
enableService();
@@ -263,7 +263,7 @@
}
@Test
- @AppModeFull // testMultipleUrlBars_firstDoesNotExist() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testMultipleUrlBars_firstDoesNotExist() is enough")
public void testUrlBarChangeCancelSessionWhenServiceReturnsNullResponse() throws Throwable {
// Set service.
enableService();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
index 07557bf..8cd9a67 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
@@ -113,7 +113,7 @@
}
@Test
- @AppModeFull // testAutofillSync() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillSync() is enough")
public void testAutofillAsync() throws Exception {
skipTestOnCompatMode();
@@ -251,7 +251,7 @@
}
@Test
- @AppModeFull // testAutofillSync() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillSync() is enough")
public void testAutofillTwoDatasets() throws Exception {
// Set service.
enableService();
@@ -324,13 +324,13 @@
}
@Test
- @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillManuallyOneDataset() is enough")
public void testAutofillManuallyTwoDatasetsPickFirst() throws Exception {
autofillManuallyTwoDatasets(true);
}
@Test
- @AppModeFull // testAutofillManuallyOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillManuallyOneDataset() is enough")
public void testAutofillManuallyTwoDatasetsPickSecond() throws Exception {
autofillManuallyTwoDatasets(false);
}
@@ -402,7 +402,7 @@
}
@Test
- @AppModeFull // testAutofillCallbacks() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillCallbacks() is enough")
public void testAutofillCallbackDisabled() throws Throwable {
// Set service.
disableService();
@@ -416,7 +416,7 @@
}
@Test
- @AppModeFull // testAutofillCallbacks() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillCallbacks() is enough")
public void testAutofillCallbackNoDatasets() throws Throwable {
// Set service.
enableService();
@@ -437,7 +437,7 @@
}
@Test
- @AppModeFull // testAutofillCallbacks() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillCallbacks() is enough")
public void testAutofillCallbackNoDatasetsButSaveInfo() throws Throwable {
// Set service.
enableService();
@@ -628,7 +628,7 @@
}
@Test
- @AppModeFull // testSaveNotShown_noUserInput() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testSaveNotShown_noUserInput() is enough")
public void testSaveNotShown_initialValues_noUserInput() throws Throwable {
// Prepare activitiy.
mActivity.mUsername.setText("foo");
@@ -653,7 +653,7 @@
}
@Test
- @AppModeFull // testSaveNotShown_noUserInput() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testSaveNotShown_noUserInput() is enough")
public void testSaveNotShown_initialValues_noUserInput_serviceDatasets() throws Throwable {
// Prepare activitiy.
mActivity.mUsername.setText("foo");
@@ -684,7 +684,7 @@
}
@Test
- @AppModeFull // testSaveNotShown_noUserInput() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testSaveNotShown_noUserInput() is enough")
public void testSaveNotShown_userInputMatchesDatasets() throws Throwable {
// Prepare activitiy.
mActivity.mUsername.setText("foo");
diff --git a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
index 4712413..637d8b4 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
@@ -67,7 +67,7 @@
}
@Test
- @AppModeFull // testAutofillOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillOneDataset() is enough")
public void testAutofillNoDatasets() throws Exception {
// Set service.
enableService();
@@ -93,7 +93,7 @@
@Ignore("blocked on b/74793485")
@Test
- @AppModeFull // testAutofillOneDataset() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillOneDataset() is enough")
public void testAutofillOneDataset_usingAppContext() throws Exception {
autofillOneDatasetTest(true);
}
@@ -297,7 +297,7 @@
}
@Test
- @AppModeFull // testAutofillAndSave() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillAndSave() is enough")
public void testAutofillAndSave_withExternalViews_loadWebViewFirst() throws Exception {
// Set service.
enableService();
@@ -423,7 +423,7 @@
@Test
@Ignore("blocked on b/69461853")
- @AppModeFull // testAutofillAndSave() is enough to test ephemeral apps support
+ @AppModeFull(reason = "testAutofillAndSave() is enough")
public void testAutofillAndSave_withExternalViews_loadExternalViewsFirst() throws Exception {
// Set service.
enableService();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
index a4d189f..9deb6ed 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
@@ -26,6 +26,7 @@
import android.autofillservice.cts.LoginActivity;
import android.autofillservice.cts.OneTimeCancellationSignalListener;
import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.AugmentedFillRequest;
+import android.platform.test.annotations.AppModeFull;
import android.support.test.uiautomator.UiObject2;
import android.view.View;
import android.view.autofill.AutofillId;
@@ -52,6 +53,7 @@
}
@Test
+ @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
public void testAutoFill_neitherServiceCanAutofill() throws Exception {
// Set services
enableService();
@@ -118,6 +120,7 @@
}
@Test
+ @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
public void testAutoFill_mainServiceReturnedNull_augmentedAutofillTwoFields() throws Exception {
// Set services
enableService();
@@ -158,6 +161,7 @@
@Ignore("blocked on b/122728762")
@Test
+ @AppModeFull(reason = "testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField enough")
public void testCancellationSignalCalledAfterTimeout() throws Exception {
// Set services
enableService();
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CanaryTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CanaryTest.java
index e512d1d..56839e2 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CanaryTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CanaryTest.java
@@ -26,6 +26,7 @@
import android.provider.DeviceConfig;
import android.text.TextUtils;
import android.util.Log;
+import android.view.contentcapture.ContentCaptureManager;
import com.android.compatibility.common.util.RequiredServiceRule;
@@ -49,8 +50,8 @@
public void assertHasService() {
final String serviceName = getInternalString(RESOURCE_STRING_SERVICE_NAME);
final String enableSettings = DeviceConfig.getProperty(
- DeviceConfig.ContentCapture.NAMESPACE,
- DeviceConfig.ContentCapture.PROPERTY_CONTENTCAPTURE_ENABLED);
+ DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ ContentCaptureManager.DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED);
final boolean hasService = RequiredServiceRule.hasService(SYSTEM_SERVICE_NAME);
Log.d(TAG, "Service resource: '" + serviceName + "' Settings: '" + enableSettings
+ "' Has '" + SYSTEM_SERVICE_NAME + "': " + hasService);
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
index d9364ca..25928cd 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
@@ -45,6 +45,7 @@
import android.net.Uri;
import android.os.SystemClock;
import android.platform.test.annotations.AppModeFull;
+import android.provider.DeviceConfig;
import android.support.test.rule.ActivityTestRule;
import android.util.Log;
import android.view.View;
@@ -58,6 +59,7 @@
import android.widget.TextView;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import org.junit.After;
import org.junit.Before;
@@ -921,6 +923,28 @@
* - etc
*/
+ private enum DisabledReason {
+ BY_API,
+ BY_SETTINGS,
+ BY_DEVICE_CONFIG
+ }
+
+ private void setFeatureEnabled(@NonNull ContentCaptureManager mgr,
+ @NonNull DisabledReason reason, boolean enabled) {
+ switch (reason) {
+ case BY_API:
+ mgr.setContentCaptureFeatureEnabled(enabled);
+ break;
+ case BY_SETTINGS:
+ setFeatureEnabled(Boolean.toString(enabled));
+ break;
+ case BY_DEVICE_CONFIG:
+ setFeatureEnabledByDeviceConfig(Boolean.toString(enabled));
+ break;
+ default:
+ throw new IllegalArgumentException("invalid reason: " + reason);
+ }
+ }
@Test
public void testIsContentCaptureFeatureEnabled_notService() throws Exception {
final ContentCaptureManager mgr = getContentCaptureManagerHack();
@@ -929,21 +953,18 @@
@Test
public void testSetContentCaptureFeatureEnabled_disabledBySettings() throws Exception {
- setContentCaptureFeatureEnabledTest_disabled(/* bySettings= */ true);
+ setContentCaptureFeatureEnabledTest_disabled(DisabledReason.BY_SETTINGS);
}
- private void setContentCaptureFeatureEnabledTest_disabled(boolean bySettings) throws Exception {
+ private void setContentCaptureFeatureEnabledTest_disabled(@NonNull DisabledReason reason)
+ throws Exception {
final ContentCaptureManager mgr = getContentCaptureManagerHack();
final CtsContentCaptureService service = enableService();
assertThat(mgr.isContentCaptureFeatureEnabled()).isTrue();
final DisconnectListener disconnectedListener = service.setOnDisconnectListener();
- if (bySettings) {
- setFeatureEnabled("false");
- } else {
- mgr.setContentCaptureFeatureEnabled(false);
- }
+ setFeatureEnabled(mgr, reason, /* enabled= */ false);
disconnectedListener.waitForOnDisconnected();
assertThat(mgr.isContentCaptureFeatureEnabled()).isFalse();
@@ -962,22 +983,18 @@
@Test
public void testSetContentCaptureFeatureEnabled_disabledThenReEnabledBySettings()
throws Exception {
- setContentCaptureFeatureEnabledTest_disabledThenReEnabled(/* bySettings= */ true);
+ setContentCaptureFeatureEnabledTest_disabledThenReEnabled(DisabledReason.BY_SETTINGS);
}
- private void setContentCaptureFeatureEnabledTest_disabledThenReEnabled(boolean bySettings)
- throws Exception {
+ private void setContentCaptureFeatureEnabledTest_disabledThenReEnabled(
+ @NonNull DisabledReason reason) throws Exception {
final ContentCaptureManager mgr = getContentCaptureManagerHack();
final CtsContentCaptureService service1 = enableService();
assertThat(mgr.isContentCaptureFeatureEnabled()).isTrue();
final DisconnectListener disconnectedListener = service1.setOnDisconnectListener();
- if (bySettings) {
- setFeatureEnabled("false");
- } else {
- mgr.setContentCaptureFeatureEnabled(false);
- }
+ setFeatureEnabled(mgr, reason, /* enabled= */ false);
disconnectedListener.waitForOnDisconnected();
assertThat(mgr.isContentCaptureFeatureEnabled()).isFalse();
@@ -992,11 +1009,7 @@
// Re-enable feature
final ServiceWatcher reconnectionWatcher = CtsContentCaptureService.setServiceWatcher();
- if (bySettings) {
- setFeatureEnabled("true");
- } else {
- mgr.setContentCaptureFeatureEnabled(true);
- }
+ setFeatureEnabled(mgr, reason, /* enabled= */ true);
final CtsContentCaptureService service2 = reconnectionWatcher.waitOnCreate();
assertThat(mgr.isContentCaptureFeatureEnabled()).isTrue();
@@ -1022,13 +1035,30 @@
@Test
public void testSetContentCaptureFeatureEnabled_disabledByApi() throws Exception {
- setContentCaptureFeatureEnabledTest_disabled(/* bySettings= */ false);
+ setContentCaptureFeatureEnabledTest_disabled(DisabledReason.BY_API);
}
@Test
public void testSetContentCaptureFeatureEnabled_disabledThenReEnabledByApi()
throws Exception {
- setContentCaptureFeatureEnabledTest_disabledThenReEnabled(/* bySettings= */ false);
+ setContentCaptureFeatureEnabledTest_disabledThenReEnabled(DisabledReason.BY_API);
+ }
+
+ @Test
+ public void testSetContentCaptureFeatureEnabled_disabledByDeviceConfig() throws Exception {
+ setContentCaptureFeatureEnabledTest_disabled(DisabledReason.BY_DEVICE_CONFIG);
+ // Reset service, otherwise it will reconnect when the deviceConfig value is reset
+ // on cleanup, which will cause the test to fail
+ Helper.resetService();
+ }
+
+ @Test
+ public void testSetContentCaptureFeatureEnabled_disabledThenReEnabledByDeviceConfig()
+ throws Exception {
+ setContentCaptureFeatureEnabledTest_disabledThenReEnabled(DisabledReason.BY_DEVICE_CONFIG);
+ // Reset service, otherwise it will reconnect when the deviceConfig value is reset
+ // on cleanup, which will cause the test to fail
+ Helper.resetService();
}
// TODO(b/123406031): add tests that mix feature_enabled with user_restriction_enabled (and
@@ -1085,4 +1115,34 @@
return mgr;
}
+
+ // TODO(b/124006095): should use a @Rule instead
+ private String mEnabledBefore;
+ @Before
+ public void saveDeviceConfig() {
+ mEnabledBefore = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ ContentCaptureManager.DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED);
+ Log.d(TAG, "@Before saveDeviceConfig(): " + mEnabledBefore);
+
+ setFeatureEnabledByDeviceConfig(null);
+
+ }
+ @After
+ // TODO(b/124006095): should use a @Rule instead
+ public void restoreDeviceConfig() {
+ Log.d(TAG, "@After restoreDeviceConfig(): " + mEnabledBefore);
+ setFeatureEnabledByDeviceConfig(mEnabledBefore);
+
+ }
+ // TODO(b/124006095): should use a DeviceConfigUtils instead
+ private void setFeatureEnabledByDeviceConfig(@Nullable String value) {
+ Log.d(TAG, "setFeatureEnabledByDeviceConfig(): " + value);
+
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ ContentCaptureManager.DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED,
+ value, /* makeDefault= */ false);
+
+ android.os.SystemClock.sleep(1000); // Wait a little bit since we're not using a listener
+ }
+
}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/README.txt b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/README.txt
deleted file mode 100644
index 2cdbf75..0000000
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This package contains utilities that are not tied to Content Capture and might eventually move to
-a common CTS package.
\ No newline at end of file
diff --git a/tests/fragment/AndroidTest.xml b/tests/fragment/AndroidTest.xml
index ed97400..902b754 100644
--- a/tests/fragment/AndroidTest.xml
+++ b/tests/fragment/AndroidTest.xml
@@ -17,6 +17,7 @@
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="uitoolkit" />
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsFragmentTestCases.apk" />
diff --git a/tests/fragment/sdk26/AndroidTest.xml b/tests/fragment/sdk26/AndroidTest.xml
index 16ffd27..baad0aa 100644
--- a/tests/fragment/sdk26/AndroidTest.xml
+++ b/tests/fragment/sdk26/AndroidTest.xml
@@ -17,6 +17,7 @@
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="uitoolkit" />
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsFragmentTestCasesSdk26.apk" />
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityAndWindowManagerOverrideConfigTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityAndWindowManagerOverrideConfigTests.java
index 7d32409..201495e 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityAndWindowManagerOverrideConfigTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityAndWindowManagerOverrideConfigTests.java
@@ -23,6 +23,7 @@
import static org.junit.Assume.assumeTrue;
+import android.platform.test.annotations.Presubmit;
import android.server.am.CommandSession.ActivityCallback;
import org.junit.Test;
@@ -31,6 +32,7 @@
* Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:ActivityAndWindowManagerOverrideConfigTests
*/
+@Presubmit
public class ActivityAndWindowManagerOverrideConfigTests extends ActivityManagerTestBase {
@Test
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAmProfileTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAmProfileTests.java
index 74f4546..da5c3fc 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAmProfileTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAmProfileTests.java
@@ -27,6 +27,7 @@
import android.content.ComponentName;
+import android.platform.test.annotations.Presubmit;
import org.junit.Test;
/**
@@ -35,6 +36,7 @@
*
* Please talk to Android Studio team first if you want to modify or delete these tests.
*/
+@Presubmit
public class ActivityManagerAmProfileTests extends ActivityManagerTestBase {
private static final String OUTPUT_FILE_PATH = "/data/local/tmp/profile.trace";
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerConfigChangeTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerConfigChangeTests.java
index 80e16e2..b7a399b 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerConfigChangeTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerConfigChangeTests.java
@@ -58,6 +58,7 @@
* Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:ActivityManagerConfigChangeTests
*/
+@Presubmit
public class ActivityManagerConfigChangeTests extends ActivityManagerTestBase {
private static final float EXPECTED_FONT_SIZE_SP = 10.0f;
@@ -102,7 +103,6 @@
}
@FlakyTest(bugId = 73701185)
- @Presubmit
@Test
public void testChangeFontScaleRelaunch() throws Exception {
// Should relaunch and receive no onConfigurationChanged()
@@ -110,7 +110,6 @@
}
@FlakyTest(bugId = 73812451)
- @Presubmit
@Test
public void testChangeFontScaleNoRelaunch() throws Exception {
// Should receive onConfigurationChanged() and no relaunch
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayKeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayKeyguardTests.java
index 7416460..6b3df7c 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayKeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayKeyguardTests.java
@@ -24,6 +24,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assume.assumeTrue;
+import android.platform.test.annotations.Presubmit;
import android.server.am.ActivityManagerState.ActivityDisplay;
import org.junit.Before;
@@ -35,6 +36,7 @@
* <p>Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:ActivityManagerDisplayKeyguardTests
*/
+@Presubmit
public class ActivityManagerDisplayKeyguardTests extends ActivityManagerDisplayTestBase {
@Before
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java
index bc6171a..2d59191 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java
@@ -26,6 +26,7 @@
import static org.junit.Assume.assumeTrue;
+import android.platform.test.annotations.Presubmit;
import android.server.am.ActivityManagerState.ActivityDisplay;
import org.junit.Before;
@@ -37,6 +38,7 @@
* <p>Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:ActivityManagerDisplayLockedKeyguardTests
*/
+@Presubmit
public class ActivityManagerDisplayLockedKeyguardTests extends ActivityManagerDisplayTestBase {
@Before
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerFreeformStackTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerFreeformStackTests.java
index 0d4ed6e..47108de 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerFreeformStackTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerFreeformStackTests.java
@@ -26,6 +26,7 @@
import static org.junit.Assert.assertEquals;
import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
import android.server.am.ActivityManagerState.ActivityStack;
import android.server.am.ActivityManagerState.ActivityTask;
import android.view.Display;
@@ -36,6 +37,7 @@
* Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:ActivityManagerFreeformStackTests
*/
+@Presubmit
public class ActivityManagerFreeformStackTests extends ActivityManagerDisplayTestBase {
private static final int TEST_TASK_OFFSET = 20;
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerGetConfigTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerGetConfigTests.java
index a6d5b57..042d15f 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerGetConfigTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerGetConfigTests.java
@@ -38,6 +38,7 @@
import android.os.Build;
import android.os.LocaleList;
import android.os.ParcelFileDescriptor;
+import android.platform.test.annotations.Presubmit;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Display;
@@ -64,6 +65,7 @@
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
+@Presubmit
public class ActivityManagerGetConfigTests {
Context mContext;
ActivityManager mAm;
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerReplaceWindowTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerReplaceWindowTests.java
index 420ebd05..c62e71f 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerReplaceWindowTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerReplaceWindowTests.java
@@ -28,6 +28,7 @@
import android.content.ComponentName;
import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
import org.junit.Before;
import org.junit.Test;
@@ -38,6 +39,7 @@
* Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:ActivityManagerReplaceWindowTests
*/
+@Presubmit
public class ActivityManagerReplaceWindowTests extends ActivityManagerTestBase {
@Before
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerVrDisplayTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerVrDisplayTests.java
index 589302a..6dbcaa9 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerVrDisplayTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerVrDisplayTests.java
@@ -30,6 +30,7 @@
import android.annotation.NonNull;
import android.content.ComponentName;
+import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.server.am.ActivityManagerState.ActivityDisplay;
import android.server.am.settings.SettingsSession;
@@ -44,6 +45,7 @@
* Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:ActivityManagerVrDisplayTests
*/
+@Presubmit
public class ActivityManagerVrDisplayTests extends ActivityManagerDisplayTestBase {
private static final int VR_VIRTUAL_DISPLAY_WIDTH = 700;
private static final int VR_VIRTUAL_DISPLAY_HEIGHT = 900;
diff --git a/tests/framework/base/activitymanager/src/android/server/am/DeprecatedTargetSdkTest.java b/tests/framework/base/activitymanager/src/android/server/am/DeprecatedTargetSdkTest.java
index ed9bc11..54a1562 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/DeprecatedTargetSdkTest.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/DeprecatedTargetSdkTest.java
@@ -19,6 +19,7 @@
import static android.server.am.UiDeviceUtils.pressBackButton;
import static android.server.am.deprecatedsdk.Components.MAIN_ACTIVITY;
+import android.platform.test.annotations.Presubmit;
import org.junit.After;
import org.junit.Test;
@@ -28,6 +29,7 @@
* <p>Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:DeprecatedTargetSdkTest
*/
+@Presubmit
public class DeprecatedTargetSdkTest extends ActivityManagerTestBase {
/** @see com.android.server.wm.DeprecatedTargetSdkVersionDialog */
diff --git a/tests/framework/base/activitymanager/src/android/server/am/DisplaySizeTest.java b/tests/framework/base/activitymanager/src/android/server/am/DisplaySizeTest.java
index f69a949..aa07257 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/DisplaySizeTest.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/DisplaySizeTest.java
@@ -28,6 +28,7 @@
import android.os.Build;
+import android.platform.test.annotations.Presubmit;
import org.junit.After;
import org.junit.Test;
@@ -38,6 +39,7 @@
* <p>Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:DisplaySizeTest
*/
+@Presubmit
public class DisplaySizeTest extends ActivityManagerTestBase {
/** @see com.android.server.am.UnsupportedDisplaySizeDialog */
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTransitionTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTransitionTests.java
index 427a2a0..7757076 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTransitionTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTransitionTests.java
@@ -33,6 +33,7 @@
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
+import android.platform.test.annotations.Presubmit;
import org.junit.Before;
import org.junit.Test;
@@ -40,6 +41,7 @@
* Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:KeyguardTransitionTests
*/
+@Presubmit
public class KeyguardTransitionTests extends ActivityManagerTestBase {
@Before
diff --git a/tests/framework/base/activitymanager/src/android/server/am/PrereleaseSdkTest.java b/tests/framework/base/activitymanager/src/android/server/am/PrereleaseSdkTest.java
index b7703a8..71803f3 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/PrereleaseSdkTest.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/PrereleaseSdkTest.java
@@ -19,6 +19,7 @@
import static android.server.am.UiDeviceUtils.pressBackButton;
import static android.server.am.prerelease.Components.MAIN_ACTIVITY;
+import android.platform.test.annotations.Presubmit;
import com.android.compatibility.common.util.SystemUtil;
import org.junit.After;
@@ -31,6 +32,7 @@
* <p>Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:PrereleaseSdkTest
*/
+@Presubmit
public class PrereleaseSdkTest extends ActivityManagerTestBase {
/** @see com.android.server.wm.UnsupportedCompileSdkDialog */
diff --git a/tests/framework/base/activitymanager/src/android/server/am/SplashscreenTests.java b/tests/framework/base/activitymanager/src/android/server/am/SplashscreenTests.java
index bf7a812..539e0f8 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/SplashscreenTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/SplashscreenTests.java
@@ -27,12 +27,14 @@
import android.graphics.Color;
import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
import org.junit.Test;
/**
* Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:SplashscreenTests
*/
+@Presubmit
public class SplashscreenTests extends ActivityManagerTestBase {
@Test
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
index 328d27e..c568d19 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
@@ -148,7 +148,8 @@
* Blocking call that will wait for activities to reach expected states with timeout.
*/
@SafeVarargs
- final void waitAndAssertActivityStates(Pair<Activity, ActivityCallback>... activityCallbacks) {
+ final void waitAndAssertActivityStates(
+ Pair<Class<? extends Activity>, ActivityCallback>... activityCallbacks) {
log("Start waitAndAssertActivityCallbacks");
mLifecycleTracker.waitAndAssertActivityStates(activityCallbacks);
}
@@ -181,15 +182,16 @@
return mLifecycleLog;
}
- static Pair<Activity, ActivityCallback> state(Activity activity, ActivityCallback stage) {
- return new Pair<>(activity, stage);
+ static Pair<Class<? extends Activity>, ActivityCallback> state(Activity activity,
+ ActivityCallback stage) {
+ return new Pair<>(activity.getClass(), stage);
}
/**
* Returns a pair of the activity and the state it should be in based on the configuration of
* occludingActivity.
*/
- static Pair<Activity, ActivityCallback> occludedActivityState(
+ static Pair<Class<? extends Activity>, ActivityCallback> occludedActivityState(
Activity activity, Activity occludingActivity) {
return occludedActivityState(activity, isTranslucent(occludingActivity));
}
@@ -198,11 +200,11 @@
* Returns a pair of the activity and the state it should be in based on
* occludingActivityIsTranslucent.
*/
- static Pair<Activity, ActivityCallback> occludedActivityState(
+ static Pair<Class<? extends Activity>, ActivityCallback> occludedActivityState(
Activity activity, boolean occludingActivityIsTranslucent) {
// Activities behind a translucent activity should be in the paused state since they are
// still visible. Otherwise, they should be in the stopped state.
- return new Pair<>(activity, occludedActivityState(occludingActivityIsTranslucent));
+ return state(activity, occludedActivityState(occludingActivityIsTranslucent));
}
static ActivityCallback occludedActivityState(boolean occludingActivityIsTranslucent) {
@@ -352,4 +354,15 @@
static ComponentName getComponentName(Class<? extends Activity> activity) {
return new ComponentName(getInstrumentation().getContext(), activity);
}
+
+ void moveTaskToPrimarySplitScreenAndVerify(Activity activity) {
+ getLifecycleLog().clear();
+
+ moveTaskToPrimarySplitScreen(activity.getTaskId());
+
+ final Class<? extends Activity> activityClass = activity.getClass();
+ waitAndAssertActivityTransitions(activityClass,
+ LifecycleVerifier.getSplitScreenTransitionSequence(activityClass),
+ "enterSplitScreen");
+ }
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java
index 044f5bc..bab51ac 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java
@@ -77,10 +77,8 @@
// Wait and assert resume
waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_RESUMED,
"Activity should be resumed after launch");
- LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog(),
- false /* includeCallbacks */);
- LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
- true /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog());
}
@Test
@@ -112,14 +110,10 @@
waitAndAssertActivityState(getComponentName(ThirdActivity.class), STATE_RESUMED, message);
// Assert lifecycle
- LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog(),
- false /* includeCallbacks */);
- LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog(),
- false /* includeCallbacks */);
- LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog(),
- false /* includeCallbacks */);
- LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
- true /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog());
}
@Test
@@ -152,12 +146,9 @@
// Assert lifecycle
LifecycleVerifier.assertLaunchAndStopSequence(FirstActivity.class, getLifecycleLog());
- LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog(),
- false /* includeCallbacks */);
- LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog(),
- false /* includeCallbacks */);
- LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
- true /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog());
// Finish the activity that was occluding the first one
getLifecycleLog().clear();
@@ -213,12 +204,9 @@
// Assert lifecycle
LifecycleVerifier.assertLaunchAndPauseSequence(FirstActivity.class, getLifecycleLog());
- LifecycleVerifier.assertLaunchSequence(TranslucentActivity.class, getLifecycleLog(),
- false /* includeCallbacks */);
- LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog(),
- false /* includeCallbacks */);
- LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
- true /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(TranslucentActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog());
// Finish the activity that was occluding the first one
getLifecycleLog().clear();
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
index 00138cf..ab99a58 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
@@ -91,7 +91,7 @@
waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
// Enter split screen
- moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
+ moveTaskToPrimarySplitScreenAndVerify(firstActivity);
// Launch second activity to side
final Activity secondActivity = mSecondActivityTestRule.launchActivity(
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java
index 0fbc0ca..8a77fcb 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java
@@ -154,8 +154,7 @@
// Wait and verify the sequence
waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
- LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog(),
- false /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog());
LifecycleVerifier.assertEmptySequence(PipActivity.class, getLifecycleLog(),
"launchBelowPip");
}
@@ -225,17 +224,10 @@
.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
- LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog(),
- false /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog());
// Enter split screen
- getLifecycleLog().clear();
- moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
-
- waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
- LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
- Arrays.asList(ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
- ON_RESUME, ON_PAUSE), "moveToSplitScreen");
+ moveTaskToPrimarySplitScreenAndVerify(firstActivity);
// TODO(b/123013403): will fail with callback tracking enabled - delivers extra
// MULTI_WINDOW_MODE_CHANGED
LifecycleVerifier.assertEmptySequence(PipActivity.class, getLifecycleLog(),
@@ -248,8 +240,7 @@
// Wait for activities to resume and verify lifecycle
waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
- LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog(),
- false /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog());
LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
Arrays.asList(ON_RESUME), "launchToSide");
LifecycleVerifier.assertEmptySequence(PipActivity.class, getLifecycleLog(),
@@ -263,7 +254,7 @@
mFirstActivityTestRule.launchActivity(new Intent());
// Enter split screen
- moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
+ moveTaskToPrimarySplitScreenAndVerify(firstActivity);
// Launch second activity to side
final Activity secondActivity = mSecondActivityTestRule.launchActivity(
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java
index 7707f1b..4950aa6 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java
@@ -50,6 +50,7 @@
import org.junit.Before;
import org.junit.Test;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -84,7 +85,7 @@
state(firstActivity, ON_STOP));
// Enter split screen
- moveTaskToPrimarySplitScreen(secondActivity.getTaskId());
+ moveTaskToPrimarySplitScreenAndVerify(secondActivity);
// CLear logs so we can capture just the destroy sequence
getLifecycleLog().clear();
@@ -111,8 +112,7 @@
waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
// Enter split screen
- moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
- waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+ moveTaskToPrimarySplitScreenAndVerify(firstActivity);
final ComponentName firstActivityName = getComponentName(FirstActivity.class);
mAmWmState.computeState(firstActivityName);
@@ -142,7 +142,9 @@
waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
state(firstActivity, ON_STOP));
- LifecycleVerifier.assertEmptySequence(ThirdActivity.class, getLifecycleLog(), "moveToSide");
+ LifecycleVerifier.assertSequenceMatchesOneOf(ThirdActivity.class, getLifecycleLog(),
+ Arrays.asList(new ArrayList<>(), LifecycleVerifier.getRelaunchSequence(ON_RESUME)),
+ "moveToSide");
LifecycleVerifier.assertRestartAndResumeSequence(SecondActivity.class, getLifecycleLog());
LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
Arrays.asList(ON_PAUSE, ON_STOP), "moveToSide");
@@ -156,8 +158,7 @@
waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
// Enter split screen
- moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
- waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+ moveTaskToPrimarySplitScreenAndVerify(firstActivity);
final ComponentName firstActivityName = getComponentName(FirstActivity.class);
mAmWmState.computeState(firstActivityName);
@@ -179,19 +180,15 @@
final Activity translucentActivity = mTranslucentActivityTestRule.launchActivity(
new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
- waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
- // Second activity should stay resumed, because it's in a separate stack below the
- // translucent activity.
- LifecycleVerifier.assertEmptySequence(SecondActivity.class, getLifecycleLog(),
- "moveToSide");
+ waitAndAssertActivityStates(state(translucentActivity, ON_RESUME),
+ state(secondActivity, ON_PAUSE));
// Move translucent activity to side, it will be on top of the first now
getLifecycleLog().clear();
moveActivityToStack(getComponentName(TranslucentActivity.class), primarySplitStack);
- waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
- LifecycleVerifier.assertEmptySequence(SecondActivity.class, getLifecycleLog(),
- "moveToSide");
+ waitAndAssertActivityStates(state(firstActivity, ON_PAUSE),
+ state(secondActivity, ON_RESUME));
LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
Arrays.asList(ON_PAUSE), "moveToSide");
// Translucent activity can be either relaunched or preserved depending on whether the split
@@ -208,16 +205,7 @@
waitAndAssertActivityStates(state(callbackTrackingActivity, ON_TOP_POSITION_GAINED));
// Enter split screen, the activity will be relaunched.
- getLifecycleLog().clear();
- moveTaskToPrimarySplitScreen(callbackTrackingActivity.getTaskId());
- // Wait for multi-window mode change that will come after activity relaunch and resume.
- waitAndAssertActivityStates(state(callbackTrackingActivity, ON_PAUSE));
- final List<LifecycleLog.ActivityCallback> splitScreenMoveSequence = Arrays.asList(
- ON_TOP_POSITION_LOST, ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE,
- ON_START, ON_POST_CREATE, ON_RESUME, ON_TOP_POSITION_GAINED,
- ON_MULTI_WINDOW_MODE_CHANGED, ON_TOP_POSITION_LOST, ON_PAUSE);
- LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
- splitScreenMoveSequence, "moveToPrimarySplitScreen");
+ moveTaskToPrimarySplitScreenAndVerify(callbackTrackingActivity);
getLifecycleLog().clear();
// Launch second activity
@@ -268,12 +256,7 @@
waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
// Enter split screen
- getLifecycleLog().clear();
- moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
- waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
- LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(), Arrays.asList(
- ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME,
- ON_PAUSE), "enterSplitScreen");
+ moveTaskToPrimarySplitScreenAndVerify(firstActivity);
// Start an activity in separate task (will be placed in secondary stack)
final Activity newTaskActivity = mThirdActivityTestRule.launchActivity(
@@ -353,8 +336,7 @@
// Wait for the activity to resume
waitAndAssertActivityStates(state(testActivity, ON_TOP_POSITION_GAINED));
- LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
- true /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog());
// Enter split screen
getLifecycleLog().clear();
@@ -402,7 +384,7 @@
// Wait for the activity to resume
waitAndAssertActivityStates(state(testActivity, ON_TOP_POSITION_GAINED));
LifecycleVerifier.assertLaunchSequence(ConfigChangeHandlingActivity.class,
- getLifecycleLog(), true /* includeCallbacks */);
+ getLifecycleLog());
// Enter split screen
getLifecycleLog().clear();
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
index d20f1b3..f9b25bb 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
@@ -71,8 +71,7 @@
final Activity activity = mFirstActivityTestRule.launchActivity(new Intent());
waitAndAssertActivityStates(state(activity, ON_RESUME));
- LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog(),
- false /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog());
}
@Test
@@ -654,8 +653,7 @@
// Wait for the activity to resume
waitAndAssertActivityStates(state(singleTopActivity, ON_TOP_POSITION_GAINED));
- LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog(),
- true /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog());
// Try to launch again
getLifecycleLog().clear();
@@ -680,8 +678,7 @@
// Wait for the activity to resume
waitAndAssertActivityStates(state(singleTopActivity, ON_TOP_POSITION_GAINED));
- LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog(),
- true /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog());
// Launch something on top
final Intent newTaskIntent = new Intent();
@@ -724,8 +721,7 @@
// Wait for the activity to resume
waitAndAssertActivityStates(state(singleTopActivity, ON_TOP_POSITION_GAINED));
- LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog(),
- true /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog());
// Launch translucent activity, which will make the first one paused.
mTranslucentActivityTestRule.launchActivity(new Intent());
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTopResumedStateTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTopResumedStateTests.java
index df99ae8..0dd03be 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTopResumedStateTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTopResumedStateTests.java
@@ -9,7 +9,6 @@
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_ACTIVITY_RESULT;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_CREATE;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_DESTROY;
-import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_MULTI_WINDOW_MODE_CHANGED;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_NEW_INTENT;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_PAUSE;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_POST_CREATE;
@@ -59,8 +58,7 @@
final Activity activity = mCallbackTrackingActivityTestRule.launchActivity(new Intent());
waitAndAssertActivityStates(state(activity, ON_TOP_POSITION_GAINED));
- LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
- true /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog());
}
@Test
@@ -73,7 +71,7 @@
mAmWmState.waitForActivityRemoved(getComponentName(CallbackTrackingActivity.class));
LifecycleVerifier.assertResumeToDestroySequence(CallbackTrackingActivity.class,
- getLifecycleLog(), true /* includeCallbacks */);
+ getLifecycleLog());
}
@Test
@@ -88,7 +86,7 @@
LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class,
CallbackTrackingActivity.class, getLifecycleLog(),
- false /* launchingIsTranslucent */, true /* includingCallbacks */);
+ false /* launchingIsTranslucent */);
}
@Test
@@ -104,7 +102,7 @@
LifecycleVerifier.assertLaunchSequence(TranslucentCallbackTrackingActivity.class,
CallbackTrackingActivity.class, getLifecycleLog(),
- true /* launchingIsTranslucent */, true /* includingCallbacks */);
+ true /* launchingIsTranslucent */);
}
@Test
@@ -209,14 +207,7 @@
waitAndAssertActivityStates(state(firstActivity, ON_TOP_POSITION_GAINED));
// Enter split screen
- getLifecycleLog().clear();
- moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
- waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
- LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
- Arrays.asList(ON_TOP_POSITION_LOST, ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE,
- ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME, ON_TOP_POSITION_GAINED,
- ON_MULTI_WINDOW_MODE_CHANGED, ON_TOP_POSITION_LOST, ON_PAUSE),
- "moveToDocked");
+ moveTaskToPrimarySplitScreenAndVerify(firstActivity);
}
@Test
@@ -229,9 +220,7 @@
waitAndAssertActivityStates(state(firstActivity, ON_TOP_POSITION_GAINED));
// Enter split screen
- getLifecycleLog().clear();
- moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
- waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+ moveTaskToPrimarySplitScreenAndVerify(firstActivity);
// Launch second activity to side
getLifecycleLog().clear();
@@ -245,8 +234,7 @@
LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
Arrays.asList(ON_RESUME), "unminimizeDockedStack");
// Second activity must be on top now
- LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog(),
- true /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(SingleTopActivity.class, getLifecycleLog());
}
@Test
@@ -259,9 +247,7 @@
waitAndAssertActivityStates(state(firstActivity, ON_TOP_POSITION_GAINED));
// Enter split screen
- getLifecycleLog().clear();
- moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
- waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+ moveTaskToPrimarySplitScreenAndVerify(firstActivity);
// Launch second activity to side
getLifecycleLog().clear();
@@ -396,7 +382,7 @@
waitAndAssertActivityStates(state(topActivity, ON_STOP));
LifecycleVerifier.assertResumeToStopSequence(CallbackTrackingActivity.class,
- getLifecycleLog(), true /* includeCallbacks */);
+ getLifecycleLog());
}
@Test
@@ -409,9 +395,7 @@
waitAndAssertActivityStates(state(firstActivity, ON_TOP_POSITION_GAINED));
// Enter split screen
- getLifecycleLog().clear();
- moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
- waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+ moveTaskToPrimarySplitScreenAndVerify(firstActivity);
// Launch second activity to side
getLifecycleLog().clear();
@@ -480,7 +464,7 @@
new Intent());
waitAndAssertActivityStates(state(activity, ON_STOP));
LifecycleVerifier.assertLaunchAndStopSequence(CallbackTrackingActivity.class,
- getLifecycleLog(), true /* includeCallbacks */, false /* onTop */);
+ getLifecycleLog(), false /* onTop */);
getLifecycleLog().clear();
}
@@ -488,7 +472,7 @@
// Lock screen removed - activity should be on top now
waitAndAssertActivityStates(state(activity, ON_TOP_POSITION_GAINED));
LifecycleVerifier.assertStopToResumeSequence(CallbackTrackingActivity.class,
- getLifecycleLog(), true /* includeCallbacks */);
+ getLifecycleLog());
}
@Test
@@ -504,7 +488,7 @@
waitAndAssertActivityStates(state(activity, ON_STOP));
LifecycleVerifier.assertResumeToStopSequence(CallbackTrackingActivity.class,
- getLifecycleLog(), true /* includeCallbacks */);
+ getLifecycleLog());
getLifecycleLog().clear();
}
@@ -512,7 +496,7 @@
// Lock screen removed - activity should be on top now
waitAndAssertActivityStates(state(activity, ON_TOP_POSITION_GAINED));
LifecycleVerifier.assertStopToResumeSequence(CallbackTrackingActivity.class,
- getLifecycleLog(), true /* includeCallbacks */);
+ getLifecycleLog());
}
@Test
@@ -540,8 +524,7 @@
// Wait for something here, but don't expect anything to happen.
waitAndAssertActivityStates(state(showWhenLockedActivity, ON_DESTROY));
LifecycleVerifier.assertResumeToDestroySequence(
- ShowWhenLockedCallbackTrackingActivity.class, getLifecycleLog(),
- true /* includeCallbacks */);
+ ShowWhenLockedCallbackTrackingActivity.class, getLifecycleLog());
}
@Test
@@ -558,7 +541,7 @@
waitAndAssertTopResumedActivity(getComponentName(CallbackTrackingActivity.class),
DEFAULT_DISPLAY, "Activity launched on default display must be focused");
waitAndAssertActivityTransitions(CallbackTrackingActivity.class,
- LifecycleVerifier.getLaunchSequence(true /* includeCallbacks */), "launch");
+ LifecycleVerifier.getLaunchSequence(CallbackTrackingActivity.class), "launch");
try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
// Create new simulated display
@@ -575,7 +558,7 @@
newDisplay.mId, "Activity launched on secondary display must be focused");
waitAndAssertActivityTransitions(SingleTopActivity.class,
- LifecycleVerifier.getLaunchSequence(true /* includeCallbacks */), "launch");
+ LifecycleVerifier.getLaunchSequence(SingleTopActivity.class), "launch");
LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
transition(CallbackTrackingActivity.class, ON_TOP_POSITION_LOST),
transition(SingleTopActivity.class, ON_TOP_POSITION_GAINED)),
@@ -586,7 +569,7 @@
// Secondary display was removed - activity will be moved to the default display
waitAndAssertActivityTransitions(SingleTopActivity.class,
- LifecycleVerifier.getResumeToDestroySequence(true /* includeCallbacks */),
+ LifecycleVerifier.getResumeToDestroySequence(SingleTopActivity.class),
"hostingDisplayRemoved");
waitAndAssertActivityTransitions(CallbackTrackingActivity.class,
Arrays.asList(ON_TOP_POSITION_GAINED, ON_TOP_POSITION_LOST, ON_PAUSE, ON_STOP),
@@ -734,7 +717,7 @@
waitAndAssertActivityStates(state(alwaysFocusableActivity, ON_DESTROY),
state(activity, ON_TOP_POSITION_GAINED), state(pipActivity, ON_PAUSE));
LifecycleVerifier.assertResumeToDestroySequence(AlwaysFocusablePipActivity.class,
- getLifecycleLog(), true /* includeCallbacks */);
+ getLifecycleLog());
LifecycleVerifier.assertOrder(getLifecycleLog(), Arrays.asList(
transition(AlwaysFocusablePipActivity.class, ON_TOP_POSITION_LOST),
transition(CallbackTrackingActivity.class, ON_TOP_POSITION_GAINED)),
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleTracker.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleTracker.java
index 25374e5..24eb301 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleTracker.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleTracker.java
@@ -40,7 +40,8 @@
mLifecycleLog = lifecycleLog;
}
- void waitAndAssertActivityStates(Pair<Activity, ActivityCallback>[] activityCallbacks) {
+ void waitAndAssertActivityStates(
+ Pair<Class<? extends Activity>, ActivityCallback>[] activityCallbacks) {
final boolean waitResult = waitForConditionWithTimeout(
() -> pendingCallbacks(activityCallbacks).isEmpty(), 5 * 1000);
@@ -68,19 +69,20 @@
}
/** Get a list of activity states that were not reached yet. */
- private List<Pair<Activity, ActivityCallback>> pendingCallbacks(Pair<Activity,
- ActivityCallback>[] activityCallbacks) {
- final List<Pair<Activity, ActivityCallback>> notReachedActivityCallbacks = new ArrayList<>();
+ private List<Pair<Class<? extends Activity>, ActivityCallback>> pendingCallbacks(
+ Pair<Class<? extends Activity>, ActivityCallback>[] activityCallbacks) {
+ final List<Pair<Class<? extends Activity>, ActivityCallback>> notReachedActivityCallbacks =
+ new ArrayList<>();
- for (Pair<Activity, ActivityCallback> activityCallback : activityCallbacks) {
- final Activity activity = activityCallback.first;
+ for (Pair<Class<? extends Activity>, ActivityCallback> callbackPair : activityCallbacks) {
+ final Class<? extends Activity> activityClass = callbackPair.first;
final List<ActivityCallback> transitionList =
- mLifecycleLog.getActivityLog(activity.getClass());
+ mLifecycleLog.getActivityLog(activityClass);
if (transitionList.isEmpty()
- || transitionList.get(transitionList.size() - 1) != activityCallback.second) {
+ || transitionList.get(transitionList.size() - 1) != callbackPair.second) {
// The activity either hasn't got any state transitions yet or the current state is
// not the one we expect.
- notReachedActivityCallbacks.add(activityCallback);
+ notReachedActivityCallbacks.add(callbackPair);
}
}
return notReachedActivityCallbacks;
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
index 1f35d1f..a289682 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
@@ -19,6 +19,7 @@
import static android.server.am.StateLogger.log;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_CREATE;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_DESTROY;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_MULTI_WINDOW_MODE_CHANGED;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_PAUSE;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_POST_CREATE;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESTART;
@@ -34,6 +35,7 @@
import static org.junit.Assert.fail;
import android.app.Activity;
+import android.server.am.lifecycle.ActivityLifecycleClientTestBase.CallbackTrackingActivity;
import android.server.am.lifecycle.LifecycleLog.ActivityCallback;
import android.util.Pair;
@@ -44,19 +46,22 @@
/** Util class that verifies correct activity state transition sequences. */
class LifecycleVerifier {
+ private static final Class CALLBACK_TRACKING_CLASS = CallbackTrackingActivity.class;
+
static void assertLaunchSequence(Class<? extends Activity> activityClass,
- LifecycleLog lifecycleLog, boolean includeCallbacks) {
+ LifecycleLog lifecycleLog) {
final List<ActivityCallback> observedTransitions =
lifecycleLog.getActivityLog(activityClass);
log("Observed sequence: " + observedTransitions);
final String errorMessage = errorDuringTransition(activityClass, "launch");
- final List<ActivityCallback> expectedTransitions = getLaunchSequence(includeCallbacks);
+ final List<ActivityCallback> expectedTransitions = getLaunchSequence(activityClass);
assertEquals(errorMessage, expectedTransitions, observedTransitions);
}
- public static List<ActivityCallback> getLaunchSequence(boolean includeCallbacks) {
- return includeCallbacks
+ public static List<ActivityCallback> getLaunchSequence(
+ Class<? extends Activity> activityClass) {
+ return CALLBACK_TRACKING_CLASS.isAssignableFrom(activityClass)
? Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
ON_TOP_POSITION_GAINED)
: Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME);
@@ -65,13 +70,20 @@
static void assertLaunchSequence(Class<? extends Activity> launchingActivity,
Class<? extends Activity> existingActivity, LifecycleLog lifecycleLog,
boolean launchingIsTranslucent) {
- assertLaunchSequence(launchingActivity, existingActivity, lifecycleLog,
- launchingIsTranslucent, false /* includingCallbacks */);
- }
+ final boolean includingCallbacks;
+ if (CALLBACK_TRACKING_CLASS.isAssignableFrom(launchingActivity)
+ && CALLBACK_TRACKING_CLASS.isAssignableFrom(existingActivity)) {
+ includingCallbacks = true;
+ } else if (!CALLBACK_TRACKING_CLASS.isAssignableFrom(launchingActivity)
+ && !CALLBACK_TRACKING_CLASS.isAssignableFrom(existingActivity)) {
+ includingCallbacks = false;
+ } else {
+ throw new IllegalArgumentException("Mixed types of callback tracking not supported. "
+ + "Both activities must support or not support callback tracking "
+ + "simultaneously");
+ }
- static void assertLaunchSequence(Class<? extends Activity> launchingActivity,
- Class<? extends Activity> existingActivity, LifecycleLog lifecycleLog,
- boolean launchingIsTranslucent, boolean includingCallbacks) {
+
final List<Pair<String, ActivityCallback>> observedTransitions = lifecycleLog.getLog();
log("Observed sequence: " + observedTransitions);
final String errorMessage = errorDuringTransition(launchingActivity, "launch");
@@ -102,17 +114,19 @@
static void assertLaunchAndStopSequence(Class<? extends Activity> activityClass,
LifecycleLog lifecycleLog) {
- assertLaunchAndStopSequence(activityClass, lifecycleLog, false /* includeCallbacks */,
+ assertLaunchAndStopSequence(activityClass, lifecycleLog,
false /* onTop */);
}
static void assertLaunchAndStopSequence(Class<? extends Activity> activityClass,
- LifecycleLog lifecycleLog, boolean includeCallbacks, boolean onTop) {
+ LifecycleLog lifecycleLog, boolean onTop) {
final List<ActivityCallback> observedTransitions =
lifecycleLog.getActivityLog(activityClass);
log("Observed sequence: " + observedTransitions);
final String errorMessage = errorDuringTransition(activityClass, "launch and stop");
+ final boolean includeCallbacks = CALLBACK_TRACKING_CLASS.isAssignableFrom(activityClass);
+
final List<ActivityCallback> expectedTransitions = new ArrayList<>();
expectedTransitions.addAll(Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START));
if (includeCallbacks) {
@@ -151,7 +165,7 @@
}
static void assertRestartAndResumeSequence(Class<? extends Activity> activityClass,
- LifecycleLog lifecycleLog) {
+ LifecycleLog lifecycleLog) {
final List<ActivityCallback> observedTransitions =
lifecycleLog.getActivityLog(activityClass);
log("Observed sequence: " + observedTransitions);
@@ -163,7 +177,7 @@
}
static void assertRecreateAndResumeSequence(Class<? extends Activity> activityClass,
- LifecycleLog lifecycleLog) {
+ LifecycleLog lifecycleLog) {
final List<ActivityCallback> observedTransitions =
lifecycleLog.getActivityLog(activityClass);
log("Observed sequence: " + observedTransitions);
@@ -188,38 +202,30 @@
static void assertResumeToDestroySequence(Class<? extends Activity> activityClass,
LifecycleLog lifecycleLog) {
- assertResumeToDestroySequence(activityClass, lifecycleLog, false /* includeCallbacks */);
- }
-
- static void assertResumeToDestroySequence(Class<? extends Activity> activityClass,
- LifecycleLog lifecycleLog, boolean includeCallbacks) {
final List<ActivityCallback> observedTransitions =
lifecycleLog.getActivityLog(activityClass);
log("Observed sequence: " + observedTransitions);
final String errorMessage = errorDuringTransition(activityClass, "launch and destroy");
final List<ActivityCallback> expectedTransitions =
- getResumeToDestroySequence(includeCallbacks);
+ getResumeToDestroySequence(activityClass);
assertEquals(errorMessage, expectedTransitions, observedTransitions);
}
- static List<ActivityCallback> getResumeToDestroySequence(boolean includeCallbacks) {
- return includeCallbacks
+ static List<ActivityCallback> getResumeToDestroySequence(
+ Class<? extends Activity> activityClass) {
+ return CALLBACK_TRACKING_CLASS.isAssignableFrom(activityClass)
? Arrays.asList(ON_TOP_POSITION_LOST, ON_PAUSE, ON_STOP, ON_DESTROY)
: Arrays.asList(ON_PAUSE, ON_STOP, ON_DESTROY);
}
static void assertResumeToStopSequence(Class<? extends Activity> activityClass,
LifecycleLog lifecycleLog) {
- assertResumeToStopSequence(activityClass, lifecycleLog, false /* includeCallbacks */);
- }
-
- static void assertResumeToStopSequence(Class<? extends Activity> activityClass,
- LifecycleLog lifecycleLog, boolean includeCallbacks) {
final List<ActivityCallback> observedTransitions =
lifecycleLog.getActivityLog(activityClass);
log("Observed sequence: " + observedTransitions);
final String errorMessage = errorDuringTransition(activityClass, "resumed to stopped");
+ final boolean includeCallbacks = CALLBACK_TRACKING_CLASS.isAssignableFrom(activityClass);
final List<ActivityCallback> expectedTransitions = new ArrayList<>();
if (includeCallbacks) {
@@ -232,11 +238,12 @@
}
static void assertStopToResumeSequence(Class<? extends Activity> activityClass,
- LifecycleLog lifecycleLog, boolean includeCallbacks) {
+ LifecycleLog lifecycleLog) {
final List<ActivityCallback> observedTransitions =
lifecycleLog.getActivityLog(activityClass);
log("Observed sequence: " + observedTransitions);
final String errorMessage = errorDuringTransition(activityClass, "stopped to resumed");
+ final boolean includeCallbacks = CALLBACK_TRACKING_CLASS.isAssignableFrom(activityClass);
final List<ActivityCallback> expectedTransitions = new ArrayList<>(
Arrays.asList(ON_RESTART, ON_START, ON_RESUME));
@@ -249,6 +256,11 @@
static void assertRelaunchSequence(Class<? extends Activity> activityClass,
LifecycleLog lifecycleLog, ActivityCallback startState) {
+ final List<ActivityCallback> expectedTransitions = getRelaunchSequence(startState);
+ assertSequence(activityClass, lifecycleLog, expectedTransitions, "relaunch");
+ }
+
+ static List<ActivityCallback> getRelaunchSequence(ActivityCallback startState) {
final List<ActivityCallback> expectedTransitions;
if (startState == ON_PAUSE) {
expectedTransitions = Arrays.asList(
@@ -267,7 +279,17 @@
} else {
throw new IllegalArgumentException("Start state not supported: " + startState);
}
- assertSequence(activityClass, lifecycleLog, expectedTransitions, "relaunch");
+ return expectedTransitions;
+ }
+
+ static List<ActivityCallback> getSplitScreenTransitionSequence(
+ Class<? extends Activity> activityClass) {
+ return CALLBACK_TRACKING_CLASS.isAssignableFrom(activityClass)
+ ? Arrays.asList(ON_TOP_POSITION_LOST, ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE,
+ ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME, ON_TOP_POSITION_GAINED,
+ ON_TOP_POSITION_LOST, ON_PAUSE, ON_MULTI_WINDOW_MODE_CHANGED)
+ : Arrays.asList(ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
+ ON_RESUME, ON_PAUSE);
}
static void assertSequence(Class<? extends Activity> activityClass, LifecycleLog lifecycleLog,
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
index 78f3534..8f1543c 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
@@ -38,6 +38,7 @@
import android.content.ComponentName;
import android.graphics.Rect;
import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.Presubmit;
import android.server.am.WaitForValidActivityState;
import android.server.am.WindowManagerState;
import android.server.am.WindowManagerState.WindowState;
@@ -56,6 +57,7 @@
* TODO: Consolidate this class with {@link ParentChildTestBase}.
*/
@AppModeFull(reason = "Requires android.permission.MANAGE_ACTIVITY_STACKS")
+@Presubmit
public class DialogFrameTests extends ParentChildTestBase<DialogFrameTestActivity> {
private static final ComponentName DIALOG_FRAME_TEST_ACTIVITY = new ComponentName(
diff --git a/tests/signature/TEST_MAPPING b/tests/signature/TEST_MAPPING
new file mode 100644
index 0000000..5ed73ce
--- /dev/null
+++ b/tests/signature/TEST_MAPPING
@@ -0,0 +1,48 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsAndroidTestMockCurrentApiSignatureTestCases"
+ },
+ {
+ "name": "CtsAndroidTestRunnerCurrentApiSignatureTestCases"
+ },
+ {
+ "name": "CtsApacheHttpLegacyCurrentApiSignatureTestCases"
+ },
+ {
+ "name": "CtsCurrentApiSignatureTestCases"
+ },
+ {
+ "name": "CtsAndroidTestBase27ApiSignatureTestCases"
+ },
+ {
+ "name": "CtsAndroidTestBase27ApiSignatureTestCases"
+ },
+ {
+ "name": "CtsApacheHttpLegacy27ApiSignatureTestCases"
+ },
+ {
+ "name": "CtsApacheHttpLegacyUsesLibraryApiSignatureTestCases"
+ },
+ {
+ "name": "CtsHiddenApiKillswitchDebugClassTestCases"
+ },
+ {
+ "name": "CtsHiddenApiKillswitchWhitelistTestCases"
+ },
+ {
+ "name": "CtsHiddenApiKillswitchWildcardTestCases"
+ },
+ {
+ "name": "CtsSystemApiAnnotationTestCases"
+ },
+ {
+ "name": "CtsSharedLibsApiSignatureTestCases"
+ }
+ ]
+}
+
+
+
+
+
diff --git a/tests/signature/api-check/android-test-base-27-api/AndroidTest.xml b/tests/signature/api-check/android-test-base-27-api/AndroidTest.xml
index bf07983..d746778 100644
--- a/tests/signature/api-check/android-test-base-27-api/AndroidTest.xml
+++ b/tests/signature/api-check/android-test-base-27-api/AndroidTest.xml
@@ -30,7 +30,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.signature.cts.api.android_test_base_27" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
- <option name="class" value="android.signature.cts.api.SignatureTest" />
+ <option name="class" value="android.signature.cts.api.api27.test.SignatureTest" />
<option name="instrumentation-arg" key="expected-api-files" value="android-test-base-current.api" />
<option name="runtime-hint" value="5s" />
</test>
diff --git a/tests/signature/api-check/android-test-base-27-api/src/java/android/signature/cts/api/api27/test/SignatureTest.java b/tests/signature/api-check/android-test-base-27-api/src/java/android/signature/cts/api/api27/test/SignatureTest.java
new file mode 100644
index 0000000..875349a
--- /dev/null
+++ b/tests/signature/api-check/android-test-base-27-api/src/java/android/signature/cts/api/api27/test/SignatureTest.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api.api27.test;
+
+public class SignatureTest extends android.signature.cts.api.SignatureTest {
+}
diff --git a/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml b/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml
index c5ecdbd..85e7484 100644
--- a/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml
@@ -30,7 +30,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.signature.cts.api.android_test_mock_current" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
- <option name="class" value="android.signature.cts.api.SignatureTest" />
+ <option name="class" value="android.signature.cts.api.current.mock.SignatureTest" />
<option name="instrumentation-arg" key="expected-api-files" value="android-test-mock-current.api" />
<option name="runtime-hint" value="5s" />
</test>
diff --git a/tests/signature/api-check/android-test-mock-current-api/src/android/signature/cts/api/current/mock/SignatureTest.java b/tests/signature/api-check/android-test-mock-current-api/src/android/signature/cts/api/current/mock/SignatureTest.java
new file mode 100644
index 0000000..758188a
--- /dev/null
+++ b/tests/signature/api-check/android-test-mock-current-api/src/android/signature/cts/api/current/mock/SignatureTest.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api.current.mock;
+
+public class SignatureTest extends android.signature.cts.api.SignatureTest {
+}
diff --git a/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml b/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml
index 53bed33..703caf7 100644
--- a/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml
@@ -33,7 +33,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.signature.cts.api.android_test_runner_current" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
- <option name="class" value="android.signature.cts.api.SignatureTest" />
+ <option name="class" value="android.signature.cts.api.current.runner.SignatureTest" />
<option name="instrumentation-arg" key="expected-api-files" value="android-test-mock-current.api,android-test-runner-current.api" />
<option name="runtime-hint" value="5s" />
</test>
diff --git a/tests/signature/api-check/android-test-runner-current-api/src/android/signature/cts/api/current/runner/SignatureTest.java b/tests/signature/api-check/android-test-runner-current-api/src/android/signature/cts/api/current/runner/SignatureTest.java
new file mode 100644
index 0000000..65f43ec
--- /dev/null
+++ b/tests/signature/api-check/android-test-runner-current-api/src/android/signature/cts/api/current/runner/SignatureTest.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api.current.runner;
+
+public class SignatureTest extends android.signature.cts.api.SignatureTest {
+}
diff --git a/tests/signature/api-check/apache-http-legacy-27-api/AndroidTest.xml b/tests/signature/api-check/apache-http-legacy-27-api/AndroidTest.xml
index 3bbc90e..6a33f1c 100644
--- a/tests/signature/api-check/apache-http-legacy-27-api/AndroidTest.xml
+++ b/tests/signature/api-check/apache-http-legacy-27-api/AndroidTest.xml
@@ -33,7 +33,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.signature.cts.api.apache_http_legacy_27" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
- <option name="class" value="android.signature.cts.api.SignatureTest" />
+ <option name="class" value="android.signature.cts.api.api27.http.SignatureTest" />
<option name="instrumentation-arg" key="base-api-files" value="current.api" />
<option name="instrumentation-arg" key="expected-api-files" value="apache-http-legacy-minus-current.api" />
<option name="runtime-hint" value="5s" />
diff --git a/tests/signature/api-check/apache-http-legacy-27-api/src/android/signature/cts/api/api27/http/SignatureTest.java b/tests/signature/api-check/apache-http-legacy-27-api/src/android/signature/cts/api/api27/http/SignatureTest.java
new file mode 100644
index 0000000..7c14ec1
--- /dev/null
+++ b/tests/signature/api-check/apache-http-legacy-27-api/src/android/signature/cts/api/api27/http/SignatureTest.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api.api27.http;
+
+public class SignatureTest extends android.signature.cts.api.SignatureTest {
+}
diff --git a/tests/signature/api-check/apache-http-legacy-current-api/AndroidTest.xml b/tests/signature/api-check/apache-http-legacy-current-api/AndroidTest.xml
index 418c881..f204883 100644
--- a/tests/signature/api-check/apache-http-legacy-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/apache-http-legacy-current-api/AndroidTest.xml
@@ -30,7 +30,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.signature.cts.api.apache_http_legacy_current" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
- <option name="class" value="android.signature.cts.api.SignatureTest" />
+ <option name="class" value="android.signature.cts.api.current.http.SignatureTest" />
<option name="instrumentation-arg" key="unexpected-api-files" value="apache-http-legacy-minus-current.api" />
<option name="runtime-hint" value="5s" />
</test>
diff --git a/tests/signature/api-check/apache-http-legacy-current-api/src/android/signature/cts/api/current/http/SignatureTest.java b/tests/signature/api-check/apache-http-legacy-current-api/src/android/signature/cts/api/current/http/SignatureTest.java
new file mode 100644
index 0000000..582e5da
--- /dev/null
+++ b/tests/signature/api-check/apache-http-legacy-current-api/src/android/signature/cts/api/current/http/SignatureTest.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api.current.http;
+
+public class SignatureTest extends android.signature.cts.api.SignatureTest {
+}
diff --git a/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidTest.xml b/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidTest.xml
index bd2c566..6fb7868 100644
--- a/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidTest.xml
+++ b/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidTest.xml
@@ -33,7 +33,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.signature.cts.api.apache_http_legacy_uses_library" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
- <option name="class" value="android.signature.cts.api.SignatureTest" />
+ <option name="class" value="android.signature.cts.api.http_uses_library.SignatureTest" />
<option name="instrumentation-arg" key="base-api-files" value="current.api" />
<option name="instrumentation-arg" key="expected-api-files" value="apache-http-legacy-minus-current.api" />
<option name="runtime-hint" value="5s" />
diff --git a/tests/signature/api-check/apache-http-legacy-uses-library-api/src/android/signature/cts/api/http_uses_library/SignatureTest.java b/tests/signature/api-check/apache-http-legacy-uses-library-api/src/android/signature/cts/api/http_uses_library/SignatureTest.java
new file mode 100644
index 0000000..b8b94cf
--- /dev/null
+++ b/tests/signature/api-check/apache-http-legacy-uses-library-api/src/android/signature/cts/api/http_uses_library/SignatureTest.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api.http_uses_library;
+
+public class SignatureTest extends android.signature.cts.api.SignatureTest {
+}
diff --git a/tests/signature/api-check/build_signature_apk.mk b/tests/signature/api-check/build_signature_apk.mk
index 23457d3..4181827 100644
--- a/tests/signature/api-check/build_signature_apk.mk
+++ b/tests/signature/api-check/build_signature_apk.mk
@@ -76,6 +76,10 @@
LOCAL_USE_EMBEDDED_NATIVE_LIBS := false
+ifneq (,$(wildcard $(LOCAL_PATH)/src))
+ LOCAL_SRC_FILES := $(call all-java-files-under, src)
+endif
+
include $(BUILD_CTS_PACKAGE)
LOCAL_SIGNATURE_API_FILES :=
diff --git a/tests/signature/api-check/current-api/AndroidTest.xml b/tests/signature/api-check/current-api/AndroidTest.xml
index 59b7bd6..8253275 100644
--- a/tests/signature/api-check/current-api/AndroidTest.xml
+++ b/tests/signature/api-check/current-api/AndroidTest.xml
@@ -37,7 +37,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.signature.cts.api.current" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
- <option name="class" value="android.signature.cts.api.SignatureTest" />
+ <option name="class" value="android.signature.cts.api.current.SignatureTest" />
<option name="instrumentation-arg" key="expected-api-files" value="current.api" />
<option name="instrumentation-arg" key="unexpected-api-files" value="android-test-mock-current.api,android-test-runner-current.api" />
<option name="runtime-hint" value="30s" />
diff --git a/tests/signature/api-check/current-api/src/android/signature/cts/api/current/SignatureTest.java b/tests/signature/api-check/current-api/src/android/signature/cts/api/current/SignatureTest.java
new file mode 100644
index 0000000..1eadd2f
--- /dev/null
+++ b/tests/signature/api-check/current-api/src/android/signature/cts/api/current/SignatureTest.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api.current;
+
+public class SignatureTest extends android.signature.cts.api.SignatureTest {
+}
diff --git a/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidTest.xml b/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidTest.xml
index bf13b5a..4413824 100644
--- a/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidTest.xml
@@ -30,7 +30,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.signature.cts.api.hiddenapi_blacklist_api_27" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
- <option name="class" value="android.signature.cts.api.HiddenApiTest" />
+ <option name="class" value="android.signature.cts.api.api27.HiddenApiTest" />
<option name="instrumentation-arg" key="hiddenapi-files" value="hiddenapi_flags.csv" />
<option name="instrumentation-arg" key="hiddenapi-test-flags" value="blacklist" />
<option name="runtime-hint" value="30s" />
diff --git a/tests/signature/api-check/hidden-api-blacklist-27-api/src/android/signature/cts/api/api27/HiddenApiTest.java b/tests/signature/api-check/hidden-api-blacklist-27-api/src/android/signature/cts/api/api27/HiddenApiTest.java
new file mode 100644
index 0000000..c940aac
--- /dev/null
+++ b/tests/signature/api-check/hidden-api-blacklist-27-api/src/android/signature/cts/api/api27/HiddenApiTest.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api.api27;
+
+public class HiddenApiTest extends android.signature.cts.api.HiddenApiTest {
+}
diff --git a/tests/signature/api-check/hidden-api-blacklist-28/AndroidTest.xml b/tests/signature/api-check/hidden-api-blacklist-28/AndroidTest.xml
index 011a565..6bebfe1 100644
--- a/tests/signature/api-check/hidden-api-blacklist-28/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-28/AndroidTest.xml
@@ -30,7 +30,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.signature.cts.api.hiddenapi_blacklist_api_28" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
- <option name="class" value="android.signature.cts.api.HiddenApiTest" />
+ <option name="class" value="android.signature.cts.api.api28.HiddenApiTest" />
<option name="instrumentation-arg" key="hiddenapi-files" value="hiddenapi_flags.csv" />
<option name="instrumentation-arg" key="hiddenapi-test-flags" value="blacklist,greylist-max-o" />
<option name="runtime-hint" value="30s" />
diff --git a/tests/signature/api-check/hidden-api-blacklist-28/src/android/signature/cts/api/api28/HiddenApiTest.java b/tests/signature/api-check/hidden-api-blacklist-28/src/android/signature/cts/api/api28/HiddenApiTest.java
new file mode 100644
index 0000000..f85dda3
--- /dev/null
+++ b/tests/signature/api-check/hidden-api-blacklist-28/src/android/signature/cts/api/api28/HiddenApiTest.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api.api28;
+
+public class HiddenApiTest extends android.signature.cts.api.HiddenApiTest {
+}
diff --git a/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidTest.xml b/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidTest.xml
index ab5e735..6f14d96 100644
--- a/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidTest.xml
@@ -30,7 +30,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.signature.cts.api.hiddenapi_blacklist_current" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
- <option name="class" value="android.signature.cts.api.HiddenApiTest" />
+ <option name="class" value="android.signature.cts.api.current.HiddenApiTest" />
<option name="instrumentation-arg" key="hiddenapi-files" value="hiddenapi_flags.csv" />
<option name="instrumentation-arg" key="hiddenapi-test-flags" value="blacklist,greylist-max-o,greylist-max-p" />
<option name="runtime-hint" value="30s" />
diff --git a/tests/signature/api-check/hidden-api-blacklist-current-api/src/android/signature/cts/api/current/HiddenApiTest.java b/tests/signature/api-check/hidden-api-blacklist-current-api/src/android/signature/cts/api/current/HiddenApiTest.java
new file mode 100644
index 0000000..34f33fe
--- /dev/null
+++ b/tests/signature/api-check/hidden-api-blacklist-current-api/src/android/signature/cts/api/current/HiddenApiTest.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api.current;
+
+public class HiddenApiTest extends android.signature.cts.api.HiddenApiTest {
+}
diff --git a/tests/signature/api-check/system-api/AndroidTest.xml b/tests/signature/api-check/system-api/AndroidTest.xml
index 5f70478..6504182 100644
--- a/tests/signature/api-check/system-api/AndroidTest.xml
+++ b/tests/signature/api-check/system-api/AndroidTest.xml
@@ -34,7 +34,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.signature.cts.api.system" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
- <option name="class" value="android.signature.cts.api.SignatureTest" />
+ <option name="class" value="android.signature.cts.api.system.SignatureTest" />
<option name="instrumentation-arg" key="base-api-files" value="current.api" />
<option name="instrumentation-arg" key="expected-api-files" value="system-all.api.zip" />
<option name="instrumentation-arg" key="unexpected-api-files" value="android-test-mock-current.api,android-test-runner-current.api" />
diff --git a/tests/signature/api-check/system-api/src/android/signature/cts/api/system/SignatureTest.java b/tests/signature/api-check/system-api/src/android/signature/cts/api/system/SignatureTest.java
new file mode 100644
index 0000000..5316e31
--- /dev/null
+++ b/tests/signature/api-check/system-api/src/android/signature/cts/api/system/SignatureTest.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.signature.cts.api.system;
+
+public class SignatureTest extends android.signature.cts.api.SignatureTest {
+}
diff --git a/tests/tests/animation/Android.bp b/tests/tests/animation/Android.bp
new file mode 100644
index 0000000..d5b1993
--- /dev/null
+++ b/tests/tests/animation/Android.bp
@@ -0,0 +1,40 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test {
+ name: "CtsAnimationTestCases",
+ defaults: ["cts_defaults"],
+
+ static_libs: [
+ "android-support-test",
+ "mockito-target-minus-junit4",
+ "android-common",
+ "compatibility-device-util",
+ "ctstestrunner",
+ "platform-test-annotations",
+ ],
+
+ libs: ["android.test.runner.stubs"],
+
+ srcs: ["src/**/*.java"],
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ "cts_instant",
+ ],
+
+ sdk_version: "test_current",
+}
diff --git a/tests/tests/animation/Android.mk b/tests/tests/animation/Android.mk
deleted file mode 100644
index 293f75f..0000000
--- a/tests/tests/animation/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2011 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_PACKAGE_NAME := CtsAnimationTestCases
-
-# Don't include this package in any target.
-LOCAL_MODULE_TAGS := optional
-
-# When built, explicitly put it in the data partition.
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_STATIC_JAVA_LIBRARIES += \
- android-support-test \
- mockito-target-minus-junit4 \
- android-common \
- compatibility-device-util \
- ctstestrunner \
- platform-test-annotations
-
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
-
-# Enforce public / test api only
-LOCAL_SDK_VERSION := test_current
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/animation/src/android/animation/cts/AnimatorTest.java b/tests/tests/animation/src/android/animation/cts/AnimatorTest.java
index 655eb1c..ef2d35ac 100644
--- a/tests/tests/animation/src/android/animation/cts/AnimatorTest.java
+++ b/tests/tests/animation/src/android/animation/cts/AnimatorTest.java
@@ -18,7 +18,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -205,18 +204,23 @@
@Test
public void testNullObjectAnimator() throws Throwable {
- Object object = mActivity.view.newBall;
- final ObjectAnimator animator = ObjectAnimator.ofFloat(object, "y", 0, 100);
+ class AnimTarget {
+ public float y = 0f;
+ public void setY(float y) {
+ this.y = y;
+ }
+
+ public float getY() {
+ return y;
+ }
+ }
+ final ObjectAnimator animator = ObjectAnimator.ofFloat(new AnimTarget(), "y", 0, 100);
MyListener listener = new MyListener();
animator.addListener(listener);
- mActivity.view.newBall.setY(0);
- startAnimation(animator);
- int sleepCount = 0;
- while (mActivity.view.newBall.getY() == 0 && sleepCount++ < 50) {
- SystemClock.sleep(1);
- }
- assertNotSame(0, mActivity.view.newBall.getY());
- mActivityRule.runOnUiThread(() -> animator.setTarget(null));
+ mActivityRule.runOnUiThread(() -> {
+ animator.start();
+ animator.setTarget(null);
+ });
assertTrue(listener.mCancel);
}
diff --git a/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java b/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
index e7d939f..427237c 100644
--- a/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
+++ b/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
@@ -32,8 +32,10 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
+import android.animation.TimeInterpolator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.graphics.Color;
import android.graphics.PointF;
import android.os.SystemClock;
@@ -480,43 +482,76 @@
@Test
public void testGetAnimatedFraction() throws Throwable {
- ValueAnimator objAnimator = getAnimator();
- objAnimator.setRepeatCount(0);
- startAnimation(objAnimator);
- assertNotNull(objAnimator);
- float[] fractions = getValue(objAnimator, 5, "getAnimatedFraction()", 100L, null);
- for (int j = 0; j < fractions.length - 1; j++) {
- assertTrue(fractions[j] >= 0.0);
- assertTrue(fractions[j] <= 1.0);
- assertTrue(errorMessage(fractions), fractions[j + 1] >= fractions[j]);
+ ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
+ assertNotNull(animator);
+ animator.setDuration(200);
+ animator.addUpdateListener(new AnimatorUpdateListener() {
+ public float lastFraction = 0;
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float currentFraction = animation.getAnimatedFraction();
+ assertTrue(
+ "Last fraction = " + lastFraction + "current fraction = " + currentFraction,
+ animation.getAnimatedFraction() >= lastFraction);
+ lastFraction = currentFraction;
+ assertTrue(currentFraction <= 1f);
+ }
+ });
+ CountDownLatch latch = new CountDownLatch(1);
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ latch.countDown();
+ }
+ });
+ mActivityRule.runOnUiThread(() -> {
+ animator.start();
+ });
+
+ latch.await(1000, TimeUnit.MILLISECONDS);
+
+ assertEquals(1.0f, animator.getAnimatedFraction(), EPSILON);
+ }
+
+ class TestInterpolator implements TimeInterpolator {
+
+ @Override
+ public float getInterpolation(float input) {
+ return input * input;
}
}
@Test
- public void testGetAnimatedValue() throws Throwable {
- ValueAnimator objAnimator = getAnimator();
- objAnimator.setRepeatCount(0);
- startAnimation(objAnimator);
- assertNotNull(objAnimator);
- float[] animatedValues = getValue(objAnimator, 5, "getAnimatedValue()", 100L, null);
+ public void testGetAnimatedValue() {
+ ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
+ assertNotNull(animator);
+ TimeInterpolator myInterpolator = new TestInterpolator();
+ animator.setInterpolator(myInterpolator);
+ int sliceNum = 10;
+ for (int i = 0; i <= sliceNum; i++) {
+ float fraction = i / (float) sliceNum;
+ animator.setCurrentFraction(fraction);
+ assertEquals(myInterpolator.getInterpolation(fraction),
+ (float) animator.getAnimatedValue(), EPSILON);
- for (int j = 0; j < animatedValues.length - 1; j++) {
- assertTrue(errorMessage(animatedValues), animatedValues[j + 1] >= animatedValues[j]);
}
}
@Test
- public void testGetAnimatedValue_PropertyName() throws Throwable {
- String property = "y";
+ public void testGetAnimatedValue_PropertyName() {
+ PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 100f, -100f);
+ PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 0f, 1f);
+ ValueAnimator animator = ValueAnimator.ofPropertyValuesHolder(pvhX, pvhY);
+ assertNotNull(animator);
+ TimeInterpolator myInterpolator = new TestInterpolator();
+ animator.setInterpolator(myInterpolator);
+ int sliceNum = 10;
+ for (int i = 0; i <= sliceNum; i++) {
+ float fraction = i / (float) sliceNum;
+ animator.setCurrentFraction(fraction);
+ assertEquals(myInterpolator.getInterpolation(fraction),
+ (float) animator.getAnimatedValue("y"), EPSILON);
- ValueAnimator objAnimator = getAnimator();
- objAnimator.setRepeatCount(0);
- startAnimation(objAnimator);
- assertNotNull(objAnimator);
- float[] animatedValues = getValue(objAnimator, 5, "getAnimatedValue(property)", 100L,
- property);
- for (int j = 0; j < animatedValues.length - 1; j++) {
- assertTrue(errorMessage(animatedValues), animatedValues[j + 1] >= animatedValues[j]);
}
}
@@ -703,24 +738,6 @@
return objAnimator;
}
- private float[] getValue(ValueAnimator animator, int n, String methodName,
- long sleepTime, String property) throws InterruptedException {
- float[] values = new float[n];
- for(int i = 0; i < n; i++){
- SystemClock.sleep(sleepTime);
- float value = 0.0f;
- if(methodName.equals("getAnimatedFraction()")) {
- value = animator.getAnimatedFraction();
- }else if(methodName.equals("getAnimatedValue()")) {
- value = ((Float)animator.getAnimatedValue()).floatValue();
- }else if(methodName.equals("getAnimatedValue(property)")) {
- value = ((Float)animator.getAnimatedValue(property)).floatValue();
- }
- values[i] = value;
- }
- return values;
- }
-
private void startAnimation(final ValueAnimator animator) throws Throwable {
mActivityRule.runOnUiThread(() -> mActivity.startAnimation(animator));
}
diff --git a/tests/tests/background/AndroidTest.xml b/tests/tests/background/AndroidTest.xml
index f0af389..364457e 100644
--- a/tests/tests/background/AndroidTest.xml
+++ b/tests/tests/background/AndroidTest.xml
@@ -17,6 +17,7 @@
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="framework" />
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="not-shardable" value="true" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/tests/carrierapi/AndroidTest.xml b/tests/tests/carrierapi/AndroidTest.xml
index d77f373..2f445eb 100644
--- a/tests/tests/carrierapi/AndroidTest.xml
+++ b/tests/tests/carrierapi/AndroidTest.xml
@@ -14,7 +14,9 @@
limitations under the License.
-->
<configuration description="Config for CTS Carrier APIs test cases">
- <option name="test-suite-tag" value="cts" />
+ <option name="test-suite-tag" value="cts" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
<option name="config-descriptor:metadata" key="component" value="telecom" />
<option name="config-descriptor:metadata" key="token" value="UICC_SIM_CARD" />
<option name="not-shardable" value="true" />
diff --git a/tests/tests/content/src/android/content/pm/cts/LauncherAppsTest.java b/tests/tests/content/src/android/content/pm/cts/LauncherAppsTest.java
index 77250f8..c72d8b3 100644
--- a/tests/tests/content/src/android/content/pm/cts/LauncherAppsTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/LauncherAppsTest.java
@@ -127,6 +127,15 @@
}
}
+ @Test
+ public void testGetAppUsageLimit_allowsZeroLimit() {
+ registerObserver(DEFAULT_OBSERVER_ID, 0);
+ final LauncherApps.AppUsageLimit limit = mLauncherApps.getAppUsageLimit(
+ SETTINGS_PACKAGE, USER_HANDLE);
+ assertNotNull("An observer with a time limit of 0 was not registered.", limit);
+ assertEquals("Usage remaining expected to be 0.", 0, limit.getUsageRemaining());
+ }
+
@After
public void tearDown() throws Exception {
unregisterObserver(DEFAULT_OBSERVER_ID);
diff --git a/tests/tests/graphics/AndroidTest.xml b/tests/tests/graphics/AndroidTest.xml
index 1fcf520..0c99b6a 100644
--- a/tests/tests/graphics/AndroidTest.xml
+++ b/tests/tests/graphics/AndroidTest.xml
@@ -16,7 +16,7 @@
<configuration description="Config for CTS Graphics test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="uitoolkit" />
- <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ColorStateListDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ColorStateListDrawableTest.java
index 7487e55..5218a4fd 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ColorStateListDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ColorStateListDrawableTest.java
@@ -18,15 +18,21 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import android.R;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.LightingColorFilter;
import android.graphics.PixelFormat;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.ColorStateListDrawable;
import android.graphics.drawable.Drawable;
+import android.os.SystemClock;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -78,6 +84,15 @@
}
@Test
+ public void testHasFocusStateSpecified() {
+ assertFalse(mDrawable.hasFocusStateSpecified());
+ final int[][] state = new int[][]{new int[]{1}, new int[]{2, R.attr.state_focused}};
+ final int[] colors = new int[]{Color.MAGENTA, Color.CYAN};
+ mDrawable.setColorStateList(new ColorStateList(state, colors));
+ assertTrue(mDrawable.hasFocusStateSpecified());
+ }
+
+ @Test
public void testAlpha() {
int transBlue = (Color.BLUE & 0xFFFFFF) | 127 << 24;
mDrawable.setColorStateList(ColorStateList.valueOf(transBlue));
@@ -99,6 +114,31 @@
}
@Test
+ public void testColorFilter() {
+ final ColorDrawable colorDrawable = (ColorDrawable) mDrawable.getCurrent();
+ final ColorFilter colorFilter = new LightingColorFilter(Color.GRAY, Color.GREEN);
+
+ assertNull(mDrawable.getColorFilter());
+ mDrawable.setColorFilter(colorFilter);
+ assertEquals(colorFilter, mDrawable.getColorFilter());
+ }
+
+ @Test
+ public void testColorStateListAccess() {
+ final ColorStateListDrawable cslDrawable = new ColorStateListDrawable();
+ final ColorDrawable colorDrawable = (ColorDrawable) cslDrawable.getCurrent();
+ assertNotNull(cslDrawable.getColorStateList());
+ assertEquals(
+ colorDrawable.getColor(),
+ cslDrawable
+ .getColorStateList()
+ .getColorForState(cslDrawable.getState(), Color.YELLOW));
+
+ cslDrawable.setColorStateList(mColorStateList);
+ assertEquals(mColorStateList, cslDrawable.getColorStateList());
+ }
+
+ @Test
public void testSetState() {
ColorDrawable colorDrawable = (ColorDrawable) mDrawable.getCurrent();
assertEquals(colorDrawable.getColor(), mColorStateList.getDefaultColor());
@@ -114,4 +154,79 @@
assertEquals(mDrawable.mutate(), mDrawable);
assertNotEquals(mDrawable.getConstantState(), oldState);
}
+
+ @Test
+ public void testInvalidationCallbackProxy() {
+ final TestCallback callback = new TestCallback();
+ mDrawable.setCallback(callback);
+
+ callback.mInvalidatedDrawable = null;
+ mDrawable.invalidateSelf();
+ assertEquals(mDrawable, callback.mInvalidatedDrawable);
+
+ callback.mInvalidatedDrawable = null;
+ mDrawable.getCurrent().invalidateSelf();
+ assertEquals(mDrawable, callback.mInvalidatedDrawable);
+ }
+
+ @Test
+ public void testScheduleCallbackProxy() {
+ final Runnable runnable = new NoOpRunnable();
+ final long scheduledTime = SystemClock.uptimeMillis() + 100;
+ final TestCallback callback = new TestCallback();
+ mDrawable.setCallback(callback);
+
+ mDrawable.getCurrent().scheduleSelf(runnable, scheduledTime);
+ assertEquals(mDrawable, callback.mScheduledDrawable);
+ assertEquals(runnable, callback.mScheduledRunnable);
+ assertEquals(scheduledTime, callback.mScheduledTime);
+ }
+
+ @Test
+ public void testUnscheduleCallbackProxy() {
+ final Runnable runnable = new NoOpRunnable();
+ final TestCallback callback = new TestCallback();
+ mDrawable.setCallback(callback);
+
+ mDrawable.getCurrent().unscheduleSelf(runnable);
+
+ assertEquals(mDrawable, callback.mUnscheduledDrawable);
+ assertEquals(runnable, callback.mUnscheduledRunnable);
+ }
+
+ private final class TestCallback implements Drawable.Callback {
+ private Drawable mInvalidatedDrawable;
+ private Drawable mScheduledDrawable;
+ private Drawable mUnscheduledDrawable;
+
+ private Runnable mScheduledRunnable;
+ private Runnable mUnscheduledRunnable;
+
+ private long mScheduledTime;
+
+ @Override
+ public void invalidateDrawable(Drawable who) {
+ mInvalidatedDrawable = who;
+ }
+
+ @Override
+ public void scheduleDrawable(Drawable who, Runnable what, long when) {
+ mScheduledDrawable = who;
+ mScheduledRunnable = what;
+ mScheduledTime = when;
+ }
+
+ @Override
+ public void unscheduleDrawable(Drawable who, Runnable what) {
+ mUnscheduledDrawable = who;
+ mUnscheduledRunnable = what;
+ }
+ }
+
+ private final class NoOpRunnable implements Runnable {
+ @Override
+ public void run() {
+
+ }
+ }
}
diff --git a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
index c00ae3b..0228f6e 100644
--- a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
+++ b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
@@ -29,6 +29,7 @@
#include <unistd.h>
#include <queue>
+#include <regex>
#include <string>
#include <unordered_set>
#include <vector>
@@ -39,37 +40,44 @@
#include <nativehelper/ScopedUtfChars.h>
#if defined(__LP64__)
-static const std::string kSystemLibraryPath = "/system/lib64";
-static const std::string kVendorLibraryPath = "/vendor/lib64";
-static const std::string kProductLibraryPath = "/product/lib64";
+#define LIB_DIR "lib64"
#else
-static const std::string kSystemLibraryPath = "/system/lib";
-static const std::string kVendorLibraryPath = "/vendor/lib";
-static const std::string kProductLibraryPath = "/product/lib";
+#define LIB_DIR "lib"
#endif
+static const std::string kSystemLibraryPath = "/system/" LIB_DIR;
+static const std::string kRuntimeApexLibraryPath = "/apex/com.android.runtime/" LIB_DIR;
+static const std::string kVendorLibraryPath = "/vendor/" LIB_DIR;
+static const std::string kProductLibraryPath = "/product/" LIB_DIR;
+
+static const std::vector<std::regex> kSystemPathRegexes = {
+ std::regex("/system/lib(64)?"),
+ std::regex("/apex/com\\.android\\.[^/]*/lib(64)?"),
+};
+
static const std::string kWebViewPlatSupportLib = "libwebviewchromium_plat_support.so";
-// This is not the complete list - just a small subset
-// of the libraries that should reside in /system/lib
-// for app-compatibility reasons.
-// (in addition to kSystemPublicLibraries)
+// This is not the complete list - just a small subset of the libraries that
+// should not be loaded from vendor locations.
+//
+// TODO(b/124049505): Do not hardcode expected paths here, to allow libraries to
+// migrate between /system and APEXes.
static std::vector<std::string> kSystemLibraries = {
- "libart.so",
- "libandroid_runtime.so",
- "libbinder.so",
- "libcrypto.so",
- "libcutils.so",
- "libexpat.so",
- "libgui.so",
- "libmedia.so",
- "libnativehelper.so",
- "libstagefright.so",
- "libsqlite.so",
- "libui.so",
- "libutils.so",
- "libvorbisidec.so",
- };
+ kRuntimeApexLibraryPath + "/libart.so",
+ kRuntimeApexLibraryPath + "/libnativehelper.so",
+ kSystemLibraryPath + "/libandroid_runtime.so",
+ kSystemLibraryPath + "/libbinder.so",
+ kSystemLibraryPath + "/libcrypto.so",
+ kSystemLibraryPath + "/libcutils.so",
+ kSystemLibraryPath + "/libexpat.so",
+ kSystemLibraryPath + "/libgui.so",
+ kSystemLibraryPath + "/libmedia.so",
+ kSystemLibraryPath + "/libsqlite.so",
+ kSystemLibraryPath + "/libstagefright.so",
+ kSystemLibraryPath + "/libui.so",
+ kSystemLibraryPath + "/libutils.so",
+ kSystemLibraryPath + "/libvorbisidec.so",
+};
static bool is_directory(const char* path) {
struct stat sb;
@@ -107,7 +115,8 @@
// Tests if a file can be loaded or not. Returns empty string on success. On any failure
// returns the error message from dlerror().
-static std::string load_library(JNIEnv* env, jclass clazz, const std::string& path) {
+static std::string load_library(JNIEnv* env, jclass clazz, const std::string& path,
+ bool test_system_load_library) {
// try to load the lib using dlopen().
void *handle = dlopen(path.c_str(), RTLD_NOW);
std::string error;
@@ -127,16 +136,40 @@
// try to load the same lib using System.load() in Java to see if it gives consistent
// result with dlopen.
- static jmethodID load_library = env->GetStaticMethodID(clazz, "loadSharedLibrary",
- "(Ljava/lang/String;)Z");
- jstring jpath = env->NewStringUTF(path.c_str());
- bool loaded_in_java = env->CallStaticBooleanMethod(clazz, load_library, jpath) == JNI_TRUE;
- env->DeleteLocalRef(jpath);
- if (loaded_in_native != loaded_in_java) {
- error = "Inconsistent result for library \"" + path + "\":" +
- " dlopen() was " + (loaded_in_native ? "success" : "failure") +
- ", System.loadLibrary() was " + (loaded_in_java ? "success" : "failure");
- } else if (loaded_in_java) {
+ static jmethodID java_load =
+ env->GetStaticMethodID(clazz, "loadWithSystemLoad", "(Ljava/lang/String;)Ljava/lang/String;");
+ ScopedLocalRef<jstring> jpath(env, env->NewStringUTF(path.c_str()));
+ jstring java_load_errmsg = jstring(env->CallStaticObjectMethod(clazz, java_load, jpath.get()));
+ bool java_load_ok = env->GetStringLength(java_load_errmsg) == 0;
+
+ jstring java_load_lib_errmsg;
+ bool java_load_lib_ok = java_load_ok;
+ if (test_system_load_library && java_load_ok) {
+ // If System.load() works then test System.loadLibrary() too. Cannot test
+ // the other way around since System.loadLibrary() might very well find the
+ // library somewhere else and hence work when System.load() fails.
+ std::string baselib = basename(path.c_str());
+ ScopedLocalRef<jstring> jname(env, env->NewStringUTF(baselib.c_str()));
+ static jmethodID java_load_lib = env->GetStaticMethodID(
+ clazz, "loadWithSystemLoadLibrary", "(Ljava/lang/String;)Ljava/lang/String;");
+ java_load_lib_errmsg = jstring(env->CallStaticObjectMethod(clazz, java_load_lib, jname.get()));
+ java_load_lib_ok = env->GetStringLength(java_load_lib_errmsg) == 0;
+ }
+
+ if (loaded_in_native != java_load_ok || java_load_ok != java_load_lib_ok) {
+ const std::string java_load_error(ScopedUtfChars(env, java_load_errmsg).c_str());
+ error = "Inconsistent result for library \"" + path + "\": dlopen() " +
+ (loaded_in_native ? "succeeded" : "failed (" + error + ")") +
+ ", System.load() " +
+ (java_load_ok ? "succeeded" : "failed (" + java_load_error + ")");
+ if (test_system_load_library) {
+ const std::string java_load_lib_error(ScopedUtfChars(env, java_load_lib_errmsg).c_str());
+ error += ", System.loadLibrary() " +
+ (java_load_lib_ok ? "succeeded" : "failed (" + java_load_lib_error + ")");
+ }
+ }
+
+ if (loaded_in_native && java_load_ok) {
// Unload the shared lib loaded in Java. Since we don't have a method in Java for unloading a
// lib other than destroying the classloader, here comes a trick; we open the same library
// again with dlopen to get the handle for the lib and then calls dlclose twice (since we have
@@ -144,7 +177,7 @@
// the same handle for the same shared lib object.
handle = dlopen(path.c_str(), RTLD_NOW);
dlclose(handle);
- dlclose(handle); // don't delete this line. it's not a mistake.
+ dlclose(handle); // don't delete this line. it's not a mistake (see comment above).
}
return error;
@@ -156,7 +189,7 @@
const std::unordered_set<std::string>& library_search_paths,
const std::unordered_set<std::string>& libraries,
std::vector<std::string>* errors) {
- std::string err = load_library(env, clazz, path);
+ std::string err = load_library(env, clazz, path, /*test_system_load_library=*/true);
bool loaded = err.empty();
// The current restrictions on public libraries:
@@ -329,33 +362,38 @@
std::vector<std::string> library_search_paths = android::base::Split(default_search_paths, ":");
- // Remove everything pointing outside of /system/lib*
+ // Remove everything pointing outside of /system/lib* and
+ // /apex/com.android.*/lib*.
std::unordered_set<std::string> system_library_search_paths;
for (const auto& path : library_search_paths) {
- if (android::base::StartsWith(path, "/system/lib")) {
- system_library_search_paths.insert(path);
+ for (const auto& regex : kSystemPathRegexes) {
+ if (std::regex_match(path, regex)) {
+ system_library_search_paths.insert(path);
+ break;
+ }
}
}
- // This path should be tested too - this is because apps may rely on some
- // libraries being available in /system/${LIB}/
+ // These paths should be tested too - this is because apps may rely on some
+ // libraries being available there.
system_library_search_paths.insert(kSystemLibraryPath);
+ system_library_search_paths.insert(kRuntimeApexLibraryPath);
if (!check_path(env, clazz, kSystemLibraryPath, system_library_search_paths,
system_public_libraries, &errors)) {
success = false;
}
- // Check that the mandatory system libraries are present - the grey list
- for (const auto& name : kSystemLibraries) {
- std::string library = kSystemLibraryPath + "/" + name;
- std::string err = load_library(env, clazz, library);
+ // Check that the mandatory system + APEX libraries are present - the grey list
+ for (const auto& library : kSystemLibraries) {
+ std::string err = load_library(env, clazz, library, /*test_system_load_library=*/false);
if (!err.empty()) {
// The libraries should be present and produce specific dlerror when inaccessible.
if (!not_accessible(err)) {
- errors.push_back("Mandatory system library \"" + library + "\" failed to load with unexpected error: " + err);
- success = false;
+ errors.push_back("Mandatory system library \"" + library +
+ "\" failed to load with unexpected error: " + err);
+ success = false;
}
}
}
@@ -384,4 +422,3 @@
return nullptr;
}
-
diff --git a/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
index 59f6cb1..634350f 100644
--- a/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
+++ b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
@@ -226,26 +226,39 @@
return nativePath;
}
- private static boolean loadSharedLibrary(String libFilePath) {
+ private static boolean isAlreadyOpenedError(UnsatisfiedLinkError e, String libFilePath) {
+ // If one of the public system libraries are already opened in the bootclassloader, consider
+ // this try as success, because dlopen to the lib is successful.
String baseName = new File(libFilePath).getName();
+ return e.getMessage().contains("Shared library \"" + libFilePath +
+ "\" already opened by ClassLoader") &&
+ Arrays.asList(PUBLIC_SYSTEM_LIBRARIES).contains(baseName);
+ }
+
+ private static String loadWithSystemLoad(String libFilePath) {
try {
System.load(libFilePath);
- // Also ensure that the lib is also accessible via its libname.
- // Drop 'lib' and '.so' from the name
- System.loadLibrary(baseName.substring(3, baseName.length()-3));
- return true;
} catch (UnsatisfiedLinkError e) {
// all other exceptions are just thrown
- if (e.getMessage().contains("Shared library \"" + libFilePath +
- "\" already opened by ClassLoader") &&
- Arrays.asList(PUBLIC_SYSTEM_LIBRARIES).contains(baseName)) {
- // If one of the public system libraries are already opened in the
- // bootclassloader, consider this try as success, because dlopen to the lib
- // is successful.
- return true;
+ if (!isAlreadyOpenedError(e, libFilePath)) {
+ return "System.load() UnsatisfiedLinkError: " + e.getMessage();
}
- return false;
}
+ return "";
+ }
+
+ private static String loadWithSystemLoadLibrary(String libFileName) {
+ // Drop 'lib' and '.so' from the base name
+ String libName = libFileName.substring(3, libFileName.length()-3);
+ try {
+ System.loadLibrary(libName);
+ } catch (UnsatisfiedLinkError e) {
+ if (!isAlreadyOpenedError(e, libFileName)) {
+ return "System.loadLibrary(\"" + libName + "\") UnsatisfiedLinkError: " +
+ e.getMessage();
+ }
+ }
+ return "";
}
// Verify the behaviour of native library loading in class loaders.
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java
index 437948f..2ec15de 100644
--- a/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java
@@ -41,6 +41,7 @@
measurement.setCarrierPhaseUncertainty(7.0);
measurement.setCn0DbHz(8.0);
measurement.setCodeType(GnssMeasurement.CODE_TYPE_C);
+ measurement.setOtherCodeTypeName("G");
measurement.setConstellationType(GnssStatus.CONSTELLATION_GALILEO);
measurement.setMultipathIndicator(GnssMeasurement.MULTIPATH_INDICATOR_DETECTED);
measurement.setPseudorangeRateMetersPerSecond(9.0);
@@ -66,6 +67,7 @@
assertEquals(GnssMeasurement.MULTIPATH_INDICATOR_DETECTED,
measurement.getMultipathIndicator());
assertEquals(GnssMeasurement.CODE_TYPE_C, measurement.getCodeType());
+ assertEquals("G", measurement.getOtherCodeTypeName());
assertEquals(9.0, measurement.getPseudorangeRateMetersPerSecond());
assertEquals(10.0, measurement.getPseudorangeRateUncertaintyMetersPerSecond());
assertEquals(11, measurement.getReceivedSvTimeNanos());
diff --git a/tests/tests/location/src/android/location/cts/GnssTestCase.java b/tests/tests/location/src/android/location/cts/GnssTestCase.java
index 62c38c88..a128c95 100644
--- a/tests/tests/location/src/android/location/cts/GnssTestCase.java
+++ b/tests/tests/location/src/android/location/cts/GnssTestCase.java
@@ -19,7 +19,6 @@
import android.os.SystemProperties;
import android.test.AndroidTestCase;
import android.util.Log;
-import android.content.pm.PackageManager;
/**
* Base Test Case class for all Gnss Tests.
@@ -38,8 +37,7 @@
// On devices using newer hardware, GNSS measurement support is required.
protected boolean isMeasurementTestStrict() {
// Enforce strict measurement test on devices with first API level at least P.
- if (SystemProperties.getInt("ro.product.first_api_level", 0) >= Build.VERSION_CODES.P &&
- !getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+ if (SystemProperties.getInt("ro.product.first_api_level", 0) >= Build.VERSION_CODES.P) {
return true;
}
diff --git a/tests/tests/media/res/values/exifinterface.xml b/tests/tests/media/res/values/exifinterface.xml
index f4f648d..11c2efd 100644
--- a/tests/tests/media/res/values/exifinterface.xml
+++ b/tests/tests/media/res/values/exifinterface.xml
@@ -17,7 +17,7 @@
<resources>
<array name="exifbyteorderii_jpg">
<item>true</item>
- <item>3112</item>
+ <item>3500</item>
<item>6265</item>
<item>512</item>
<item>288</item>
@@ -61,7 +61,7 @@
<item>0</item>
<item>false</item>
<item>true</item>
- <item>675</item>
+ <item>572</item>
<item>24</item>
<item>0.0</item>
<item>0.0</item>
@@ -175,7 +175,7 @@
<item />
<item />
<item>true</item>
- <item>3081</item>
+ <item>3143</item>
<item>24</item>
<item>37.423</item>
<item>-122.162</item>
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
index 6301258..f1594af 100644
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
@@ -277,6 +277,8 @@
}
mDecodingSurface = new OutputSurface(w, h);
mDecoder.configure(decoderFormat, mDecodingSurface.getSurface(), null, 0);
+ // only scale to fit scaling mode is supported
+ mDecoder.setVideoScalingMode(MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
mDecoder.start();
mDecoderInputBuffers = mDecoder.getInputBuffers();
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
index 3408545..bd36a54 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
@@ -192,7 +192,7 @@
MediaCodec codec = MediaCodec.createByCodecName(info.getName());
assertEquals(codec.getName(), info.getName());
-
+ assertEquals(codec.getCanonicalName(), info.getCanonicalName());
assertEquals(codec.getCodecInfo(), info);
codec.release();
diff --git a/tests/tests/notificationlegacy/notificationlegacy27/src/android/app/notification/legacy/cts/ConditionProviderServiceTest.java b/tests/tests/notificationlegacy/notificationlegacy27/src/android/app/notification/legacy/cts/ConditionProviderServiceTest.java
index 86b1ba0..a841486 100644
--- a/tests/tests/notificationlegacy/notificationlegacy27/src/android/app/notification/legacy/cts/ConditionProviderServiceTest.java
+++ b/tests/tests/notificationlegacy/notificationlegacy27/src/android/app/notification/legacy/cts/ConditionProviderServiceTest.java
@@ -33,6 +33,7 @@
import android.content.Context;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
+import android.service.notification.Condition;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.util.ArraySet;
@@ -240,6 +241,26 @@
}
}
+ @Test
+ public void testMethodsExistAndDoNotThrow() throws Exception {
+ // behavior is covered in cts verifier
+
+ if (mActivityManager.isLowRamDevice()) {
+ return;
+ }
+
+ // make sure it gets bound
+ pollForConnection(LegacyConditionProviderService.class, true);
+
+ // request unbind
+ LegacyConditionProviderService.getInstance().onConnected();
+ LegacyConditionProviderService.getInstance().onRequestConditions(
+ Condition.FLAG_RELEVANT_NOW);
+ LegacyConditionProviderService.getInstance().onSubscribe(Uri.EMPTY);
+ LegacyConditionProviderService.getInstance().onUnsubscribe(Uri.EMPTY);
+
+ }
+
private void addRule(ComponentName cn, int filter, boolean enabled) {
String id = mNm.addAutomaticZenRule(new AutomaticZenRule("name",
cn, Uri.EMPTY, filter, enabled));
diff --git a/tests/tests/os/jni/Android.bp b/tests/tests/os/jni/Android.bp
new file mode 100644
index 0000000..752146f
--- /dev/null
+++ b/tests/tests/os/jni/Android.bp
@@ -0,0 +1,82 @@
+// Copyright (C) 2010 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_defaults {
+ name: "libctsos_jni_defaults",
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-parameter",
+ "-Wno-inline-asm",
+ "-Wno-unused-const-variable",
+ ],
+
+ shared_libs: [
+ "libnativehelper_compat_libc++",
+ "liblog",
+ "libdl",
+ "libandroid",
+ ],
+ stl: "libc++_static",
+}
+
+cc_library_shared {
+ name: "libctsos_jni",
+ defaults: ["libctsos_jni_defaults"],
+
+ srcs: [
+ "CtsOsJniOnLoad.cpp",
+ "android_os_cts_TaggedPointer.cpp",
+ "android_os_cts_HardwareName.cpp",
+ "android_os_cts_OSFeatures.cpp",
+ "android_os_cts_NoExecutePermissionTest.cpp",
+ "android_os_cts_SeccompTest.cpp",
+ "android_os_cts_SharedMemory.cpp",
+ "android_os_cts_SPMITest.cpp",
+ ],
+
+ whole_static_libs: ["libctsos_jni_arm"],
+ static_libs: [
+ "libminijail",
+ "external_seccomp_tests",
+ ],
+
+ // This define controls the behavior of OSFeatures.needsSeccompSupport().
+ // TODO(b/124189460): This was reset before use in Android.mk
+ //cflags: ["-DARCH_SUPPORTS_SECCOMP"],
+}
+
+cc_library_static {
+ name: "libctsos_jni_arm",
+ defaults: ["libctsos_jni_defaults"],
+
+ srcs: ["android_os_cts_CpuInstructions.cpp"],
+
+ arch: {
+ arm: {
+ cppflags: [
+ // Let's overwrite -mcpu in case it's set to some ARMv8 core by
+ // TARGET_2ND_CPU_VARIANT and causes clang to ignore the -march below.
+ "-mcpu=generic",
+
+ // The ARM version of this library must be built using ARMv7 ISA (even if it
+ // can be run on armv8 cores) since one of the tested instruction, swp, is
+ // only supported in ARMv7 (and older) cores, and obsolete in ARMv8.
+ "-march=armv7-a",
+ ],
+ instruction_set: "arm",
+ },
+ },
+}
diff --git a/tests/tests/os/jni/Android.mk b/tests/tests/os/jni/Android.mk
deleted file mode 100644
index 58b9d01..0000000
--- a/tests/tests/os/jni/Android.mk
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (C) 2010 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 := libctsos_jni
-
-# Don't include this package in any configuration by default.
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := \
- CtsOsJniOnLoad.cpp \
- android_os_cts_CpuInstructions.cpp.arm \
- android_os_cts_TaggedPointer.cpp \
- android_os_cts_HardwareName.cpp \
- android_os_cts_OSFeatures.cpp \
- android_os_cts_NoExecutePermissionTest.cpp \
- android_os_cts_SeccompTest.cpp \
- android_os_cts_SharedMemory.cpp \
- android_os_cts_SPMITest.cpp
-
-LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
-
-LOCAL_SHARED_LIBRARIES := libnativehelper_compat_libc++ liblog libdl libandroid
-LOCAL_CXX_STL := none
-
-LOCAL_STATIC_LIBRARIES := libc++_static libminijail
-
-# Select the architectures on which seccomp-bpf are supported. This is used to
-# include extra test files that will not compile on architectures where it is
-# not supported.
-ARCH_SUPPORTS_SECCOMP := 1
-ifeq ($(strip $(TARGET_ARCH)),mips)
- ARCH_SUPPORTS_SECCOMP = 0
-endif
-ifeq ($(strip $(TARGET_ARCH)),mips64)
- ARCH_SUPPORTS_SECCOMP = 0
-endif
-
-ifeq ($(ARCH_SUPPORTS_SECCOMP),1)
- LOCAL_STATIC_LIBRARIES += external_seccomp_tests
-
- # This define controls the behavior of OSFeatures.needsSeccompSupport().
- LOCAL_CFLAGS += -DARCH_SUPPORTS_SECCOMP
-endif
-
-LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter
-LOCAL_CFLAGS += -Wno-inline-asm -Wno-unused-const-variable
-
-# Let's overwrite -mcpu in case it's set to some ARMv8 core by
-# TARGET_2ND_CPU_VARIANT and causes clang to ignore the -march below.
-LOCAL_CPPFLAGS_arm := -mcpu=generic
-
-# The ARM version of this library must be built using ARMv7 ISA (even if it
-# can be run on armv8 cores) since one of the tested instruction, swp, is
-# only supported in ARMv7 (and older) cores, and obsolete in ARMv8.
-LOCAL_CPPFLAGS_arm += -march=armv7-a
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java b/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
index a4f956b..0b03458 100644
--- a/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
@@ -151,8 +151,8 @@
}
@Test
- public void testToString() {
- ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
+ public void testToString() throws Exception {
+ ParcelFileDescriptor pfd = makeParcelFileDescriptor(getContext());
assertNotNull(pfd.toString());
}
@@ -206,8 +206,8 @@
}
@Test
- public void testGetFileDescriptor() {
- ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
+ public void testGetFileDescriptor() throws Exception {
+ ParcelFileDescriptor pfd = makeParcelFileDescriptor(getContext());
assertNotNull(pfd.getFileDescriptor());
ParcelFileDescriptor p = new ParcelFileDescriptor(pfd);
@@ -215,8 +215,8 @@
}
@Test
- public void testDescribeContents() {
- ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
+ public void testDescribeContents() throws Exception{
+ ParcelFileDescriptor pfd = makeParcelFileDescriptor(getContext());
assertTrue((Parcelable.CONTENTS_FILE_DESCRIPTOR & pfd.describeContents()) != 0);
}
diff --git a/tests/tests/preference/Android.bp b/tests/tests/preference/Android.bp
new file mode 100644
index 0000000..23b3224
--- /dev/null
+++ b/tests/tests/preference/Android.bp
@@ -0,0 +1,36 @@
+// Copyright (C) 2010 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test {
+ name: "CtsPreferenceTestCases",
+ defaults: ["cts_defaults"],
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ "cts_instant",
+ ],
+
+ static_libs: ["ctstestrunner"],
+
+ libs: [
+ "android.test.runner.stubs",
+ "android.test.base.stubs",
+ ],
+
+ srcs: ["src/**/*.java"],
+
+ sdk_version: "test_current",
+}
diff --git a/tests/tests/preference/Android.mk b/tests/tests/preference/Android.mk
deleted file mode 100644
index 5398722..0000000
--- a/tests/tests/preference/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2010 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 := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
-
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsPreferenceTestCases
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/preference2/Android.bp b/tests/tests/preference2/Android.bp
new file mode 100644
index 0000000..51e446f
--- /dev/null
+++ b/tests/tests/preference2/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test {
+ name: "CtsPreference2TestCases",
+ defaults: ["cts_defaults"],
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ "cts_instant",
+ ],
+
+ static_libs: [
+ "ctstestrunner",
+ "compatibility-device-util",
+ "mockito-target-minus-junit4",
+ "ub-uiautomator",
+ ],
+
+ libs: [
+ "android.test.runner.stubs",
+ "android.test.base.stubs",
+ ],
+
+ srcs: ["src/**/*.java"],
+
+ sdk_version: "test_current",
+}
diff --git a/tests/tests/preference2/Android.mk b/tests/tests/preference2/Android.mk
deleted file mode 100644
index 8fc5ee2..0000000
--- a/tests/tests/preference2/Android.mk
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (C) 2012 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_PACKAGE_NAME := CtsPreference2TestCases
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- ctstestrunner \
- compatibility-device-util \
- mockito-target-minus-junit4 \
- ub-uiautomator
-
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java b/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java
index 2d15765..d4ac9a3 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java
@@ -18,6 +18,8 @@
import static android.provider.cts.MediaStoreTest.TAG;
import static android.provider.cts.ProviderTestUtils.containsId;
+import static android.provider.cts.ProviderTestUtils.getRawFile;
+import static android.provider.cts.ProviderTestUtils.getRawFileHash;
import static android.provider.cts.ProviderTestUtils.hash;
import static org.junit.Assert.assertArrayEquals;
@@ -55,7 +57,6 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
-import java.util.regex.Pattern;
@RunWith(Parameterized.class)
public class MediaStorePendingTest {
@@ -425,27 +426,4 @@
return session.publish();
}
}
-
- private static File getRawFile(Uri uri) throws Exception {
- final String res = ProviderTestUtils.executeShellCommand(
- "content query --uri " + uri + " --projection _data",
- InstrumentationRegistry.getInstrumentation().getUiAutomation());
- final int i = res.indexOf("_data=");
- if (i >= 0) {
- return new File(res.substring(i + 6));
- } else {
- throw new FileNotFoundException("Failed to find _data for " + uri + "; found " + res);
- }
- }
-
- private static String getRawFileHash(File file) throws Exception {
- final String res = ProviderTestUtils.executeShellCommand(
- "sha1sum " + file.getAbsolutePath(),
- InstrumentationRegistry.getInstrumentation().getUiAutomation());
- if (Pattern.matches("[0-9a-fA-F]{40}.+", res)) {
- return res.substring(0, 40);
- } else {
- throw new FileNotFoundException("Failed to find hash for " + file + "; found " + res);
- }
- }
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStorePlacementTest.java b/tests/tests/provider/src/android/provider/cts/MediaStorePlacementTest.java
new file mode 100644
index 0000000..2259a44
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/MediaStorePlacementTest.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2019 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.provider.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Environment;
+import android.provider.MediaStore;
+import android.provider.MediaStore.MediaColumns;
+import android.support.test.InstrumentationRegistry;
+import android.util.Log;
+import android.util.Pair;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.io.File;
+
+@RunWith(Parameterized.class)
+public class MediaStorePlacementTest {
+ static final String TAG = "MediaStorePlacementTest";
+
+ private Context mContext;
+ private ContentResolver mContentResolver;
+
+ private Uri mExternalImages;
+
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getTargetContext();
+ mContentResolver = mContext.getContentResolver();
+
+ Log.d(TAG, "Using volume " + mVolumeName);
+ mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
+ }
+
+ @Test
+ public void testDefault() throws Exception {
+ final Uri uri = ProviderTestUtils.stageMedia(R.drawable.scenery,
+ mExternalImages, "image/jpeg");
+
+ // By default placed under "Pictures" with sane name
+ final File before = ProviderTestUtils.getRelativeFile(uri);
+ assertTrue(before.getName().startsWith("cts"));
+ assertTrue(before.getName().endsWith("jpg"));
+ assertEquals("Pictures", before.getParent());
+ }
+
+ @Test
+ public void testIgnored() throws Exception {
+ final Uri uri = ProviderTestUtils.stageMedia(R.drawable.scenery,
+ mExternalImages, "image/jpeg");
+
+ {
+ final ContentValues values = new ContentValues();
+ values.put(MediaColumns.SIZE, 0);
+ assertEquals(0, mContentResolver.update(uri, values, null, null));
+ }
+
+ // Make sure shady paths can't be passed in
+ for (String column : new String[] {
+ MediaColumns.DISPLAY_NAME,
+ MediaColumns.PRIMARY_DIRECTORY,
+ MediaColumns.SECONDARY_DIRECTORY
+ }) {
+ final ContentValues values = new ContentValues();
+ values.put(column, "path/to/file");
+ try {
+ mContentResolver.update(uri, values, null, null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+ }
+
+ @Test
+ public void testDisplayName_SameMime() throws Exception {
+ final Uri uri = ProviderTestUtils.stageMedia(R.drawable.scenery,
+ mExternalImages, "image/jpeg");
+
+ // Movement within same MIME type is okay
+ final File before = ProviderTestUtils.getRelativeFile(uri);
+ final String name = "CTS" + System.nanoTime() + ".JPEG";
+ assertTrue(updatePlacement(uri, Pair.create(MediaColumns.DISPLAY_NAME, name)));
+
+ final File after = ProviderTestUtils.getRelativeFile(uri);
+ assertEquals(before.getParent(), after.getParent());
+ assertEquals(name, after.getName());
+ }
+
+ @Test
+ public void testDisplayName_DifferentMime() throws Exception {
+ final Uri uri = ProviderTestUtils.stageMedia(R.drawable.scenery,
+ mExternalImages, "image/jpeg");
+
+ final File before = ProviderTestUtils.getRelativeFile(uri);
+ assertTrue(before.getName().endsWith(".jpg"));
+
+ // Movement across MIME types is not okay; verify that original MIME
+ // type remains intact
+ final String name = "cts" + System.nanoTime() + ".png";
+ assertTrue(updatePlacement(uri, Pair.create(MediaColumns.DISPLAY_NAME, name)));
+
+ final File after = ProviderTestUtils.getRelativeFile(uri);
+ assertTrue(after.getName().startsWith(name));
+ assertTrue(after.getName().endsWith(".jpg"));
+ }
+
+ @Test
+ public void testDirectory_Valid() throws Exception {
+ final Uri uri = ProviderTestUtils.stageMedia(R.drawable.scenery,
+ mExternalImages, "image/jpeg");
+
+ final File before = ProviderTestUtils.getRelativeFile(uri);
+ assertEquals("Pictures", before.getParent());
+
+ {
+ assertTrue(updatePlacement(uri,
+ Pair.create(MediaColumns.PRIMARY_DIRECTORY, null)));
+ final File after = ProviderTestUtils.getRelativeFile(uri);
+ assertEquals("Pictures", after.getParent());
+ }
+ {
+ assertTrue(updatePlacement(uri,
+ Pair.create(MediaColumns.PRIMARY_DIRECTORY, Environment.DIRECTORY_DCIM),
+ Pair.create(MediaColumns.SECONDARY_DIRECTORY, "Vacation")));
+ final File after = ProviderTestUtils.getRelativeFile(uri);
+ assertEquals("DCIM/Vacation", after.getParent());
+ }
+ {
+ assertTrue(updatePlacement(uri,
+ Pair.create(MediaColumns.SECONDARY_DIRECTORY, "Misc")));
+ final File after = ProviderTestUtils.getRelativeFile(uri);
+ assertEquals("DCIM/Misc", after.getParent());
+ }
+ {
+ assertTrue(updatePlacement(uri,
+ Pair.create(MediaColumns.PRIMARY_DIRECTORY, Environment.DIRECTORY_PICTURES)));
+ final File after = ProviderTestUtils.getRelativeFile(uri);
+ assertEquals("Pictures/Misc", after.getParent());
+ }
+ {
+ assertTrue(updatePlacement(uri,
+ Pair.create(MediaColumns.SECONDARY_DIRECTORY, null)));
+ final File after = ProviderTestUtils.getRelativeFile(uri);
+ assertEquals("Pictures", after.getParent());
+ }
+ }
+
+ @Test
+ public void testDirectory_Invalid() throws Exception {
+ final Uri uri = ProviderTestUtils.stageMedia(R.drawable.scenery,
+ mExternalImages, "image/jpeg");
+
+ assertFalse(updatePlacement(uri,
+ Pair.create(MediaColumns.PRIMARY_DIRECTORY, "Random")));
+ assertFalse(updatePlacement(uri,
+ Pair.create(MediaColumns.PRIMARY_DIRECTORY, Environment.DIRECTORY_ALARMS)));
+ }
+
+ private boolean updatePlacement(Uri uri, Pair<?, ?>... args) throws Exception {
+ final ContentValues values = new ContentValues();
+ for (Pair<?, ?> arg : args) {
+ if (arg.second != null) {
+ values.put(String.valueOf(arg.first), String.valueOf(arg.second));
+ } else {
+ values.putNull(String.valueOf(arg.first));
+ }
+ }
+ try {
+ return (mContentResolver.update(uri, values, null, null) == 1);
+ } catch (Exception tolerated) {
+ return false;
+ }
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
index 792a00b..45e4e5a 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
@@ -18,7 +18,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -36,8 +35,6 @@
import android.support.test.InstrumentationRegistry;
import android.util.Log;
-import libcore.util.HexEncoding;
-
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
@@ -48,8 +45,6 @@
import org.junit.runners.Parameterized.Parameters;
import java.io.File;
-import java.io.OutputStream;
-import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
index de1b40a..24f7ed4 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
@@ -44,12 +44,14 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -148,6 +150,58 @@
}
@Test
+ public void testInsertDownload() throws Exception {
+ final String content = "<html><body>Content</body></html>";
+ final String displayName = "cts" + System.nanoTime();
+ final String mimeType = "text/html";
+ final Uri downloadUri = Uri.parse("https://developer.android.com/overview.html");
+ final Uri refererUri = Uri.parse("https://www.android.com");
+
+ final MediaStore.PendingParams params = new MediaStore.PendingParams(
+ Downloads.EXTERNAL_CONTENT_URI, displayName, mimeType);
+ params.setDownloadUri(downloadUri);
+ params.setRefererUri(refererUri);
+
+ final Uri pendingUri = MediaStore.createPending(mContext, params);
+ assertNotNull(pendingUri);
+ mAddedUris.add(pendingUri);
+ final Uri publishUri;
+ try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
+ try (PrintWriter pw = new PrintWriter(session.openOutputStream())) {
+ pw.print(content);
+ }
+ try (OutputStream out = session.openOutputStream()) {
+ out.write(content.getBytes(StandardCharsets.UTF_8));
+ }
+ publishUri = session.publish();
+ }
+
+ try (Cursor cursor = mContentResolver.query(publishUri, null, null, null, null)) {
+ assertEquals(1, cursor.getCount());
+
+ cursor.moveToNext();
+ assertEquals(mimeType,
+ cursor.getString(cursor.getColumnIndex(Downloads.MIME_TYPE)));
+ assertEquals(displayName,
+ cursor.getString(cursor.getColumnIndex(Downloads.DISPLAY_NAME)));
+ assertEquals(downloadUri.toString(),
+ cursor.getString(cursor.getColumnIndex(Downloads.DOWNLOAD_URI)));
+ assertEquals(refererUri.toString(),
+ cursor.getString(cursor.getColumnIndex(Downloads.REFERER_URI)));
+ }
+
+ final ByteArrayOutputStream actual = new ByteArrayOutputStream();
+ try (InputStream in = mContentResolver.openInputStream(publishUri)) {
+ final byte[] buf = new byte[512];
+ int bytesRead;
+ while ((bytesRead = in.read(buf)) != -1) {
+ actual.write(buf, 0, bytesRead);
+ }
+ }
+ assertEquals(content, actual.toString(StandardCharsets.UTF_8.name()));
+ }
+
+ @Test
public void testUpdateDownload() throws Exception {
final String displayName = "cts" + System.nanoTime();
final MediaStore.PendingParams params = new MediaStore.PendingParams(
@@ -268,7 +322,7 @@
private Uri insertImage(String displayName, String description,
File file, String mimeType, int resourceId) throws Exception {
file.createNewFile();
- try (InputStream in = mContext.getResources().openRawResource(R.raw.scenery);
+ try (InputStream in = mContext.getResources().openRawResource(resourceId);
OutputStream out = new FileOutputStream(file)) {
FileUtils.copy(in, out);
}
diff --git a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
index c5c43f4..825cdc3 100644
--- a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
+++ b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
@@ -68,6 +68,9 @@
private static final Pattern BMGR_ENABLED_PATTERN = Pattern.compile(
"^Backup Manager currently (enabled|disabled)$");
+ private static final Pattern PATTERN_STORAGE_PATH = Pattern.compile(
+ "(?i)^/storage/[^/]+/(?:[0-9]+/)?");
+
static Iterable<String> getSharedVolumeNames() {
if (StorageManager.hasIsolatedStorage()) {
final Set<String> volumeNames = MediaStore
@@ -315,4 +318,37 @@
}
return false;
}
+
+ public static File getRawFile(Uri uri) throws Exception {
+ final String res = ProviderTestUtils.executeShellCommand(
+ "content query --uri " + uri + " --projection _data",
+ InstrumentationRegistry.getInstrumentation().getUiAutomation());
+ final int i = res.indexOf("_data=");
+ if (i >= 0) {
+ return new File(res.substring(i + 6));
+ } else {
+ throw new FileNotFoundException("Failed to find _data for " + uri + "; found " + res);
+ }
+ }
+
+ public static String getRawFileHash(File file) throws Exception {
+ final String res = ProviderTestUtils.executeShellCommand(
+ "sha1sum " + file.getAbsolutePath(),
+ InstrumentationRegistry.getInstrumentation().getUiAutomation());
+ if (Pattern.matches("[0-9a-fA-F]{40}.+", res)) {
+ return res.substring(0, 40);
+ } else {
+ throw new FileNotFoundException("Failed to find hash for " + file + "; found " + res);
+ }
+ }
+
+ public static File getRelativeFile(Uri uri) throws Exception {
+ final String path = getRawFile(uri).getAbsolutePath();
+ final Matcher matcher = PATTERN_STORAGE_PATH.matcher(path);
+ if (matcher.find()) {
+ return new File(path.substring(matcher.end()));
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
}
diff --git a/tests/tests/telecom/CallScreeningServiceTestApp/Android.mk b/tests/tests/telecom/CallScreeningServiceTestApp/Android.mk
index 9f140ef..ae09720 100644
--- a/tests/tests/telecom/CallScreeningServiceTestApp/Android.mk
+++ b/tests/tests/telecom/CallScreeningServiceTestApp/Android.mk
@@ -22,11 +22,11 @@
src_dirs := src
+LOCAL_AIDL_INCLUDES := $(call all-Iaidl-files-under, aidl)
+
LOCAL_SRC_FILES := $(call all-java-files-under, $(src_dirs)) \
$(call all-Iaidl-files-under, aidl)
-LOCAL_AIDL_INCLUDES := aidl/
-
LOCAL_PACKAGE_NAME := CallScreeningServiceTestApp
LOCAL_MODULE_TAGS := optional
diff --git a/tests/tests/telecom/CallScreeningServiceTestApp/AndroidManifest.xml b/tests/tests/telecom/CallScreeningServiceTestApp/AndroidManifest.xml
index c3b39a7..9dd60be6 100644
--- a/tests/tests/telecom/CallScreeningServiceTestApp/AndroidManifest.xml
+++ b/tests/tests/telecom/CallScreeningServiceTestApp/AndroidManifest.xml
@@ -30,5 +30,10 @@
<action android:name="android.telecom.cts.screeningtestapp.ACTION_CONTROL_CALL_SCREENING_SERVICE" />
</intent-filter>
</service>
+ <receiver android:name=".NuisanceCallStateReceiver">
+ <intent-filter>
+ <action android:name="android.telecom.action.NUISANCE_CALL_STATUS_CHANGED" />
+ </intent-filter>
+ </receiver>
</application>
</manifest>
diff --git a/tests/tests/telecom/CallScreeningServiceTestApp/aidl/android/telecom/cts/screeningtestapp/ICallScreeningControl.aidl b/tests/tests/telecom/CallScreeningServiceTestApp/aidl/android/telecom/cts/screeningtestapp/ICallScreeningControl.aidl
index 43c75df..62640d6 100644
--- a/tests/tests/telecom/CallScreeningServiceTestApp/aidl/android/telecom/cts/screeningtestapp/ICallScreeningControl.aidl
+++ b/tests/tests/telecom/CallScreeningServiceTestApp/aidl/android/telecom/cts/screeningtestapp/ICallScreeningControl.aidl
@@ -26,4 +26,10 @@
in Icon icon, int confidence);
void setCallResponse(boolean shouldDisallowCall, boolean shouldRejectCall,
boolean shouldSkipCallLog, boolean shouldSkipNotification);
+ void waitForNuisanceReport(long timeoutMillis);
+ boolean getIsNuisance();
+ Uri getNuisanceCallHandle();
+ int getNuisanceCallType();
+ int getNuisanceCallDuration();
+ boolean isNuisanceReportReceived();
}
diff --git a/tests/tests/telecom/CallScreeningServiceTestApp/src/android/telecom/cts/screeningtestapp/CallScreeningServiceControl.java b/tests/tests/telecom/CallScreeningServiceTestApp/src/android/telecom/cts/screeningtestapp/CallScreeningServiceControl.java
index 1563fb5..0e9e913 100644
--- a/tests/tests/telecom/CallScreeningServiceTestApp/src/android/telecom/cts/screeningtestapp/CallScreeningServiceControl.java
+++ b/tests/tests/telecom/CallScreeningServiceTestApp/src/android/telecom/cts/screeningtestapp/CallScreeningServiceControl.java
@@ -20,13 +20,18 @@
import android.content.ComponentName;
import android.content.Intent;
import android.graphics.drawable.Icon;
+import android.net.Uri;
import android.os.IBinder;
import android.telecom.CallIdentification;
import android.telecom.CallScreeningService;
import android.text.TextUtils;
import android.util.Log;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
public class CallScreeningServiceControl extends Service {
+ private static final int ASYNC_TIMEOUT = 10000;
private static final String TAG = CallScreeningServiceControl.class.getSimpleName();
public static final String CONTROL_INTERFACE_ACTION =
"android.telecom.cts.screeningtestapp.ACTION_CONTROL_CALL_SCREENING_SERVICE";
@@ -41,6 +46,8 @@
@Override
public void reset() {
mCallIdentification = null;
+ mNuisanceCallUri = null;
+ mIsNuisanceReportReceived = false;
mCallResponse = new CallScreeningService.CallResponse.Builder()
.setDisallowCall(false)
.setRejectCall(false)
@@ -79,10 +86,43 @@
.setRejectCall(shouldRejectCall)
.build();
}
+
+ @Override
+ public void waitForNuisanceReport(long timeoutMillis) {
+ try {
+ mNuisanceLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public boolean getIsNuisance() {
+ return mIsNuisanceCall;
+ }
+
+ @Override
+ public Uri getNuisanceCallHandle() {
+ return mNuisanceCallUri;
+ }
+
+ @Override
+ public int getNuisanceCallType() {
+ return mNuisanceCallType;
+ }
+
+ @Override
+ public int getNuisanceCallDuration() {
+ return mNuisanceCallDuration;
+ }
+
+ @Override
+ public boolean isNuisanceReportReceived() {
+ return mIsNuisanceReportReceived;
+ }
};
private CallIdentification mCallIdentification = null;
- private boolean mIsAcceptingCall = true;
private CallScreeningService.CallResponse mCallResponse =
new CallScreeningService.CallResponse.Builder()
.setDisallowCall(false)
@@ -90,6 +130,12 @@
.setSkipCallLog(false)
.setSkipNotification(false)
.build();
+ private CountDownLatch mNuisanceLatch = new CountDownLatch(1);
+ private boolean mIsNuisanceCall;
+ private int mNuisanceCallType;
+ private int mNuisanceCallDuration;
+ private Uri mNuisanceCallUri;
+ private boolean mIsNuisanceReportReceived = false;
public static CallScreeningServiceControl getInstance() {
return sCallScreeningServiceControl;
@@ -119,4 +165,16 @@
public CallScreeningService.CallResponse getCallResponse() {
return mCallResponse;
}
+
+ public void handleNuisanceStatusChanged(Uri handle, int callDuration, int callType,
+ boolean isNuisance) {
+ mNuisanceCallUri = handle;
+ mIsNuisanceCall = isNuisance;
+ mNuisanceCallDuration = callDuration;
+ mNuisanceCallType = callType;
+ mIsNuisanceReportReceived = true;
+ Log.i(TAG, "handleNuisanceStatusChanged - got nuisance report");
+ mNuisanceLatch.countDown();
+ }
+
}
diff --git a/tests/tests/telecom/CallScreeningServiceTestApp/src/android/telecom/cts/screeningtestapp/NuisanceCallStateReceiver.java b/tests/tests/telecom/CallScreeningServiceTestApp/src/android/telecom/cts/screeningtestapp/NuisanceCallStateReceiver.java
new file mode 100644
index 0000000..1d393f4
--- /dev/null
+++ b/tests/tests/telecom/CallScreeningServiceTestApp/src/android/telecom/cts/screeningtestapp/NuisanceCallStateReceiver.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 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.telecom.cts.screeningtestapp;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.telecom.CallScreeningService;
+import android.util.Log;
+
+public class NuisanceCallStateReceiver extends BroadcastReceiver {
+ private static String TAG = "NuisanceCallStateReceiver";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(CallScreeningService.ACTION_NUISANCE_CALL_STATUS_CHANGED)) {
+ int callDuration = intent.getIntExtra(CallScreeningService.EXTRA_CALL_DURATION, -1);
+ Uri handle = intent.getParcelableExtra(CallScreeningService.EXTRA_CALL_HANDLE);
+ int callType = intent.getIntExtra(CallScreeningService.EXTRA_CALL_TYPE, -1);
+ boolean isNuisance = intent.getBooleanExtra(CallScreeningService.EXTRA_IS_NUISANCE,
+ false);
+
+ Log.i(TAG, "onReceive - got nuisance report");
+ CallScreeningServiceControl.getInstance().handleNuisanceStatusChanged(handle,
+ callDuration, callType, isNuisance);
+ }
+ }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
index a6d9fc1..7472e48 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -695,7 +695,7 @@
* @return Randomized phone number.
*/
Uri createRandomTestNumber() {
- return Uri.fromParts("tel", String.format("%06d", new Random().nextInt(999999))
+ return Uri.fromParts("tel", String.format("16%05d", new Random().nextInt(99999))
+ String.format("%04d", new Random().nextInt(9999)), null);
}
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
index 9e131ae..cd4d5f8 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
@@ -678,6 +678,19 @@
}
/**
+ * Tests whether the getCallDirection() getter returns correct call direction.
+ */
+ public void testGetCallDirection() {
+ if (!mShouldTestTelecom) {
+ return;
+ }
+
+ assertEquals(Call.Details.DIRECTION_OUTGOING, mCall.getDetails().getCallDirection());
+ assertFalse(Call.Details.DIRECTION_INCOMING == mCall.getDetails().getCallDirection());
+ assertFalse(Call.Details.DIRECTION_UNKNOWN == mCall.getDetails().getCallDirection());
+ }
+
+ /**
* Asserts that a call's extras contain a specified key.
*
* @param call The call.
diff --git a/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java b/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
index fede567..c1de6a0 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
@@ -18,6 +18,8 @@
import static android.telecom.cts.TestUtils.*;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
import android.os.Bundle;
import android.telecom.Call;
import android.telecom.Conference;
@@ -34,6 +36,8 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
/**
* Extended suite of tests that use {@link CtsConnectionService} and {@link MockInCallService} to
@@ -87,6 +91,17 @@
assertConnectionState(mConferenceObject.getConnections().get(0), Connection.STATE_ACTIVE);
assertConnectionState(mConferenceObject.getConnections().get(1), Connection.STATE_ACTIVE);
assertConferenceState(mConferenceObject, Connection.STATE_ACTIVE);
+
+ LinkedBlockingQueue<Connection> queue = new LinkedBlockingQueue(1);
+ runWithShellPermissionIdentity(() ->
+ queue.put(mConferenceObject.getPrimaryConnection()));
+ try {
+ Connection primaryConnection = queue.poll(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertEquals(mConferenceObject.getConnections().get(0), primaryConnection);
+ } catch (InterruptedException e) {
+ fail("Couldn't get TTY mode.");
+ }
}
public void testConferenceSplit() {
diff --git a/tests/tests/telecom/src/android/telecom/cts/DefaultPhoneAccountTest.java b/tests/tests/telecom/src/android/telecom/cts/DefaultPhoneAccountTest.java
index 9d73e43..6a84634 100755
--- a/tests/tests/telecom/src/android/telecom/cts/DefaultPhoneAccountTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/DefaultPhoneAccountTest.java
@@ -16,6 +16,8 @@
package android.telecom.cts;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
@@ -58,6 +60,33 @@
}
/**
+ * Verifies that {@link TelecomManager#getUserSelectedOutgoingPhoneAccount()} is able to
+ * retrieve the user-selected outgoing phone account.
+ * Given that there is a user-selected default, also verifies that
+ * {@link TelecomManager#getDefaultOutgoingPhoneAccount(String)} reports this value as well.
+ * @throws Exception
+ */
+ public void testSetUserSelectedOutgoingPhoneAccount() throws Exception {
+ if (!mShouldTestTelecom) {
+ return;
+ }
+ // Make sure to set the default outgoing phone account to the new connection service
+ setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+
+ // Use TelecomManager API to set the outgoing phone account.
+ runWithShellPermissionIdentity(() ->
+ mTelecomManager.setUserSelectedOutgoingPhoneAccount(
+ TestUtils.TEST_PHONE_ACCOUNT_HANDLE));
+
+ PhoneAccountHandle handle = mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+ assertEquals(TestUtils.TEST_PHONE_ACCOUNT_HANDLE, handle);
+
+ PhoneAccountHandle defaultOutgoing = mTelecomManager.getDefaultOutgoingPhoneAccount(
+ PhoneAccount.SCHEME_TEL);
+ assertEquals(TestUtils.TEST_PHONE_ACCOUNT_HANDLE, defaultOutgoing);
+ }
+
+ /**
* Verifies operation of the {@link TelecomManager#getDefaultOutgoingPhoneAccount(String)} API
* where there is NO user selected default outgoing phone account.
* In AOSP, this mimics the user having changed the
diff --git a/tests/tests/telecom/src/android/telecom/cts/TelecomManagerTest.java b/tests/tests/telecom/src/android/telecom/cts/TelecomManagerTest.java
new file mode 100644
index 0000000..2247cdd
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/TelecomManagerTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 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.telecom.cts;
+
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
+import android.telecom.TelecomManager;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public class TelecomManagerTest extends BaseTelecomTestWithMockServices {
+ public void testGetCurrentTtyMode() {
+ LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue(1);
+ runWithShellPermissionIdentity(() ->
+ queue.put(mTelecomManager.getCurrentTtyMode()));
+ try {
+ int currentTtyMode = queue.poll(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertEquals(TelecomManager.TTY_MODE_OFF, currentTtyMode);
+ assertFalse(TelecomManager.TTY_MODE_FULL == currentTtyMode);
+ assertFalse(TelecomManager.TTY_MODE_HCO == currentTtyMode);
+ assertFalse(TelecomManager.TTY_MODE_VCO == currentTtyMode);
+ } catch (InterruptedException e) {
+ fail("Couldn't get TTY mode.");
+ e.printStackTrace();
+ }
+ }
+
+ public void testIsInEmergencyCall() {
+ LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1);
+ runWithShellPermissionIdentity(() ->
+ queue.put(mTelecomManager.isInEmergencyCall()));
+ try {
+ boolean isInEmergencyCall = queue.poll(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertFalse(isInEmergencyCall);
+ } catch (InterruptedException e) {
+ fail("Couldn't check if in emergency call.");
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
index 38e1a25..e772cc1 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
@@ -52,6 +52,7 @@
public class TestUtils {
static final String TAG = "TelecomCTSTests";
static final boolean HAS_TELECOM = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
+ static final long WAIT_FOR_NUISANCE_REPORT_TIMEOUT_MS = 1000;
static final long WAIT_FOR_STATE_CHANGE_TIMEOUT_MS = 10000;
static final long WAIT_FOR_CALL_ADDED_TIMEOUT_S = 15;
static final long WAIT_FOR_STATE_CHANGE_TIMEOUT_CALLBACK = 50;
diff --git a/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java
index 5ccfa3c..f594945 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ThirdPartyCallScreeningServiceTest.java
@@ -47,6 +47,7 @@
import android.telecom.cts.screeningtestapp.CtsCallScreeningService;
import android.telecom.cts.screeningtestapp.ICallScreeningControl;
import android.text.TextUtils;
+import android.util.Log;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@@ -232,33 +233,7 @@
if (!shouldTestTelecom(mContext)) {
return;
}
-
- // Tell the test app to set its call id info.
- mCallScreeningControl.setProviderCallIdentification(
- SAMPLE_CALL_ID.getName(),
- SAMPLE_CALL_ID.getDescription(),
- SAMPLE_CALL_ID.getDetails(),
- SAMPLE_CALL_ID.getPhoto(),
- SAMPLE_CALL_ID.getNuisanceConfidence());
-
- // Setup content observer to notify us when we call log entry is added.
- CountDownLatch callLogEntryLatch = getCallLogEntryLatch();
-
- Uri phoneNumber = createRandomTestNumber();
- Bundle extras = new Bundle();
- extras.putParcelable(TestUtils.EXTRA_PHONE_NUMBER, phoneNumber);
- // Create a new outgoing call.
- placeAndVerifyCall(extras);
-
- // Wait for call id to be passed back to InCallService
- assertCallIdentification(SAMPLE_CALL_ID, TEST_APP_NAME, TEST_APP_PACKAGE);
-
- // Disconnect the call
- mInCallCallbacks.getService().disconnectAllCalls();
- assertNumCalls(mInCallCallbacks.getService(), 0);
-
- // Wait for it to log.
- callLogEntryLatch.await(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS);
+ Uri phoneNumber = placeOutgoingCall();
// Query the latest entry into the call log and verify the call identification information
// was logged appropriately
@@ -310,7 +285,84 @@
assertEquals(SAMPLE_CALL_ID, unparceled);
}
- private void addIncomingAndVerifyBlocked() throws Exception {
+ /**
+ * Verifies operation of the {@link TelecomManager#reportNuisanceCallStatus(Uri, boolean)} API
+ * for an outgoing call; should not be possible to report as nuisance.
+ * @throws Exception
+ */
+ public void testReportNuisanceInvalid() throws Exception {
+ if (!shouldTestTelecom(mContext)) {
+ return;
+ }
+ Uri phoneNumber = placeOutgoingCall();
+
+ // Report the call as a nuisance call.
+ mTelecomManager.reportNuisanceCallStatus(phoneNumber, true);
+
+ // Block on the control service and wait for the nuisance report; we don't expect one so we
+ // will only wait a short time to avoid this test blocking for a long time.
+ mCallScreeningControl.waitForNuisanceReport(TestUtils.WAIT_FOR_NUISANCE_REPORT_TIMEOUT_MS);
+
+ // We should not have gotten a response back.
+ assertFalse(mCallScreeningControl.isNuisanceReportReceived());
+ }
+
+ /**
+ * Verifies operation of the {@link TelecomManager#reportNuisanceCallStatus(Uri, boolean)} API
+ * for an incoming call.
+ * @throws Exception
+ */
+ public void testReportNuisanceIncoming() throws Exception {
+ if (!shouldTestTelecom(mContext)) {
+ return;
+ }
+ Uri phoneNumber = addIncoming(true /* disconnectImmediately */);
+
+ // Disconnect the incoming call so it can be logged.
+ mInCallCallbacks.getService().disconnectAllCalls();
+ assertNumCalls(mInCallCallbacks.getService(), 0);
+
+ // Report the call as a nuisance call.
+ mTelecomManager.reportNuisanceCallStatus(phoneNumber, true);
+
+ // Block on the control service and wait for the nuisance report; we will potentially wait
+ // longer because we really do expect something here.
+ mCallScreeningControl.waitForNuisanceReport(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+
+ // We should have gotten a response back.
+ assertTrue(mCallScreeningControl.isNuisanceReportReceived());
+ }
+
+ private Uri placeOutgoingCall() throws Exception {
+ // Tell the test app to set its call id info.
+ mCallScreeningControl.setProviderCallIdentification(
+ SAMPLE_CALL_ID.getName(),
+ SAMPLE_CALL_ID.getDescription(),
+ SAMPLE_CALL_ID.getDetails(),
+ SAMPLE_CALL_ID.getPhoto(),
+ SAMPLE_CALL_ID.getNuisanceConfidence());
+
+ // Setup content observer to notify us when we call log entry is added.
+ CountDownLatch callLogEntryLatch = getCallLogEntryLatch();
+
+ Uri phoneNumber = createRandomTestNumber();
+ Bundle extras = new Bundle();
+ extras.putParcelable(TestUtils.EXTRA_PHONE_NUMBER, phoneNumber);
+ // Create a new outgoing call.
+ placeAndVerifyCall(extras);
+
+ // Wait for call id to be passed back to InCallService
+ assertCallIdentification(SAMPLE_CALL_ID, TEST_APP_NAME, TEST_APP_PACKAGE);
+
+ mInCallCallbacks.getService().disconnectAllCalls();
+ assertNumCalls(mInCallCallbacks.getService(), 0);
+
+ // Wait for it to log.
+ callLogEntryLatch.await(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS);
+ return phoneNumber;
+ }
+
+ private Uri addIncoming(boolean disconnectImmediately) throws Exception {
// Add call through TelecomManager; we can't use the test methods since they assume a call
// makes it through to the InCallService; this is blocked so it shouldn't.
Uri testNumber = createRandomTestNumber();
@@ -325,8 +377,19 @@
// Wait until the new incoming call is processed.
waitOnAllHandlers(getInstrumentation());
+ if (disconnectImmediately) {
+ // Disconnect the call
+ mInCallCallbacks.getService().disconnectAllCalls();
+ assertNumCalls(mInCallCallbacks.getService(), 0);
+ }
+
// Wait for the content observer to report that we have gotten a new call log entry.
callLogEntryLatch.await(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS);
+ return testNumber;
+ }
+
+ private void addIncomingAndVerifyBlocked() throws Exception {
+ Uri testNumber = addIncoming(false);
// Query the latest entry into the call log.
Cursor callsCursor = mContext.getContentResolver().query(CallLog.Calls.CONTENT_URI, null,
@@ -360,7 +423,7 @@
CallLog.Calls.CONTENT_URI, true,
new ContentObserver(mHandler) {
@Override
- public void onChange(boolean selfChange) {
+ public void onChange(boolean selfChange, Uri uri) {
mContext.getContentResolver().unregisterContentObserver(this);
changeLatch.countDown();
super.onChange(selfChange);
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
index eaa5722..ee3ff6e 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
@@ -22,17 +22,20 @@
import android.telephony.CellIdentityGsm;
import android.telephony.CellIdentityLte;
import android.telephony.CellIdentityNr;
+import android.telephony.CellIdentityTdscdma;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoNr;
+import android.telephony.CellInfoTdscdma;
import android.telephony.CellInfoWcdma;
import android.telephony.CellSignalStrengthCdma;
import android.telephony.CellSignalStrengthGsm;
import android.telephony.CellSignalStrengthLte;
import android.telephony.CellSignalStrengthNr;
+import android.telephony.CellSignalStrengthTdscdma;
import android.telephony.CellSignalStrengthWcdma;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
@@ -107,8 +110,10 @@
private static final int LAC = 65535;
// UMTS Cell Identity ranges from 0 to 268435455.
private static final int CID_UMTS = 268435455;
- // Primary Scrambling Coderanges from 0 to 511.
+ // Primary Scrambling Code ranges from 0 to 511.
private static final int PSC = 511;
+ // Cell Parameters Index rangest from 0-127.
+ private static final int CPID = 127;
// The followings are parameters for testing CellIdentityGsm
// GSM Cell Identity ranges from 0 to 65535.
@@ -137,7 +142,7 @@
public void testCellInfo() throws Throwable {
- if(! (mPm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY))) {
+ if(!(mPm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY))) {
Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
return;
}
@@ -164,8 +169,12 @@
verifyGsmInfo((CellInfoGsm) cellInfo);
} else if (cellInfo instanceof CellInfoCdma) {
verifyCdmaInfo((CellInfoCdma) cellInfo);
+ } else if (cellInfo instanceof CellInfoTdscdma) {
+ verifyTdscdmaInfo((CellInfoTdscdma) cellInfo);
} else if (cellInfo instanceof CellInfoNr) {
verifyNrInfo((CellInfoNr) cellInfo);
+ } else {
+ fail("Unknown CellInfo Type reported.");
}
}
@@ -212,11 +221,13 @@
int basestationId = cdma.getBasestationId();
assertTrue("getBasestationId() out of range [0,65535], basestationId=" + basestationId,
- basestationId == Integer.MAX_VALUE || (basestationId >= 0 && basestationId <= BASESTATION_ID));
+ basestationId == Integer.MAX_VALUE
+ || (basestationId >= 0 && basestationId <= BASESTATION_ID));
int longitude = cdma.getLongitude();
assertTrue("getLongitude() out of range [-2592000,2592000], longitude=" + longitude,
- longitude == Integer.MAX_VALUE || (longitude >= -LONGITUDE && longitude <= LONGITUDE));
+ longitude == Integer.MAX_VALUE
+ || (longitude >= -LONGITUDE && longitude <= LONGITUDE));
int latitude = cdma.getLatitude();
assertTrue("getLatitude() out of range [-1296000,1296000], latitude=" + latitude,
@@ -698,6 +709,103 @@
assertEquals(gsm, newCss);
}
+ // Verify tdscdma cell information is within correct range.
+ private void verifyTdscdmaInfo(CellInfoTdscdma tdscdma) {
+ verifyCellConnectionStatus(tdscdma.getCellConnectionStatus());
+ verifyCellInfoTdscdmaParcelandHashcode(tdscdma);
+ verifyCellIdentityTdscdma(tdscdma.getCellIdentity());
+ verifyCellIdentityTdscdmaParcel(tdscdma.getCellIdentity());
+ verifyCellSignalStrengthTdscdma(tdscdma.getCellSignalStrength());
+ verifyCellSignalStrengthTdscdmaParcel(tdscdma.getCellSignalStrength());
+ }
+
+ private void verifyCellInfoTdscdmaParcelandHashcode(CellInfoTdscdma tdscdma) {
+ Parcel p = Parcel.obtain();
+ tdscdma.writeToParcel(p, 0);
+ p.setDataPosition(0);
+
+ CellInfoTdscdma newCi = CellInfoTdscdma.CREATOR.createFromParcel(p);
+ assertTrue(tdscdma.equals(newCi));
+ assertEquals("hashCode() did not get right hasdCode", tdscdma.hashCode(), newCi.hashCode());
+ }
+
+ private void verifyCellIdentityTdscdma(CellIdentityTdscdma tdscdma) {
+ String mccStr = tdscdma.getMccString();
+ String mncStr = tdscdma.getMncString();
+
+ // This class was added after numeric mcc/mncs were no longer provided, so it lacks the
+ // basic getMcc() and getMnc() - Dummy out those checks.
+ verifyPlmnInfo(tdscdma.getMccString(), tdscdma.getMncString(),
+ mccStr != null ? Integer.parseInt(mccStr) : CellInfo.UNAVAILABLE,
+ mncStr != null ? Integer.parseInt(mncStr) : CellInfo.UNAVAILABLE);
+
+ int lac = tdscdma.getLac();
+ assertTrue("getLac() out of range [0, 65535], lac=" + lac,
+ (lac >= 0 && lac <= LAC) || lac == Integer.MAX_VALUE);
+
+ int cid = tdscdma.getCid();
+ assertTrue("getCid() out of range [0, 268435455], cid=" + cid,
+ (cid >= 0 && cid <= CID_UMTS) || cid == Integer.MAX_VALUE);
+
+ // Verify tdscdma primary scrambling code information.
+ // Primary scrambling code should be within [0, 511].
+ int cpid = tdscdma.getCpid();
+ assertTrue("getCpid() out of range [0, 127], cpid=" + cpid, (cpid >= 0 && cpid <= CPID));
+
+ String mobileNetworkOperator = tdscdma.getMobileNetworkOperator();
+ assertTrue("getMobileNetworkOperator() out of range [0, 999999], mobileNetworkOperator="
+ + mobileNetworkOperator,
+ mobileNetworkOperator == null
+ || mobileNetworkOperator.matches("^[0-9]{5,6}$"));
+
+ // b/123957505
+ // int uarfcn = tdscdma.getUarfcn();
+ // Reference 3GPP 25.101 Table 5.2
+ // From Appendix E.1, even though UARFCN is numbered from 400, the minumum
+ // usable channel is 412 due to the fixed bandwidth of 5Mhz
+ // assertTrue("getUarfcn() out of range [412,11000], uarfcn=" + uarfcn,
+ // uarfcn >= 412 && uarfcn <= 11000);
+
+ String alphaLong = (String) tdscdma.getOperatorAlphaLong();
+ assertNotNull("getOperatorAlphaLong() returns NULL!", alphaLong);
+
+ String alphaShort = (String) tdscdma.getOperatorAlphaShort();
+ assertNotNull("getOperatorAlphaShort() returns NULL!", alphaShort);
+ }
+
+ private void verifyCellIdentityTdscdmaParcel(CellIdentityTdscdma tdscdma) {
+ Parcel p = Parcel.obtain();
+ tdscdma.writeToParcel(p, 0);
+ p.setDataPosition(0);
+
+ CellIdentityTdscdma newci = CellIdentityTdscdma.CREATOR.createFromParcel(p);
+ assertEquals(tdscdma, newci);
+ }
+
+ private void verifyCellSignalStrengthTdscdma(CellSignalStrengthTdscdma tdscdma) {
+ verifyRssiDbm(tdscdma.getDbm());
+
+ // Dbm here does not have specific limits. So just calling to verify that it does not crash
+ // the phone
+ tdscdma.getDbm();
+
+ int asuLevel = tdscdma.getAsuLevel();
+ assertTrue("getLevel() out of range [0,31] (or 99 is unknown), level=" + asuLevel,
+ asuLevel == 99 || (asuLevel >= 0 && asuLevel <= 31));
+
+ int level = tdscdma.getLevel();
+ assertTrue("getLevel() out of range [0,4], level=" + level, level >= 0 && level <= 4);
+ }
+
+ private void verifyCellSignalStrengthTdscdmaParcel(CellSignalStrengthTdscdma tdscdma) {
+ Parcel p = Parcel.obtain();
+ tdscdma.writeToParcel(p, 0);
+ p.setDataPosition(0);
+
+ CellSignalStrengthTdscdma newCss = CellSignalStrengthTdscdma.CREATOR.createFromParcel(p);
+ assertEquals(tdscdma, newCss);
+ }
+
// Rssi(in dbm) should be within [MIN_RSSI, MAX_RSSI].
private void verifyRssiDbm(int dbm) {
assertTrue("getCellSignalStrength().getDbm() out of range, dbm=" + dbm,
diff --git a/tests/tests/theme/Android.bp b/tests/tests/theme/Android.bp
new file mode 100644
index 0000000..607f63f
--- /dev/null
+++ b/tests/tests/theme/Android.bp
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test {
+ name: "CtsThemeDeviceTestCases",
+ defaults: ["cts_defaults"],
+
+ static_libs: ["ctstestrunner"],
+
+ libs: [
+ "android.test.runner.stubs",
+ "android.test.base.stubs",
+ ],
+
+ srcs: ["src/**/*.java"],
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ ],
+
+ sdk_version: "current",
+}
diff --git a/tests/tests/transition/Android.bp b/tests/tests/transition/Android.bp
new file mode 100644
index 0000000..317ec79
--- /dev/null
+++ b/tests/tests/transition/Android.bp
@@ -0,0 +1,40 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test {
+ name: "CtsTransitionTestCases",
+ defaults: ["cts_defaults"],
+
+ static_libs: [
+ "android-support-test",
+ "mockito-target-minus-junit4",
+ "hamcrest-library",
+ "android-common",
+ "compatibility-device-util",
+ "ctstestrunner",
+ "platform-test-annotations",
+ ],
+
+ libs: ["android.test.runner.stubs"],
+
+ srcs: ["src/**/*.java"],
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ ],
+
+ sdk_version: "test_current",
+}
diff --git a/tests/tests/transition/Android.mk b/tests/tests/transition/Android.mk
deleted file mode 100644
index 5b721e0..0000000
--- a/tests/tests/transition/Android.mk
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (C) 2015 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_PACKAGE_NAME := CtsTransitionTestCases
-
-# Don't include this package in any target.
-LOCAL_MODULE_TAGS := optional
-
-# When built, explicitly put it in the data partition.
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_STATIC_JAVA_LIBRARIES += \
- android-support-test \
- mockito-target-minus-junit4 \
- hamcrest-library \
- android-common \
- compatibility-device-util \
- ctstestrunner \
- platform-test-annotations
-
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
-# Enforce public / test api only
-LOCAL_SDK_VERSION := test_current
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/uirendering/AndroidManifest.xml b/tests/tests/uirendering/AndroidManifest.xml
index cbbcfb3..d7adaf7 100644
--- a/tests/tests/uirendering/AndroidManifest.xml
+++ b/tests/tests/uirendering/AndroidManifest.xml
@@ -16,7 +16,8 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.uirendering.cts">
+ package="android.uirendering.cts"
+ android:targetSandboxVersion="2">
<uses-permission android:name="android.permission.INJECT_EVENTS" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
diff --git a/tests/tests/uirendering/AndroidTest.xml b/tests/tests/uirendering/AndroidTest.xml
index 369eb41..4661bbd 100644
--- a/tests/tests/uirendering/AndroidTest.xml
+++ b/tests/tests/uirendering/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS UI Rendering test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="uitoolkit" />
+ <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsUiRenderingTestCases.apk" />
diff --git a/tests/tests/view/AndroidManifest.xml b/tests/tests/view/AndroidManifest.xml
index 925f3e2..2c03228 100644
--- a/tests/tests/view/AndroidManifest.xml
+++ b/tests/tests/view/AndroidManifest.xml
@@ -33,7 +33,7 @@
<activity android:name="android.app.Activity"
android:label="Empty Activity"
- android:theme="@style/ViewStyleTestTheme">
+ android:theme="@style/ViewAttributeTestTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
diff --git a/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp b/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp
index dd6a186..2bfab1e 100644
--- a/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp
+++ b/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp
@@ -24,6 +24,7 @@
#include <cinttypes>
#include <string>
+#include <android/data_space.h>
#include <android/hardware_buffer.h>
#include <android/log.h>
#include <android/native_window_jni.h>
@@ -212,6 +213,10 @@
reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
reinterpret_cast<ASurfaceControl*>(surfaceControl), buffer, fence);
+ ASurfaceTransaction_setBufferDataSpace(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+ reinterpret_cast<ASurfaceControl*>(surfaceControl), ADATASPACE_UNKNOWN);
+
return reinterpret_cast<jlong>(buffer);
}
@@ -233,6 +238,10 @@
reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
reinterpret_cast<ASurfaceControl*>(surfaceControl), buffer, fence);
+ ASurfaceTransaction_setBufferDataSpace(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+ reinterpret_cast<ASurfaceControl*>(surfaceControl), ADATASPACE_UNKNOWN);
+
return reinterpret_cast<jlong>(buffer);
}
diff --git a/tests/tests/view/res/layout/view_style_layout.xml b/tests/tests/view/res/layout/view_attribute_layout.xml
similarity index 100%
rename from tests/tests/view/res/layout/view_style_layout.xml
rename to tests/tests/view/res/layout/view_attribute_layout.xml
diff --git a/tests/tests/view/res/values/styles.xml b/tests/tests/view/res/values/styles.xml
index ab984e8..5b832c6 100644
--- a/tests/tests/view/res/values/styles.xml
+++ b/tests/tests/view/res/values/styles.xml
@@ -188,7 +188,7 @@
<item name="android:windowAnimationStyle">@null</item>
</style>
- <style name="ViewStyleTestTheme" parent="@android:Theme.Material">
+ <style name="ViewAttributeTestTheme" parent="@android:Theme.Material">
<item name="android:buttonStyle">@style/MyButtonStyle</item>
</style>
diff --git a/tests/tests/view/src/android/view/animation/cts/AnimationTest.java b/tests/tests/view/src/android/view/animation/cts/AnimationTest.java
index fb9e27d..5fe1141 100644
--- a/tests/tests/view/src/android/view/animation/cts/AnimationTest.java
+++ b/tests/tests/view/src/android/view/animation/cts/AnimationTest.java
@@ -599,90 +599,6 @@
}
@Test
- public void testAddRemoveAnimationListener() throws Throwable {
- final View animWindow = mActivity.findViewById(R.id.anim_window);
-
- // XML file of R.anim.accelerate_alpha
- // <alpha xmlns:android="http://schemas.android.com/apk/res/android"
- // android:interpolator="@android:anim/accelerate_interpolator"
- // android:fromAlpha="0.1"
- // android:toAlpha="0.9"
- // android:duration="1000" />
- final Animation anim = AnimationUtils.loadAnimation(mActivity, R.anim.accelerate_alpha);
- // Speed things up a little
- anim.setDuration(10);
-
- final AnimationListener l1 = mock(AnimationListener.class);
- final AnimationListener l2 = mock(AnimationListener.class);
- final AnimationListener l3 = mock(AnimationListener.class);
- final AnimationListener l4 = mock(AnimationListener.class);
-
- // Test that adding listeners does not remove the set listener
- anim.setAnimationListener(l1);
- anim.addAnimationListener(l2);
- anim.addAnimationListener(l3);
- verifyZeroInteractions(l1, l2, l3, l4);
-
- // set: l1
- // added: l2, l3
- AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow, anim);
- verifyListeners(anim, l1, l2, l3);
- verifyZeroInteractions(l4);
-
- // Test that setting a listener does not remove the added listeners
- reset(l1, l2, l3, l4);
- anim.setAnimationListener(l4);
- verifyZeroInteractions(l1, l2, l3, l4);
-
- // set: l4
- // added: l2, l3
- AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow, anim);
- verifyListeners(anim, l2, l3, l4);
- verifyZeroInteractions(l1);
-
- // Test that removing a listener does not affect the set listener
- reset(l1, l2, l3, l4);
- anim.removeAnimationListener(l2);
- verifyZeroInteractions(l1, l2, l3, l4);
-
- // set: l4
- // added: l3
- AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow, anim);
- verifyListeners(anim, l3, l4);
- verifyZeroInteractions(l1, l2);
-
- // Test that removing the set listener does not affect the set listener
- reset(l1, l2, l3, l4);
- anim.removeAnimationListener(l4);
- verifyZeroInteractions(l1, l2, l3, l4);
-
- // set: l4
- // added: l3
- AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow, anim);
- verifyListeners(anim, l3, l4);
- verifyZeroInteractions(l1, l2);
-
- // Test that setting the set listener to null does not remove the added listeners
- reset(l1, l2, l3, l4);
- anim.setAnimationListener(null);
- verifyZeroInteractions(l1, l2, l3, l4);
-
- // set: null
- // added: l3
- AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow, anim);
- verifyListeners(anim, l3);
- verifyZeroInteractions(l1, l2, l4);
- }
-
- private void verifyListeners(Animation anim, AnimationListener... listeners) {
- for (AnimationListener listener : listeners) {
- verify(listener, times(1)).onAnimationStart(anim);
- verify(listener, times(1)).onAnimationEnd(anim);
- verify(listener, never()).onAnimationRepeat(anim);
- }
- }
-
- @Test
public void testStart() {
Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.accelerate_alpha);
animation.setStartTime(0);
diff --git a/tests/tests/view/src/android/view/cts/ViewStyleTest.java b/tests/tests/view/src/android/view/cts/ViewAttributeTest.java
similarity index 82%
rename from tests/tests/view/src/android/view/cts/ViewStyleTest.java
rename to tests/tests/view/src/android/view/cts/ViewAttributeTest.java
index 866e8b6..02766d9 100644
--- a/tests/tests/view/src/android/view/cts/ViewStyleTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewAttributeTest.java
@@ -42,7 +42,7 @@
@MediumTest
@RunWith(AndroidJUnit4.class)
-public class ViewStyleTest {
+public class ViewAttributeTest {
@Rule
public ActivityTestRule<Activity> mActivityRule =
@@ -72,7 +72,8 @@
public void testGetExplicitStyle() {
Context context = InstrumentationRegistry.getTargetContext();
LayoutInflater inflater = LayoutInflater.from(context);
- LinearLayout rootView = (LinearLayout) inflater.inflate(R.layout.view_style_layout, null);
+ LinearLayout rootView =
+ (LinearLayout) inflater.inflate(R.layout.view_attribute_layout, null);
View view1 = rootView.findViewById(R.id.view1);
assertEquals(R.style.ExplicitStyle1, view1.getExplicitStyle());
@@ -89,12 +90,17 @@
@Test
public void testGetAttributeResolutionStack() {
LayoutInflater inflater = LayoutInflater.from(mActivityRule.getActivity());
- LinearLayout rootView = (LinearLayout) inflater.inflate(R.layout.view_style_layout, null);
+ LinearLayout rootView =
+ (LinearLayout) inflater.inflate(R.layout.view_attribute_layout, null);
+ List<Integer> stackRootView = rootView.getAttributeResolutionStack();
+ assertEquals(1, stackRootView.size());
+ assertEquals(R.layout.view_attribute_layout, stackRootView.get(0).intValue());
+
// View that has an explicit style ExplicitStyle1 set via style = ...
View view1 = rootView.findViewById(R.id.view1);
List<Integer> stackView1 = view1.getAttributeResolutionStack();
assertEquals(3, stackView1.size());
- assertEquals(R.layout.view_style_layout, stackView1.get(0).intValue());
+ assertEquals(R.layout.view_attribute_layout, stackView1.get(0).intValue());
assertEquals(R.style.ExplicitStyle1, stackView1.get(1).intValue());
assertEquals(R.style.ParentOfExplicitStyle1, stackView1.get(2).intValue());
@@ -103,7 +109,7 @@
Button button1 = rootView.findViewById(R.id.button1);
List<Integer> stackButton1 = button1.getAttributeResolutionStack();
assertEquals(3, stackButton1.size());
- assertEquals(R.layout.view_style_layout, stackButton1.get(0).intValue());
+ assertEquals(R.layout.view_attribute_layout, stackButton1.get(0).intValue());
assertEquals(R.style.MyButtonStyle, stackButton1.get(1).intValue());
assertEquals(R.style.MyButtonStyleParent, stackButton1.get(2).intValue());
@@ -112,7 +118,7 @@
Button button2 = rootView.findViewById(R.id.button2);
List<Integer> stackButton2 = button2.getAttributeResolutionStack();
assertEquals(5, stackButton2.size());
- assertEquals(R.layout.view_style_layout, stackButton2.get(0).intValue());
+ assertEquals(R.layout.view_attribute_layout, stackButton2.get(0).intValue());
assertEquals(R.style.ExplicitStyle1, stackButton2.get(1).intValue());
assertEquals(R.style.ParentOfExplicitStyle1, stackButton2.get(2).intValue());
assertEquals(R.style.MyButtonStyle, stackButton2.get(3).intValue());
@@ -122,16 +128,20 @@
@Test
public void testGetAttributeSourceResourceMap() {
LayoutInflater inflater = LayoutInflater.from(mActivityRule.getActivity());
- LinearLayout rootView = (LinearLayout) inflater.inflate(R.layout.view_style_layout, null);
+ LinearLayout rootView =
+ (LinearLayout) inflater.inflate(R.layout.view_attribute_layout, null);
+ Map<Integer, Integer> attributeMapRootView = rootView.getAttributeSourceResourceMap();
+ assertEquals(R.layout.view_attribute_layout,
+ (attributeMapRootView.get(android.R.attr.orientation)).intValue());
+
// View that has an explicit style ExplicitStyle1 set via style = ...
View view1 = rootView.findViewById(R.id.view1);
Map<Integer, Integer> attributeMapView1 = view1.getAttributeSourceResourceMap();
- assertEquals(9, attributeMapView1.size());
assertEquals(R.style.ExplicitStyle1,
(attributeMapView1.get(android.R.attr.padding)).intValue());
assertEquals(R.style.ParentOfExplicitStyle1,
(attributeMapView1.get(android.R.attr.paddingLeft)).intValue());
- assertEquals(R.layout.view_style_layout,
+ assertEquals(R.layout.view_attribute_layout,
(attributeMapView1.get(android.R.attr.paddingTop)).intValue());
}
}
diff --git a/tests/tests/view/src/android/view/cts/ViewConfigurationTest.java b/tests/tests/view/src/android/view/cts/ViewConfigurationTest.java
index aa9dcf1..d8c293f 100644
--- a/tests/tests/view/src/android/view/cts/ViewConfigurationTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewConfigurationTest.java
@@ -19,9 +19,11 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.util.TypedValue;
import android.view.ViewConfiguration;
import org.junit.Test;
@@ -65,7 +67,8 @@
@Test
public void testInstanceValues() {
- ViewConfiguration vc = ViewConfiguration.get(InstrumentationRegistry.getTargetContext());
+ Context context = InstrumentationRegistry.getTargetContext();
+ ViewConfiguration vc = ViewConfiguration.get(context);
assertNotNull(vc);
vc.getScaledDoubleTapSlop();
@@ -83,6 +86,30 @@
vc.getScaledTouchSlop();
vc.getScaledWindowTouchSlop();
vc.hasPermanentMenuKey();
+
+ float pixelsToMmRatio = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 1,
+ context.getResources().getDisplayMetrics());
+
+ // Verify that the min scaling span size is reasonable.
+ float scaledMinScalingSpanMm = vc.getScaledMinScalingSpan() / pixelsToMmRatio;
+ assertTrue(scaledMinScalingSpanMm > 0);
+ assertTrue(scaledMinScalingSpanMm < 40.5); // 1.5 times the recommended size of 27mm
+ }
+
+ @Test
+ public void testExceptionsThrown() {
+ ViewConfiguration vc = new ViewConfiguration();
+ boolean correctExceptionThrown = false;
+ try {
+ vc.getScaledMinScalingSpan();
+ } catch (IllegalStateException e) {
+ if (e.getMessage().equals("Min scaling span cannot be determined when this "
+ + "method is called on a ViewConfiguration that was instantiated using a "
+ + "constructor with no Context parameter")) {
+ correctExceptionThrown = true;
+ }
+ }
+ assertTrue(correctExceptionThrown);
}
/**
diff --git a/tests/tests/webkit/AndroidTest.xml b/tests/tests/webkit/AndroidTest.xml
index 903aef7..a25f80b 100644
--- a/tests/tests/webkit/AndroidTest.xml
+++ b/tests/tests/webkit/AndroidTest.xml
@@ -16,6 +16,10 @@
<configuration description="Config for CTS Webkit test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="webview" />
+ <!-- Note: about half of webkit CTS tests are skipped in instant_app mode since it requires HTTPS -->
+ <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.LocationCheck" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/tests/webkit/src/android/webkit/cts/ChromeClient.java b/tests/tests/webkit/src/android/webkit/cts/ChromeClient.java
index 5435cf8..a78f219 100644
--- a/tests/tests/webkit/src/android/webkit/cts/ChromeClient.java
+++ b/tests/tests/webkit/src/android/webkit/cts/ChromeClient.java
@@ -18,33 +18,25 @@
import android.webkit.ConsoleMessage;
import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
+import com.google.common.util.concurrent.SettableFuture;
+
// A chrome client for listening webview chrome events.
class ChromeClient extends WaitForProgressClient {
-
- private boolean mIsMessageLevelAvailable;
- private ConsoleMessage.MessageLevel mMessageLevel;
+ private final SettableFuture<ConsoleMessage.MessageLevel> mMessageLevel =
+ SettableFuture.create();
public ChromeClient(WebViewOnUiThread onUiThread) {
super(onUiThread);
}
@Override
- public synchronized boolean onConsoleMessage(ConsoleMessage message) {
- mMessageLevel = message.messageLevel();
- mIsMessageLevelAvailable = true;
- notify();
+ public boolean onConsoleMessage(ConsoleMessage message) {
+ mMessageLevel.set(message.messageLevel());
// return false for default handling; i.e. printing the message.
return false;
}
- public synchronized ConsoleMessage.MessageLevel getMessageLevel(int timeout) {
- for(; timeout > 0; timeout -= 1000) {
- if( mIsMessageLevelAvailable ) break;
- try {
- wait(1000);
- } catch (InterruptedException e) {
- }
- }
- return mMessageLevel;
+ public ConsoleMessage.MessageLevel getMessageLevel() {
+ return WebkitUtils.waitForFuture(mMessageLevel);
}
}
diff --git a/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java b/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
index 843e81e..08bbc67 100644
--- a/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
@@ -16,6 +16,7 @@
package android.webkit.cts;
+import android.platform.test.annotations.AppModeFull;
import android.test.ActivityInstrumentationTestCase2;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
@@ -33,6 +34,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+@AppModeFull
public class CookieManagerTest extends
ActivityInstrumentationTestCase2<CookieSyncManagerCtsActivity> {
diff --git a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
index f4724cf..2b12f19 100644
--- a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
@@ -16,6 +16,7 @@
package android.webkit.cts;
+import android.platform.test.annotations.AppModeFull;
import android.test.ActivityInstrumentationTestCase2;
import android.webkit.HttpAuthHandler;
import android.webkit.WebView;
@@ -25,6 +26,7 @@
import org.apache.http.HttpStatus;
+@AppModeFull
public class HttpAuthHandlerTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
private static final long TIMEOUT = 10000;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
index c881de4..e59daf5 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
@@ -19,6 +19,7 @@
import android.graphics.Bitmap;
import android.os.Message;
import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
import android.test.ActivityInstrumentationTestCase2;
import android.view.MotionEvent;
import android.view.ViewGroup;
@@ -32,6 +33,7 @@
import com.android.compatibility.common.util.NullWebViewUtils;
import com.android.compatibility.common.util.PollingCheck;
+@AppModeFull
public class WebChromeClientTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
private static final long TEST_TIMEOUT = 5000L;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java b/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
index d2c54f0..cae5ff8 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
@@ -17,6 +17,7 @@
package android.webkit.cts;
import android.graphics.Bitmap;
+import android.platform.test.annotations.AppModeFull;
import android.test.ActivityInstrumentationTestCase2;
import android.webkit.WebBackForwardList;
import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
@@ -27,6 +28,7 @@
import com.android.compatibility.common.util.NullWebViewUtils;
import com.android.compatibility.common.util.PollingCheck;
+@AppModeFull
public class WebHistoryItemTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
private final static long TEST_TIMEOUT = 10000;
private CtsTestServer mWebServer;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 2d2d74f..b9b50d4 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -20,6 +20,7 @@
import android.net.http.SslError;
import android.os.Build;
import android.os.Message;
+import android.platform.test.annotations.AppModeFull;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Base64;
import android.util.Log;
@@ -55,6 +56,7 @@
/**
* Tests for {@link android.webkit.WebSettings}
*/
+@AppModeFull
public class WebSettingsTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
private static final int WEBVIEW_TIMEOUT = 5000;
@@ -973,7 +975,7 @@
mOnUiThread.loadUrlAndWaitForCompletion(url);
String iframeUrl = TestHtmlConstants.getFileUrl(TestHtmlConstants.HELLO_WORLD_URL);
assertFalse(iframeUrl.equals(mOnUiThread.getTitle()));
- assertEquals(ConsoleMessage.MessageLevel.ERROR, webChromeClient.getMessageLevel(10000));
+ assertEquals(ConsoleMessage.MessageLevel.ERROR, webChromeClient.getMessageLevel());
}
// Verify that enabling file access from file URLs enable XmlHttpRequest (XHR) across files
@@ -993,7 +995,7 @@
final ChromeClient webChromeClient = new ChromeClient(mOnUiThread);
mOnUiThread.setWebChromeClient(webChromeClient);
verifyFileXHR(false);
- assertEquals(ConsoleMessage.MessageLevel.ERROR, webChromeClient.getMessageLevel(10000));
+ assertEquals(ConsoleMessage.MessageLevel.ERROR, webChromeClient.getMessageLevel());
}
// verify XHR across files matches the allowFileAccessFromFileURLs setting
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
index 8f08dc7..a0b0ef5 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
@@ -20,6 +20,7 @@
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Message;
+import android.platform.test.annotations.AppModeFull;
import android.test.ActivityInstrumentationTestCase2;
import android.view.KeyEvent;
import android.view.ViewGroup;
@@ -48,6 +49,7 @@
import java.util.List;
import java.util.ArrayList;
+@AppModeFull
public class WebViewClientTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
private static final long TEST_TIMEOUT = 5000;
private static final String TEST_URL = "http://www.example.com/";
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewRendererClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewRendererClientTest.java
index dfdbcee..a372638 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewRendererClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewRendererClientTest.java
@@ -16,6 +16,7 @@
package android.webkit.cts;
+import android.platform.test.annotations.AppModeFull;
import android.test.ActivityInstrumentationTestCase2;
import android.view.KeyEvent;
import android.webkit.JavascriptInterface;
@@ -30,6 +31,7 @@
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
+@AppModeFull
public class WebViewRendererClientTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
private WebViewOnUiThread mOnUiThread;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewRendererTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewRendererTest.java
index e209d87..a99427b 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewRendererTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewRendererTest.java
@@ -18,6 +18,7 @@
import android.annotation.SuppressLint;
import android.os.Build;
+import android.platform.test.annotations.AppModeFull;
import android.test.ActivityInstrumentationTestCase2;
import android.webkit.RenderProcessGoneDetail;
import android.webkit.WebView;
@@ -28,6 +29,7 @@
import java.util.concurrent.Future;
+@AppModeFull
public class WebViewRendererTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
private WebViewOnUiThread mOnUiThread;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index cd0965d..6fbdb89 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -39,6 +39,7 @@
import android.os.StrictMode;
import android.os.StrictMode.ThreadPolicy;
import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.Presubmit;
import android.print.PageRange;
import android.print.PrintAttributes;
@@ -118,12 +119,17 @@
import org.apache.http.util.EncodingUtils;
import org.apache.http.util.EntityUtils;
+@AppModeFull
public class WebViewTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
public static final long TEST_TIMEOUT = 20000L;
private static final int INITIAL_PROGRESS = 100;
private static final String X_REQUESTED_WITH = "X-Requested-With";
private static final String PRINTER_TEST_FILE = "print.pdf";
private static final String PDF_PREAMBLE = "%PDF-1";
+ // Snippet of HTML that will prevent favicon requests to the test server.
+ private static final String HTML_HEADER =
+ "<html><head><link rel=\"shortcut icon\" href=\"%23\" /></head>";
+ private static final String SIMPLE_HTML = "<html><body>simple html</body></html>";
/**
* This is the minimum number of milliseconds to wait for scrolling to
@@ -147,11 +153,6 @@
*/
private static final long SCROLL_WAIT_INTERVAL_MS = 200;
- /**
- * Epsilon used in page scale value comparisons.
- */
- private static final float PAGE_SCALE_EPSILON = 0.0001f;
-
private WebView mWebView;
private CtsTestServer mWebServer;
private WebViewOnUiThread mOnUiThread;
@@ -296,122 +297,6 @@
assertNull(WebView.findAddress("This is not an address: no town, no state, no zip."));
}
- @SuppressWarnings("deprecation")
- @UiThreadTest
- public void testGetZoomControls() {
- if (!NullWebViewUtils.isWebViewAvailable()) {
- return;
- }
- WebSettings settings = mWebView.getSettings();
- assertTrue(settings.supportZoom());
- View zoomControls = mWebView.getZoomControls();
- assertNotNull(zoomControls);
-
- // disable zoom support
- settings.setSupportZoom(false);
- assertFalse(settings.supportZoom());
- assertNull(mWebView.getZoomControls());
- }
-
- @UiThreadTest
- public void testInvokeZoomPicker() throws Exception {
- if (!NullWebViewUtils.isWebViewAvailable()) {
- return;
- }
- WebSettings settings = mWebView.getSettings();
- assertTrue(settings.supportZoom());
- startWebServer(false);
- String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- mOnUiThread.loadUrlAndWaitForCompletion(url);
- mWebView.invokeZoomPicker();
- }
-
- public void testZoom() throws Throwable {
- if (!NullWebViewUtils.isWebViewAvailable()) {
- return;
- }
-
- // Pinch zoom is not supported in wrap_content layouts.
- mOnUiThread.setLayoutHeightToMatchParent();
-
- final ScaleChangedWebViewClient webViewClient = new ScaleChangedWebViewClient();
- mOnUiThread.setWebViewClient(webViewClient);
-
- mWebServer = new CtsTestServer(getActivity());
- mOnUiThread.loadUrlAndWaitForCompletion(
- mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
- pollingCheckForCanZoomIn();
-
- WebSettings settings = mOnUiThread.getSettings();
- settings.setSupportZoom(false);
- assertFalse(settings.supportZoom());
- float currScale = mOnUiThread.getScale();
- float previousScale = currScale;
-
- // can zoom in or out although zoom support is disabled in web settings
- assertTrue(mOnUiThread.zoomIn());
- currScale = webViewClient.expectZoomIn(currScale);
-
- assertTrue(mOnUiThread.zoomOut());
- currScale = webViewClient.expectZoomOut(currScale);
-
- mOnUiThread.zoomBy(1.25f); // zoom in
- currScale = webViewClient.expectZoomBy(currScale, 1.25f);
-
- mOnUiThread.zoomBy(0.8f); // zoom out
- currScale = webViewClient.expectZoomBy(currScale, 0.8f);
-
- // enable zoom support
- settings.setSupportZoom(true);
- assertTrue(settings.supportZoom());
-
- // Zoom in until maximum scale, in default increments.
- while (mOnUiThread.zoomIn()) {
- currScale = webViewClient.expectZoomIn(currScale);
- }
-
- assertFalse(mOnUiThread.zoomIn());
- assertNoScaleChange(webViewClient, currScale);
-
- // Zoom out until minimum scale, in default increments.
- while (mOnUiThread.zoomOut()) {
- currScale = webViewClient.expectZoomOut(currScale);
- }
-
- assertFalse(mOnUiThread.zoomOut());
- assertNoScaleChange(webViewClient, currScale);
-
- // Zoom in until maximum scale, in specified increments designed so that the last zoom will
- // be less than expected.
- while (mOnUiThread.canZoomIn()) {
- mOnUiThread.zoomBy(1.7f);
- currScale = webViewClient.expectZoomBy(currScale, 1.7f);
- }
-
- // At this point, zooming in should do nothing.
- mOnUiThread.zoomBy(1.7f);
- assertNoScaleChange(webViewClient, currScale);
-
- // Zoom out until minimum scale, in specified increments designed so that the last zoom will
- // be less than requested.
- while (mOnUiThread.canZoomOut()) {
- mOnUiThread.zoomBy(0.7f);
- currScale = webViewClient.expectZoomBy(currScale, 0.7f);
- }
-
- // At this point, zooming out should do nothing.
- mOnUiThread.zoomBy(0.7f);
- assertNoScaleChange(webViewClient, currScale);
- }
-
- private void assertNoScaleChange(ScaleChangedWebViewClient webViewClient, float currScale) throws InterruptedException {
- // We sleep to assert to the best of our ability
- // that a scale change does *not* happen.
- Thread.sleep(500);
- assertFalse(webViewClient.onScaleChangedCalled());
- assertEquals(currScale, mOnUiThread.getScale());
- }
-
@UiThreadTest
public void testScrollBarOverlay() throws Throwable {
if (!NullWebViewUtils.isWebViewAvailable()) {
@@ -1233,88 +1118,130 @@
startWebServer(false);
final ChromeClient webChromeClient = new ChromeClient(mOnUiThread);
final String crossOriginUrl = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- WebkitUtils.onMainThreadSync(() -> {
- mWebView.getSettings().setJavaScriptEnabled(true);
- mWebView.setWebChromeClient(webChromeClient);
- mOnUiThread.loadDataAndWaitForCompletion(
- "<html><head></head><body onload=\"" +
- "document.title = " +
- "document.getElementById('frame').contentWindow.location.href;" +
- "\"><iframe id=\"frame\" src=\"" + crossOriginUrl + "\"></body></html>",
- "text/html", null);
- });
- assertEquals(ConsoleMessage.MessageLevel.ERROR, webChromeClient.getMessageLevel(10000));
+ mOnUiThread.getSettings().setJavaScriptEnabled(true);
+ mOnUiThread.setWebChromeClient(webChromeClient);
+ mOnUiThread.loadDataAndWaitForCompletion(
+ "<html><head></head><body onload=\"" +
+ "document.title = " +
+ "document.getElementById('frame').contentWindow.location.href;" +
+ "\"><iframe id=\"frame\" src=\"" + crossOriginUrl + "\"></body></html>",
+ "text/html", null);
+ assertEquals(ConsoleMessage.MessageLevel.ERROR, webChromeClient.getMessageLevel());
}
- @UiThreadTest
- public void testLoadDataWithBaseUrl() throws Throwable {
+ public void testLoadDataWithBaseUrl_resolvesRelativeToBaseUrl() throws Throwable {
if (!NullWebViewUtils.isWebViewAvailable()) {
return;
}
- assertNull(mWebView.getUrl());
+ assertNull(mOnUiThread.getUrl());
String imgUrl = TestHtmlConstants.SMALL_IMG_URL; // relative
- // Snippet of HTML that will prevent favicon requests to the test server.
- final String HTML_HEADER = "<html><head><link rel=\"shortcut icon\" href=\"%23\" /></head>";
// Trying to resolve a relative URL against a data URL without a base URL
// will fail and we won't make a request to the test web server.
// By using the test web server as the base URL we expect to see a request
// for the relative URL in the test server.
startWebServer(false);
- String baseUrl = mWebServer.getAssetUrl("foo.html");
- String historyUrl = "http://www.example.com/";
+ final String baseUrl = mWebServer.getAssetUrl("foo.html");
mWebServer.resetRequestState();
mOnUiThread.loadDataWithBaseURLAndWaitForCompletion(baseUrl,
HTML_HEADER + "<body><img src=\"" + imgUrl + "\"/></body></html>",
- "text/html", "UTF-8", historyUrl);
+ "text/html", "UTF-8", null);
// Verify that the resource request makes it to the server.
assertTrue(mWebServer.wasResourceRequested(imgUrl));
- assertEquals(historyUrl, mWebView.getUrl());
+ }
+ public void testLoadDataWithBaseUrl_historyUrl() throws Throwable {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+ final String baseUrl = "http://www.baseurl.com/";
+ final String historyUrl = "http://www.example.com/";
+ mOnUiThread.loadDataWithBaseURLAndWaitForCompletion(baseUrl,
+ SIMPLE_HTML,
+ "text/html", "UTF-8", historyUrl);
+ assertEquals(historyUrl, mOnUiThread.getUrl());
+ }
+
+ public void testLoadDataWithBaseUrl_nullHistoryUrlShowsAsAboutBlank() throws Throwable {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
// Check that reported URL is "about:blank" when supplied history URL
// is null.
- imgUrl = TestHtmlConstants.LARGE_IMG_URL;
+ final String baseUrl = "http://www.baseurl.com/";
mOnUiThread.loadDataWithBaseURLAndWaitForCompletion(baseUrl,
- HTML_HEADER + "<body><img src=\"" + imgUrl + "\"/></body></html>",
+ SIMPLE_HTML,
"text/html", "UTF-8", null);
- assertTrue(mWebServer.wasResourceRequested(imgUrl));
- assertEquals("about:blank", mWebView.getUrl());
+ assertEquals("about:blank", mOnUiThread.getUrl());
+ }
+ public void testLoadDataWithBaseUrl_javascriptCanAccessOrigin() throws Throwable {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
// Test that JavaScript can access content from the same origin as the base URL.
- mWebView.getSettings().setJavaScriptEnabled(true);
+ mOnUiThread.getSettings().setJavaScriptEnabled(true);
+ startWebServer(false);
+ final String baseUrl = mWebServer.getAssetUrl("foo.html");
final String crossOriginUrl = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
mOnUiThread.loadDataWithBaseURLAndWaitForCompletion(baseUrl,
HTML_HEADER + "<body onload=\"" +
"document.title = document.getElementById('frame').contentWindow.location.href;" +
"\"><iframe id=\"frame\" src=\"" + crossOriginUrl + "\"></body></html>",
"text/html", "UTF-8", null);
- assertEquals(crossOriginUrl, mWebView.getTitle());
+ assertEquals(crossOriginUrl, mOnUiThread.getTitle());
+ }
+ public void testLoadDataWithBaseUrl_dataBaseUrlIgnoresHistoryUrl() throws Throwable {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
// Check that when the base URL uses the 'data' scheme, a 'data' scheme URL is used and the
// history URL is ignored.
- mOnUiThread.loadDataWithBaseURLAndWaitForCompletion("data:foo",
- HTML_HEADER + "<body>bar</body></html>", "text/html", "UTF-8",
- historyUrl);
- assertTrue("URL: " + mWebView.getUrl(), mWebView.getUrl().indexOf("data:text/html") == 0);
- assertTrue("URL: " + mWebView.getUrl(), mWebView.getUrl().indexOf("bar") > 0);
+ final String baseUrl = "data:foo";
+ final String historyUrl = "http://www.example.com/";
+ mOnUiThread.loadDataWithBaseURLAndWaitForCompletion(baseUrl,
+ SIMPLE_HTML,
+ "text/html", "UTF-8", historyUrl);
+ final String currentUrl = mOnUiThread.getUrl();
+ assertEquals("Current URL (" + currentUrl + ") should be a data URI", 0,
+ mOnUiThread.getUrl().indexOf("data:text/html"));
+ assertTrue("Current URL (" + currentUrl + ") should contain the simple HTML we loaded",
+ mOnUiThread.getUrl().indexOf("simple html") > 0);
+ }
+
+ public void testLoadDataWithBaseUrl_unencodedContentHttpBaseUrl() throws Throwable {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
// Check that when a non-data: base URL is used, we treat the String to load as
// a raw string and just dump it into the WebView, i.e. not decoding any URL entities.
mOnUiThread.loadDataWithBaseURLAndWaitForCompletion("http://www.foo.com",
HTML_HEADER + "<title>Hello World%21</title><body>bar</body></html>",
"text/html", "UTF-8", null);
- assertEquals("Hello World%21", mWebView.getTitle());
+ assertEquals("Hello World%21", mOnUiThread.getTitle());
+ }
+ public void testLoadDataWithBaseUrl_urlEncodedContentDataBaseUrl() throws Throwable {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
// Check that when a data: base URL is used, we treat the String to load as a data: URL
// and run load steps such as decoding URL entities (i.e., contrary to the test case
// above.)
mOnUiThread.loadDataWithBaseURLAndWaitForCompletion("data:foo",
HTML_HEADER + "<title>Hello World%21</title></html>", "text/html", "UTF-8", null);
- assertEquals("Hello World!", mWebView.getTitle());
+ assertEquals("Hello World!", mOnUiThread.getTitle());
+ }
- // Check the method is null input safe.
+ public void testLoadDataWithBaseUrl_nullSafe() throws Throwable {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+
mOnUiThread.loadDataWithBaseURLAndWaitForCompletion(null, null, null, null, null);
- assertEquals("about:blank", mWebView.getUrl());
+ assertEquals("about:blank", mOnUiThread.getUrl());
}
private void deleteIfExists(File file) throws IOException {
@@ -2119,47 +2046,6 @@
assertEquals(url3, copyListAfterRestore.getItemAtIndex(2).getUrl());
}
- public void testSetWebViewClient() throws Throwable {
- if (!NullWebViewUtils.isWebViewAvailable()) {
- return;
- }
- final ScaleChangedWebViewClient webViewClient = new ScaleChangedWebViewClient();
- mOnUiThread.setWebViewClient(webViewClient);
- startWebServer(false);
-
- assertFalse(webViewClient.onScaleChangedCalled());
- String url1 = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- mOnUiThread.loadUrlAndWaitForCompletion(url1);
- pollingCheckForCanZoomIn();
-
- assertTrue(mOnUiThread.zoomIn());
- webViewClient.waitForNextScaleChange();
- }
-
- public void testScaleChangeCallbackMatchesGetScale() throws Throwable {
- if (!NullWebViewUtils.isWebViewAvailable()) {
- return;
- }
- // wrap_parent layout causes extra onScaleChanged ecallbacks, so set to match_parent to
- // suppress them.
- mOnUiThread.setLayoutHeightToMatchParent();
- final ScaleChangedWebViewClient webViewClient = new ScaleChangedWebViewClient();
- mOnUiThread.setWebViewClient(webViewClient);
- startWebServer(false);
-
- assertFalse(webViewClient.onScaleChangedCalled());
- String url1 = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- mOnUiThread.loadUrlAndWaitForCompletion(url1);
- pollingCheckForCanZoomIn();
-
- assertFalse(webViewClient.onScaleChangedCalled());
- assertTrue(mOnUiThread.zoomIn());
- ScaleChangedState state = webViewClient.waitForNextScaleChange();
- assertEquals(
- "Expected onScaleChanged arg 2 (new scale) to equal view.getScale()",
- state.mNewScale, mOnUiThread.getScale());
- }
-
public void testRequestChildRectangleOnScreen() throws Throwable {
if (!NullWebViewUtils.isWebViewAvailable()) {
return;
@@ -2907,103 +2793,6 @@
}
}
- private void pollingCheckForCanZoomIn() {
- new PollingCheck(TEST_TIMEOUT) {
- @Override
- protected boolean check() {
- return mOnUiThread.canZoomIn();
- }
- }.run();
- }
-
- static class ScaleChangedState {
- public float mOldScale;
- public float mNewScale;
- public boolean mCanZoomIn;
- public boolean mCanZoomOut;
-
- ScaleChangedState(WebView view, float oldScale, float newScale) {
- mOldScale = oldScale;
- mNewScale = newScale;
- mCanZoomIn = view.canZoomIn();
- mCanZoomOut = view.canZoomOut();
- }
- }
-
- final class ScaleChangedWebViewClient extends WaitForLoadedClient {
- private BlockingQueue<ScaleChangedState> mCallQueue;
-
- public ScaleChangedWebViewClient() {
- super(mOnUiThread);
- mCallQueue = new LinkedBlockingQueue<>();
- }
-
- @Override
- public void onScaleChanged(WebView view, float oldScale, float newScale) {
- super.onScaleChanged(view, oldScale, newScale);
- mCallQueue.add(new ScaleChangedState(view, oldScale, newScale));
- }
-
- public float expectZoomBy(float currentScale, float scaleAmount) {
- assertTrue(scaleAmount != 1.0f);
-
- float nextScale = currentScale * scaleAmount;
- ScaleChangedState state = waitForNextScaleChange();
- assertEquals(currentScale, state.mOldScale);
-
- // Check that we zoomed in the expected direction wrt. the current scale.
- if (scaleAmount > 1.0f) {
- assertTrue(
- "Expected new scale > current scale when zooming in",
- state.mNewScale > currentScale);
- } else {
- assertTrue(
- "Expected new scale < current scale when zooming out",
- state.mNewScale < currentScale);
- }
-
- // If we hit the zoom limit, then the new scale should be between the old scale
- // and the expected new scale. Otherwise it should equal the expected new scale.
- if (Math.abs(nextScale - state.mNewScale) > PAGE_SCALE_EPSILON) {
- if (scaleAmount > 1.0f) {
- assertFalse(state.mCanZoomIn);
- assertTrue(
- "Expected new scale <= requested scale when zooming in past limit",
- state.mNewScale <= nextScale);
- } else {
- assertFalse(state.mCanZoomOut);
- assertTrue(
- "Expected new scale >= requested scale when zooming out past limit",
- state.mNewScale >= nextScale);
- }
- }
-
- return state.mNewScale;
- }
-
- public float expectZoomOut(float currentScale) {
- ScaleChangedState state = waitForNextScaleChange();
- assertEquals(currentScale, state.mOldScale);
- assertTrue(state.mNewScale < currentScale);
- return state.mNewScale;
- }
-
- public float expectZoomIn(float currentScale) {
- ScaleChangedState state = waitForNextScaleChange();
- assertEquals(currentScale, state.mOldScale);
- assertTrue(state.mNewScale > currentScale);
- return state.mNewScale;
- }
-
- public ScaleChangedState waitForNextScaleChange() {
- return WebkitUtils.waitForNextQueueElement(mCallQueue);
- }
-
- public boolean onScaleChangedCalled() {
- return mCallQueue.size() > 0;
- }
- }
-
/**
* This should remain functionally equivalent to
* androidx.webkit.WebViewCompatTest#testGetSafeBrowsingPrivacyPolicyUrl. Modifications to this
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java
new file mode 100644
index 0000000..93e2cd5
--- /dev/null
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewZoomTest.java
@@ -0,0 +1,372 @@
+/*
+ * Copyright 2019 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.webkit.cts;
+
+import android.os.StrictMode;
+import android.os.StrictMode.ThreadPolicy;
+import android.test.ActivityInstrumentationTestCase2;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
+
+import com.android.compatibility.common.util.NullWebViewUtils;
+import com.android.compatibility.common.util.PollingCheck;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Test WebView zooming behaviour
+ */
+public class WebViewZoomTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
+ private WebView mWebView;
+ private WebViewOnUiThread mOnUiThread;
+ private ScaleChangedWebViewClient mWebViewClient;
+ private CtsTestServer mWebServer;
+
+ /**
+ * Epsilon used in page scale value comparisons.
+ */
+ private static final float PAGE_SCALE_EPSILON = 0.0001f;
+
+ public WebViewZoomTest() {
+ super("com.android.cts.webkit", WebViewCtsActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ final WebViewCtsActivity activity = getActivity();
+ mWebView = activity.getWebView();
+ if (mWebView == null)
+ return;
+
+ new PollingCheck() {
+ @Override
+ protected boolean check() {
+ return activity.hasWindowFocus();
+ }
+ }.run();
+ mOnUiThread = new WebViewOnUiThread(mWebView);
+ mWebViewClient = new ScaleChangedWebViewClient();
+ mOnUiThread.setWebViewClient(mWebViewClient);
+
+ // Pinch zoom is not supported in wrap_content layouts.
+ mOnUiThread.setLayoutHeightToMatchParent();
+
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mOnUiThread != null) {
+ mOnUiThread.cleanUp();
+ }
+ if (mWebServer != null) {
+ stopWebServer();
+ }
+ super.tearDown();
+ }
+
+ private void startWebServer(boolean secure) throws Exception {
+ assertNull(mWebServer);
+ mWebServer = new CtsTestServer(getActivity(), secure);
+ }
+
+ private void stopWebServer() throws Exception {
+ assertNotNull(mWebServer);
+ ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
+ ThreadPolicy tmpPolicy = new ThreadPolicy.Builder(oldPolicy)
+ .permitNetwork()
+ .build();
+ StrictMode.setThreadPolicy(tmpPolicy);
+ mWebServer.shutdown();
+ mWebServer = null;
+ StrictMode.setThreadPolicy(oldPolicy);
+ }
+
+ private void setUpPage() throws Exception {
+ assertFalse(mWebViewClient.onScaleChangedCalled());
+ startWebServer(false);
+ mOnUiThread.loadUrlAndWaitForCompletion(
+ mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
+ pollingCheckForCanZoomIn();
+ }
+
+ public void testZoomIn() throws Throwable {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+
+ setUpPage();
+
+ assertTrue(mOnUiThread.zoomIn());
+ mWebViewClient.waitForNextScaleChange();
+ }
+
+ @SuppressWarnings("deprecation")
+ public void testGetZoomControls() {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+ WebSettings settings = mOnUiThread.getSettings();
+ assertTrue(settings.supportZoom());
+ assertNotNull(
+ "Should be able to get zoom controls when zoom is enabled",
+ WebkitUtils.onMainThreadSync(() -> { return mWebView.getZoomControls(); }));
+
+ // disable zoom support
+ settings.setSupportZoom(false);
+ assertFalse(settings.supportZoom());
+ assertNull(
+ "Should not be able to get zoom controls when zoom is disabled",
+ WebkitUtils.onMainThreadSync(() -> { return mWebView.getZoomControls(); }));
+ }
+
+ public void testInvokeZoomPicker() throws Exception {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+ WebSettings settings = mOnUiThread.getSettings();
+ assertTrue(settings.supportZoom());
+ setUpPage();
+ WebkitUtils.onMainThreadSync(() -> mWebView.invokeZoomPicker());
+ }
+
+ public void testZoom_canNotZoomInPastMaximum() {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+ float currScale = mOnUiThread.getScale();
+ // Zoom in until maximum scale, in default increments.
+ while (mOnUiThread.zoomIn()) {
+ currScale = mWebViewClient.expectZoomIn(currScale);
+ }
+
+ assertFalse(mOnUiThread.zoomIn());
+ assertNoScaleChange(currScale);
+ }
+
+ public void testZoom_canNotZoomOutPastMinimum() {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+ float currScale = mOnUiThread.getScale();
+ // Zoom in until maximum scale, in default increments.
+ while (mOnUiThread.zoomOut()) {
+ currScale = mWebViewClient.expectZoomOut(currScale);
+ }
+
+ assertFalse(mOnUiThread.zoomOut());
+ assertNoScaleChange(currScale);
+ }
+
+ public void testCanZoomWhileZoomSupportedFalse() throws Throwable {
+ // setZoomSupported disables user controls, but not zooming via API
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+
+ setUpPage();
+
+ WebSettings settings = mOnUiThread.getSettings();
+ settings.setSupportZoom(false);
+ assertFalse(settings.supportZoom());
+
+ float currScale = mOnUiThread.getScale();
+
+ // can zoom in or out although zoom support is disabled in web settings
+ assertTrue(mOnUiThread.zoomIn());
+ currScale = mWebViewClient.expectZoomIn(currScale);
+
+ assertTrue(mOnUiThread.zoomOut());
+ currScale = mWebViewClient.expectZoomOut(currScale);
+ }
+
+ public void testZoomByPowerOfTwoIncrements() throws Throwable {
+ // setZoomSupported disables user controls, but not zooming via API
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+
+ setUpPage();
+ float currScale = mOnUiThread.getScale();
+
+ mOnUiThread.zoomBy(1.25f); // zoom in
+ currScale = mWebViewClient.expectZoomBy(currScale, 1.25f);
+
+ mOnUiThread.zoomBy(0.75f); // zoom out
+ currScale = mWebViewClient.expectZoomBy(currScale, 0.75f);
+ }
+
+ public void testZoomByNonPowerOfTwoIncrements() throws Throwable {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+
+ setUpPage();
+
+ float currScale = mOnUiThread.getScale();
+
+ // Zoom in until maximum scale, in specified increments designed so that the last zoom will
+ // be less than expected.
+ while (mOnUiThread.canZoomIn()) {
+ mOnUiThread.zoomBy(1.7f);
+ currScale = mWebViewClient.expectZoomBy(currScale, 1.7f);
+ }
+
+ // At this point, zooming in should do nothing.
+ mOnUiThread.zoomBy(1.7f);
+ assertNoScaleChange(currScale);
+
+ // Zoom out until minimum scale, in specified increments designed so that the last zoom will
+ // be less than requested.
+ while (mOnUiThread.canZoomOut()) {
+ mOnUiThread.zoomBy(0.7f);
+ currScale = mWebViewClient.expectZoomBy(currScale, 0.7f);
+ }
+
+ // At this point, zooming out should do nothing.
+ mOnUiThread.zoomBy(0.7f);
+ assertNoScaleChange(currScale);
+ }
+
+ public void testScaleChangeCallbackMatchesGetScale() throws Throwable {
+ if (!NullWebViewUtils.isWebViewAvailable()) {
+ return;
+ }
+ assertFalse(mWebViewClient.onScaleChangedCalled());
+
+ setUpPage();
+
+ assertFalse(mWebViewClient.onScaleChangedCalled());
+ assertTrue(mOnUiThread.zoomIn());
+ ScaleChangedState state = mWebViewClient.waitForNextScaleChange();
+ assertEquals(
+ "Expected onScaleChanged arg 2 (new scale) to equal view.getScale()",
+ state.mNewScale, mOnUiThread.getScale());
+ }
+
+ private void assertNoScaleChange(float currScale) {
+ // We sleep to assert to the best of our ability
+ // that a scale change does *not* happen.
+ try {
+ Thread.sleep(500);
+ assertFalse(mWebViewClient.onScaleChangedCalled());
+ assertEquals(currScale, mOnUiThread.getScale());
+ } catch (InterruptedException e) {
+ fail("Interrupted");
+ }
+ }
+
+ private static final class ScaleChangedState {
+ public float mOldScale;
+ public float mNewScale;
+ public boolean mCanZoomIn;
+ public boolean mCanZoomOut;
+
+ ScaleChangedState(WebView view, float oldScale, float newScale) {
+ mOldScale = oldScale;
+ mNewScale = newScale;
+ mCanZoomIn = view.canZoomIn();
+ mCanZoomOut = view.canZoomOut();
+ }
+ }
+
+ private void pollingCheckForCanZoomIn() {
+ new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
+ @Override
+ protected boolean check() {
+ return mOnUiThread.canZoomIn();
+ }
+ }.run();
+ }
+
+ private final class ScaleChangedWebViewClient extends WaitForLoadedClient {
+ private BlockingQueue<ScaleChangedState> mCallQueue;
+
+ public ScaleChangedWebViewClient() {
+ super(mOnUiThread);
+ mCallQueue = new LinkedBlockingQueue<>();
+ }
+
+ @Override
+ public void onScaleChanged(WebView view, float oldScale, float newScale) {
+ super.onScaleChanged(view, oldScale, newScale);
+ mCallQueue.add(new ScaleChangedState(view, oldScale, newScale));
+ }
+
+ public float expectZoomBy(float currentScale, float scaleAmount) {
+ assertTrue(scaleAmount != 1.0f);
+
+ float nextScale = currentScale * scaleAmount;
+ ScaleChangedState state = waitForNextScaleChange();
+ assertEquals(currentScale, state.mOldScale);
+
+ // Check that we zoomed in the expected direction wrt. the current scale.
+ if (scaleAmount > 1.0f) {
+ assertTrue(
+ "Expected new scale > current scale when zooming in",
+ state.mNewScale > currentScale);
+ } else {
+ assertTrue(
+ "Expected new scale < current scale when zooming out",
+ state.mNewScale < currentScale);
+ }
+
+ // If we hit the zoom limit, then the new scale should be between the old scale
+ // and the expected new scale. Otherwise it should equal the expected new scale.
+ if (Math.abs(nextScale - state.mNewScale) > PAGE_SCALE_EPSILON) {
+ if (scaleAmount > 1.0f) {
+ assertFalse(state.mCanZoomIn);
+ assertTrue(
+ "Expected new scale <= requested scale when zooming in past limit",
+ state.mNewScale <= nextScale);
+ } else {
+ assertFalse(state.mCanZoomOut);
+ assertTrue(
+ "Expected new scale >= requested scale when zooming out past limit",
+ state.mNewScale >= nextScale);
+ }
+ }
+
+ return state.mNewScale;
+ }
+
+ public float expectZoomOut(float currentScale) {
+ ScaleChangedState state = waitForNextScaleChange();
+ assertEquals(currentScale, state.mOldScale);
+ assertTrue(state.mNewScale < currentScale);
+ return state.mNewScale;
+ }
+
+ public float expectZoomIn(float currentScale) {
+ ScaleChangedState state = waitForNextScaleChange();
+ assertEquals(currentScale, state.mOldScale);
+ assertTrue(state.mNewScale > currentScale);
+ return state.mNewScale;
+ }
+
+ public ScaleChangedState waitForNextScaleChange() {
+ return WebkitUtils.waitForNextQueueElement(mCallQueue);
+ }
+
+ public boolean onScaleChangedCalled() {
+ return mCallQueue.size() > 0;
+ }
+ }
+}
diff --git a/tests/tests/widget/Android.bp b/tests/tests/widget/Android.bp
index 5887cb8..6703c55 100644
--- a/tests/tests/widget/Android.bp
+++ b/tests/tests/widget/Android.bp
@@ -24,6 +24,7 @@
"compatibility-device-util",
"ctstestrunner",
"platform-test-annotations",
+ "truth-prebuilt",
],
libs: ["android.test.runner.stubs"],
diff --git a/tests/tests/widget/AndroidManifest.xml b/tests/tests/widget/AndroidManifest.xml
index e7929e0..df712eb 100644
--- a/tests/tests/widget/AndroidManifest.xml
+++ b/tests/tests/widget/AndroidManifest.xml
@@ -558,6 +558,15 @@
</intent-filter>
</activity>
+ <activity android:name="android.app.Activity"
+ android:label="Activity"
+ android:theme="@style/WidgetAttributeTestTheme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
<activity android:name="android.app.ActivityGroup"
android:label="ActivityGroup" />
diff --git a/tests/tests/widget/res/layout/widget_attribute_layout.xml b/tests/tests/widget/res/layout/widget_attribute_layout.xml
new file mode 100644
index 0000000..f858548
--- /dev/null
+++ b/tests/tests/widget/res/layout/widget_attribute_layout.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <ProgressBar
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/progress_bar"
+ android:minWidth="7dp"
+ android:maxWidth="10dp"
+ android:progressTint="#ff00ff"
+ style="@style/ExplicitStyle1" />
+
+ <Switch android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/switch_view"
+ android:switchPadding="5dp"
+ style="@style/ExplicitStyle2" />
+
+ <Toolbar android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/toolbar_view" />
+
+ <View android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/view4"
+ style="?android:attr/textAppearanceLarge"/>
+
+ <Button android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/button1" />
+
+ <Button android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/button2"
+ style="@style/ExplicitStyle1" />
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/widget/res/values/styles.xml b/tests/tests/widget/res/values/styles.xml
index b35ba64..3966207 100644
--- a/tests/tests/widget/res/values/styles.xml
+++ b/tests/tests/widget/res/values/styles.xml
@@ -416,4 +416,29 @@
<style name="TextView_FontXmlResource">
<item name="android:fontFamily">@font/samplexmlfont</item>
</style>
+
+ <style name="WidgetAttributeTestTheme" parent="@android:Theme.Material">
+ <item name="android:toolbarStyle">@style/MyToolbarStyle</item>
+ </style>
+
+ <style name="MyToolbarStyle" parent="@style/MyToolbarStyleParent">
+ <item name="android:titleMarginEnd">3dp</item>
+ </style>
+
+ <style name="MyToolbarStyleParent">
+ <item name="android:titleMarginStart">6dp</item>
+ </style>
+
+ <style name="ExplicitStyle1" parent="@style/ParentOfExplicitStyle1">
+ <item name="android:padding">1dp</item>
+ <item name="android:progress">5</item>
+ <item name="android:max">50</item>
+ </style>
+
+ <style name="ParentOfExplicitStyle1">
+ <item name="android:paddingLeft">2dp</item>
+ <item name="android:mirrorForRtl">true</item>
+ </style>
+
+ <style name="ExplicitStyle2" />
</resources>
diff --git a/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java b/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
index 5b969d3..fa105c2 100644
--- a/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
@@ -18,6 +18,8 @@
import static com.android.compatibility.common.util.WidgetTestUtils.sameCharSequence;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -70,12 +72,17 @@
import com.android.compatibility.common.util.PollingCheck;
+import com.google.common.collect.ImmutableList;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xmlpull.v1.XmlPullParser;
+import java.util.ArrayList;
+import java.util.List;
+
@MediumTest
@RunWith(AndroidJUnit4.class)
public class AutoCompleteTextViewTest {
@@ -420,6 +427,232 @@
false, Color.YELLOW, 1, true);
}
+ @Test
+ public void refreshAutoCompleteResults_addItem() throws Throwable {
+ List<String> suggestions = new ArrayList<>(ImmutableList.of("testOne", "testTwo"));
+ mAdapter = new ArrayAdapter<String>(
+ mActivity, android.R.layout.simple_dropdown_item_1line, suggestions);
+
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setAdapter(mAdapter);
+ mAutoCompleteTextView.setText("testT");
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+ mInstrumentation.waitForIdleSync();
+
+ assertThat(getAutoCompleteSuggestions()).containsExactly("testTwo");
+
+ mActivityRule.runOnUiThread(() -> {
+ mAdapter.add("testThree");
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+
+ mInstrumentation.waitForIdleSync();
+
+ assertThat(getAutoCompleteSuggestions()).containsExactly("testTwo", "testThree");
+ }
+
+ @Test
+ public void refreshAutoCompleteResults_removeItem() throws Throwable {
+ List<String> suggestions = new ArrayList<>(
+ ImmutableList.of("testOne", "testTwo", "testThree"));
+ mAdapter = new ArrayAdapter<String>(
+ mActivity, android.R.layout.simple_dropdown_item_1line, suggestions);
+
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setAdapter(mAdapter);
+ mAutoCompleteTextView.setText("testT");
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+ mInstrumentation.waitForIdleSync();
+
+ assertThat(getAutoCompleteSuggestions()).containsExactly("testTwo", "testThree");
+
+ mActivityRule.runOnUiThread(() -> {
+ mAdapter.remove("testThree");
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+
+ mInstrumentation.waitForIdleSync();
+
+ assertThat(getAutoCompleteSuggestions()).containsExactly("testTwo");
+ }
+
+ @Test
+ public void refreshAutoCompleteResults_threshold_changeText() throws Throwable {
+ List<String> suggestions = new ArrayList<>(
+ ImmutableList.of("testOne", "testTwo", "testThree"));
+ mAdapter = new ArrayAdapter<String>(
+ mActivity, android.R.layout.simple_dropdown_item_1line, suggestions);
+
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setThreshold(3);
+ mAutoCompleteTextView.setAdapter(mAdapter);
+ mAutoCompleteTextView.setText("tes");
+ });
+ mInstrumentation.waitForIdleSync();
+
+ // Above Threshold.
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setText("test");
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+ mInstrumentation.waitForIdleSync();
+ assertThat(mAutoCompleteTextView.isPopupShowing()).isTrue();
+ assertThat(getAutoCompleteSuggestions()).containsExactly("testOne", "testTwo", "testThree");
+
+ // At Threshold.
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setText("tes");
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+ mInstrumentation.waitForIdleSync();
+ assertThat(mAutoCompleteTextView.isPopupShowing()).isTrue();
+ assertThat(getAutoCompleteSuggestions()).containsExactly("testOne", "testTwo", "testThree");
+
+ // Below Threshold.
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setText("te");
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+ mInstrumentation.waitForIdleSync();
+ assertThat(mAutoCompleteTextView.isPopupShowing()).isFalse();
+ }
+
+ @Test
+ public void refreshAutoCompleteResults_changeThreshold() throws Throwable {
+ List<String> suggestions = new ArrayList<>(
+ ImmutableList.of("testOne", "testTwo", "testThree"));
+ mAdapter = new ArrayAdapter<String>(mActivity, android.R.layout.simple_dropdown_item_1line,
+ suggestions);
+
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setAdapter(mAdapter);
+ mAutoCompleteTextView.setText("test");
+ });
+ mInstrumentation.waitForIdleSync();
+
+ // Above Threshold.
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setThreshold(3);
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+ mInstrumentation.waitForIdleSync();
+ assertThat(mAutoCompleteTextView.isPopupShowing()).isTrue();
+ assertThat(getAutoCompleteSuggestions()).containsExactly("testOne", "testTwo", "testThree");
+
+ // At Threshold.
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setThreshold(4);
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+ mInstrumentation.waitForIdleSync();
+ assertThat(mAutoCompleteTextView.isPopupShowing()).isTrue();
+ assertThat(getAutoCompleteSuggestions()).containsExactly("testOne", "testTwo", "testThree");
+
+ // Below Threshold.
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setThreshold(5);
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+ mInstrumentation.waitForIdleSync();
+ assertThat(mAutoCompleteTextView.isPopupShowing()).isFalse();
+ }
+
+ @Test
+ public void refreshAutoCompleteResults_dropDownAlwaysVisible() throws Throwable {
+ List<String> suggestions = new ArrayList<>(
+ ImmutableList.of("testOne", "testTwo", "testThree"));
+ mAdapter = new ArrayAdapter<String>(mActivity, android.R.layout.simple_dropdown_item_1line,
+ suggestions);
+
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setAdapter(mAdapter);
+ mAutoCompleteTextView.setDropDownAlwaysVisible(true);
+ mAutoCompleteTextView.setText("test");
+ });
+ mInstrumentation.waitForIdleSync();
+
+ // Below Threshold.
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setThreshold(5);
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+ mInstrumentation.waitForIdleSync();
+ assertThat(mAutoCompleteTextView.isPopupShowing()).isTrue();
+ }
+
+ @Test
+ public void refreshAutoCompleteResults_dropDownNotAlwaysVisible() throws Throwable {
+ List<String> suggestions = new ArrayList<>(
+ ImmutableList.of("testOne", "testTwo", "testThree"));
+ mAdapter = new ArrayAdapter<String>(mActivity, android.R.layout.simple_dropdown_item_1line,
+ suggestions);
+
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setAdapter(mAdapter);
+ mAutoCompleteTextView.setDropDownAlwaysVisible(false);
+ mAutoCompleteTextView.setText("test");
+ });
+ mInstrumentation.waitForIdleSync();
+
+ // Below Threshold.
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setThreshold(5);
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+ mInstrumentation.waitForIdleSync();
+ assertThat(mAutoCompleteTextView.isPopupShowing()).isFalse();
+ }
+
+ @Test
+ public void refreshAutoCompleteResults_popupCanBeUpdated() throws Throwable {
+ List<String> suggestions = new ArrayList<>(
+ ImmutableList.of("testOne", "testTwo", "testThree"));
+ mAdapter = new ArrayAdapter<String>(mActivity, android.R.layout.simple_dropdown_item_1line,
+ suggestions);
+
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setAdapter(mAdapter);
+ mAutoCompleteTextView.setDropDownAlwaysVisible(false);
+ mAutoCompleteTextView.setText("test");
+ });
+ mInstrumentation.waitForIdleSync();
+
+ // Below Threshold.
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setThreshold(5);
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+ mInstrumentation.waitForIdleSync();
+ assertThat(mAutoCompleteTextView.isPopupShowing()).isFalse();
+ }
+
+ @Test
+ public void refreshAutoCompleteResults() throws Throwable {
+ List<String> suggestions = new ArrayList<>(ImmutableList.of("testOne", "testTwo"));
+ mAdapter = new ArrayAdapter<String>(mActivity, android.R.layout.simple_dropdown_item_1line,
+ suggestions);
+
+ mActivityRule.runOnUiThread(() -> {
+ mAutoCompleteTextView.setAdapter(mAdapter);
+ mAutoCompleteTextView.setText("testT");
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+ mInstrumentation.waitForIdleSync();
+
+ assertThat(getAutoCompleteSuggestions()).containsExactly("testTwo");
+
+ mActivityRule.runOnUiThread(() -> {
+ mAdapter.add("testThree");
+ mAutoCompleteTextView.refreshAutoCompleteResults();
+ });
+
+ mInstrumentation.waitForIdleSync();
+
+ assertThat(getAutoCompleteSuggestions()).containsExactly("testTwo", "testThree");
+ }
+
@UiThreadTest
@Test
public void testReplaceText() {
@@ -803,6 +1036,15 @@
assertEquals(ViewGroup.LayoutParams.MATCH_PARENT, mAutoCompleteTextView.getDropDownWidth());
}
+ private List<Object> getAutoCompleteSuggestions() {
+ int count = mAutoCompleteTextView.getAdapter().getCount();
+ List<Object> autoCompleteSuggestions = new ArrayList<>(count);
+ for (int index = 0; index < count; index++) {
+ autoCompleteSuggestions.add(mAutoCompleteTextView.getAdapter().getItem(index));
+ }
+ return autoCompleteSuggestions;
+ }
+
private class MockValidator implements AutoCompleteTextView.Validator {
public CharSequence fixText(CharSequence invalidText) {
return STRING_VALIDATED;
diff --git a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
index 88aa357..3ad7ad0 100644
--- a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
@@ -28,6 +28,7 @@
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
+import android.graphics.Color;
import android.graphics.Rect;
import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
@@ -39,6 +40,7 @@
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
+import android.widget.EdgeEffect;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.TextView;
@@ -769,6 +771,26 @@
assertTrue(myScrollViewCustom.getRightFadingEdgeStrength() >= 0.0f);
}
+ @UiThreadTest
+ @Test
+ public void testEdgeEffectColors() {
+ int defaultColor = new EdgeEffect(mScrollViewRegular.getContext()).getColor();
+ assertEquals(mScrollViewRegular.getLeftEdgeEffectColor(), defaultColor);
+ assertEquals(mScrollViewRegular.getRightEdgeEffectColor(), defaultColor);
+
+ mScrollViewRegular.setEdgeEffectColor(Color.BLUE);
+ assertEquals(mScrollViewRegular.getLeftEdgeEffectColor(), Color.BLUE);
+ assertEquals(mScrollViewRegular.getRightEdgeEffectColor(), Color.BLUE);
+
+ mScrollViewRegular.setLeftEdgeEffectColor(Color.RED);
+ assertEquals(mScrollViewRegular.getLeftEdgeEffectColor(), Color.RED);
+ assertEquals(mScrollViewRegular.getRightEdgeEffectColor(), Color.BLUE);
+
+ mScrollViewRegular.setRightEdgeEffectColor(Color.GREEN);
+ assertEquals(mScrollViewRegular.getLeftEdgeEffectColor(), Color.RED);
+ assertEquals(mScrollViewRegular.getRightEdgeEffectColor(), Color.GREEN);
+ }
+
private boolean isInRange(int current, int from, int to) {
if (from < to) {
return current >= from && current <= to;
diff --git a/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
index 88f3450..b53bf4f 100644
--- a/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
@@ -388,6 +388,20 @@
}
@Test
+ public void testAccessEpicenterBounds() {
+ mPopupWindow = new ListPopupWindow(mActivity);
+ assertNull(mPopupWindow.getEpicenterBounds());
+
+ final Rect epicenter = new Rect(5, 10, 15, 20);
+
+ mPopupWindow.setEpicenterBounds(epicenter);
+ assertEquals(mPopupWindow.getEpicenterBounds(), epicenter);
+
+ mPopupWindow.setEpicenterBounds(null);
+ assertNull(mPopupWindow.getEpicenterBounds());
+ }
+
+ @Test
public void testAccessInputMethodMode() throws Throwable {
mPopupWindowBuilder = new Builder().withDismissListener();
mActivityRule.runOnUiThread(mPopupWindowBuilder::show);
diff --git a/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java b/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
index 1904710..d84a229 100644
--- a/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ProgressBarTest.java
@@ -220,6 +220,20 @@
@UiThreadTest
@Test
+ public void testAccessCurrentDrawable() {
+ final Drawable progressDrawable = new ColorDrawable(Color.BLUE);
+ final Drawable indeterminateDrawable = new ColorDrawable(Color.RED);
+ mProgressBarHorizontal.setProgressDrawable(progressDrawable);
+ mProgressBarHorizontal.setIndeterminateDrawable(indeterminateDrawable);
+
+ mProgressBarHorizontal.setIndeterminate(false);
+ assertSame(progressDrawable, mProgressBarHorizontal.getCurrentDrawable());
+ mProgressBarHorizontal.setIndeterminate(true);
+ assertSame(indeterminateDrawable, mProgressBarHorizontal.getCurrentDrawable());
+ }
+
+ @UiThreadTest
+ @Test
public void testAccessProgress() {
assertEquals(0, mProgressBarHorizontal.getProgress());
diff --git a/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java b/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
index bae62ed..05944c4 100644
--- a/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
@@ -28,6 +28,7 @@
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
+import android.graphics.Color;
import android.graphics.Rect;
import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
@@ -39,6 +40,7 @@
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
+import android.widget.EdgeEffect;
import android.widget.FrameLayout;
import android.widget.ScrollView;
import android.widget.TextView;
@@ -816,6 +818,26 @@
assertEquals(lastChildTop, mScrollViewCustom.getScrollY());
}
+ @UiThreadTest
+ @Test
+ public void testEdgeEffectColors() {
+ int defaultColor = new EdgeEffect(mScrollViewRegular.getContext()).getColor();
+ assertEquals(mScrollViewRegular.getTopEdgeEffectColor(), defaultColor);
+ assertEquals(mScrollViewRegular.getBottomEdgeEffectColor(), defaultColor);
+
+ mScrollViewRegular.setEdgeEffectColor(Color.BLUE);
+ assertEquals(mScrollViewRegular.getTopEdgeEffectColor(), Color.BLUE);
+ assertEquals(mScrollViewRegular.getBottomEdgeEffectColor(), Color.BLUE);
+
+ mScrollViewRegular.setTopEdgeEffectColor(Color.RED);
+ assertEquals(mScrollViewRegular.getTopEdgeEffectColor(), Color.RED);
+ assertEquals(mScrollViewRegular.getBottomEdgeEffectColor(), Color.BLUE);
+
+ mScrollViewRegular.setBottomEdgeEffectColor(Color.GREEN);
+ assertEquals(mScrollViewRegular.getTopEdgeEffectColor(), Color.RED);
+ assertEquals(mScrollViewRegular.getBottomEdgeEffectColor(), Color.GREEN);
+ }
+
private boolean isInRange(int current, int from, int to) {
if (from < to) {
return current >= from && current <= to;
diff --git a/tests/tests/widget/src/android/widget/cts/WidgetAttributeTest.kt b/tests/tests/widget/src/android/widget/cts/WidgetAttributeTest.kt
new file mode 100644
index 0000000..071a0ae
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/WidgetAttributeTest.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2019 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.widget.cts
+
+import android.app.Activity
+import android.support.test.InstrumentationRegistry
+import android.support.test.filters.MediumTest
+import android.support.test.rule.ActivityTestRule
+import android.support.test.runner.AndroidJUnit4
+import android.support.test.uiautomator.UiDevice
+import android.view.LayoutInflater
+import android.widget.LinearLayout
+import android.widget.ProgressBar
+import android.widget.Switch
+import android.widget.Toolbar
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class WidgetAttributeTest {
+ companion object {
+ const val DISABLE_SHELL_COMMAND =
+ "settings delete global debug_view_attributes_application_package"
+ const val ENABLE_SHELL_COMMAND =
+ "settings put global debug_view_attributes_application_package android.widget.cts"
+ }
+
+ @get:Rule
+ val activityRule = ActivityTestRule<Activity>(Activity::class.java, true, false)
+ private lateinit var uiDevice: UiDevice
+
+ @Before
+ fun setUp() {
+ uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ uiDevice.executeShellCommand(ENABLE_SHELL_COMMAND)
+ activityRule.launchActivity(null)
+ }
+
+ @After
+ fun tearDown() {
+ uiDevice.executeShellCommand(DISABLE_SHELL_COMMAND)
+ }
+
+ @Test
+ fun testGetAttributeSourceResourceMap() {
+ val inflater = LayoutInflater.from(activityRule.getActivity())
+ val rootView = inflater.inflate(R.layout.widget_attribute_layout, null) as LinearLayout
+
+ // ProgressBar that has an explicit style ExplicitStyle1 set via style = ...
+ val progressBar = rootView.findViewById<ProgressBar>(R.id.progress_bar)
+ val attributeMapProgressBar = progressBar!!.attributeSourceResourceMap
+ assertEquals(R.layout.widget_attribute_layout,
+ attributeMapProgressBar[android.R.attr.minWidth]!!.toInt())
+ assertEquals(R.layout.widget_attribute_layout,
+ attributeMapProgressBar[android.R.attr.maxWidth]!!.toInt())
+ assertEquals(R.layout.widget_attribute_layout,
+ attributeMapProgressBar[android.R.attr.progressTint]!!.toInt())
+ assertEquals(R.style.ExplicitStyle1,
+ attributeMapProgressBar[android.R.attr.progress]!!.toInt())
+ assertEquals(R.style.ExplicitStyle1,
+ attributeMapProgressBar[android.R.attr.padding]!!.toInt())
+ assertEquals(R.style.ExplicitStyle1,
+ attributeMapProgressBar[android.R.attr.max]!!.toInt())
+ assertEquals(R.style.ParentOfExplicitStyle1,
+ attributeMapProgressBar[android.R.attr.mirrorForRtl]!!.toInt())
+
+ // Switch that has an explicit style ExplicitStyle2 set via style = ...
+ val switch = rootView.findViewById<Switch>(R.id.switch_view)
+ val attributeMapSwitch = switch!!.attributeSourceResourceMap
+ assertEquals(R.layout.widget_attribute_layout,
+ attributeMapSwitch[android.R.attr.switchPadding]!!.toInt())
+
+ // Toolbar that has MyToolbarStyle set via the theme android:toolbarStyle = ...
+ val toolbar = rootView.findViewById<Toolbar>(R.id.toolbar_view)
+ val attributeMapToobar = toolbar!!.attributeSourceResourceMap
+ assertEquals(R.style.MyToolbarStyle,
+ attributeMapToobar[android.R.attr.titleMarginEnd]!!.toInt())
+ assertEquals(R.style.MyToolbarStyleParent,
+ attributeMapToobar[android.R.attr.titleMarginStart]!!.toInt())
+ }
+}
\ No newline at end of file