Merge "Fix getting proper device rotation value based upon valid displayId of multiple display device." into pie-cts-dev
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index f2640e5..72e43e2 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.verifier"
android:versionCode="5"
- android:versionName="9.0_r6">
+ android:versionName="9.0_r7">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="28"/>
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberService.java b/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberService.java
new file mode 100644
index 0000000..360c078
--- /dev/null
+++ b/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberService.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.compatibility.common.util;
+
+import static android.provider.BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER;
+import static android.provider.BlockedNumberContract.BlockedNumbers.CONTENT_URI;
+
+import android.app.IntentService;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.ResultReceiver;
+import android.util.Log;
+
+/**
+ * A service to handle interactions with the BlockedNumberProvider. The BlockedNumberProvider
+ * can only be accessed by the primary user. This service can be run as a singleton service
+ * which will then be able to access the BlockedNumberProvider from a test running in a
+ * secondary user.
+ */
+public class BlockedNumberService extends IntentService {
+
+ static final String INSERT_ACTION = "android.telecom.cts.InsertBlockedNumber";
+ static final String DELETE_ACTION = "android.telecom.cts.DeleteBlockedNumber";
+ static final String PHONE_NUMBER_EXTRA = "number";
+ static final String URI_EXTRA = "uri";
+ static final String ROWS_EXTRA = "rows";
+ static final String RESULT_RECEIVER_EXTRA = "resultReceiver";
+
+ private static final String TAG = "CtsBlockNumberSvc";
+
+ private ContentResolver mContentResolver;
+
+ public BlockedNumberService() {
+ super(BlockedNumberService.class.getName());
+ }
+
+ @Override
+ public void onHandleIntent(Intent intent) {
+ Log.i(TAG, "Starting BlockedNumberService service: " + intent);
+ if (intent == null) {
+ return;
+ }
+ Bundle bundle;
+ mContentResolver = getContentResolver();
+ switch (intent.getAction()) {
+ case INSERT_ACTION:
+ bundle = insertBlockedNumber(intent.getStringExtra(PHONE_NUMBER_EXTRA));
+ break;
+ case DELETE_ACTION:
+ bundle = deleteBlockedNumber(Uri.parse(intent.getStringExtra(URI_EXTRA)));
+ break;
+ default:
+ bundle = new Bundle();
+ break;
+ }
+ ResultReceiver receiver = intent.getParcelableExtra(RESULT_RECEIVER_EXTRA);
+ receiver.send(0, bundle);
+ }
+
+ private Bundle insertBlockedNumber(String number) {
+ Log.i(TAG, "insertBlockedNumber: " + number);
+
+ ContentValues cv = new ContentValues();
+ cv.put(COLUMN_ORIGINAL_NUMBER, number);
+ Uri uri = mContentResolver.insert(CONTENT_URI, cv);
+ Bundle bundle = new Bundle();
+ bundle.putString(URI_EXTRA, uri.toString());
+ return bundle;
+ }
+
+ private Bundle deleteBlockedNumber(Uri uri) {
+ Log.i(TAG, "deleteBlockedNumber: " + uri);
+
+ int rows = mContentResolver.delete(uri, null, null);
+ Bundle bundle = new Bundle();
+ bundle.putInt(ROWS_EXTRA, rows);
+ return bundle;
+ }
+}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberUtil.java
new file mode 100644
index 0000000..e5a0ce4
--- /dev/null
+++ b/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberUtil.java
@@ -0,0 +1,92 @@
+/*
+ * 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.compatibility.common.util;
+
+import static com.android.compatibility.common.util.BlockedNumberService.DELETE_ACTION;
+import static com.android.compatibility.common.util.BlockedNumberService.INSERT_ACTION;
+import static com.android.compatibility.common.util.BlockedNumberService.PHONE_NUMBER_EXTRA;
+import static com.android.compatibility.common.util.BlockedNumberService.RESULT_RECEIVER_EXTRA;
+import static com.android.compatibility.common.util.BlockedNumberService.ROWS_EXTRA;
+import static com.android.compatibility.common.util.BlockedNumberService.URI_EXTRA;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ResultReceiver;
+
+import junit.framework.TestCase;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Utility for starting the blocked number service.
+ */
+public class BlockedNumberUtil {
+
+ private static final int TIMEOUT = 2;
+
+ private BlockedNumberUtil() {}
+
+ /** Insert a phone number into the blocked number provider and returns the resulting Uri. */
+ public static Uri insertBlockedNumber(Context context, String phoneNumber) {
+ Intent intent = new Intent(INSERT_ACTION);
+ intent.putExtra(PHONE_NUMBER_EXTRA, phoneNumber);
+
+ return Uri.parse(runBlockedNumberService(context, intent).getString(URI_EXTRA));
+ }
+
+ /** Remove a number from the blocked number provider and returns the number of rows deleted. */
+ public static int deleteBlockedNumber(Context context, Uri uri) {
+ Intent intent = new Intent(DELETE_ACTION);
+ intent.putExtra(URI_EXTRA, uri.toString());
+
+ return runBlockedNumberService(context, intent).getInt(ROWS_EXTRA);
+ }
+
+ /** Start the blocked number service. */
+ static Bundle runBlockedNumberService(Context context, Intent intent) {
+ // Temporarily allow background service
+ SystemUtil.runShellCommand("cmd deviceidle tempwhitelist " + context.getPackageName());
+
+ final Semaphore semaphore = new Semaphore(0);
+ final Bundle result = new Bundle();
+
+ ResultReceiver receiver = new ResultReceiver(new Handler(Looper.getMainLooper())) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ result.putAll(resultData);
+ semaphore.release();
+ }
+ };
+ intent.putExtra(RESULT_RECEIVER_EXTRA, receiver);
+ intent.setComponent(new ComponentName(context, BlockedNumberService.class));
+
+ context.startService(intent);
+
+ try {
+ TestCase.assertTrue(semaphore.tryAcquire(TIMEOUT, TimeUnit.SECONDS));
+ } catch (InterruptedException e) {
+ TestCase.fail("Timed out waiting for result from BlockedNumberService");
+ }
+ return result;
+ }
+}
diff --git a/hostsidetests/backup/AndroidTest.xml b/hostsidetests/backup/AndroidTest.xml
index 868e20f..b78cd07 100644
--- a/hostsidetests/backup/AndroidTest.xml
+++ b/hostsidetests/backup/AndroidTest.xml
@@ -16,6 +16,9 @@
<configuration description="Config for CTS Backup host test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="backup" />
+ <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="test-file-name" value="CtsFullbackupApp.apk" />
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyConnectionService.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyConnectionService.java
index b00e0a4..7579cf7 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyConnectionService.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DummyConnectionService.java
@@ -126,7 +126,7 @@
}
/**
- * Hang up the call after 1 second in a background thread.
+ * Hang up the call after 5 second in a background thread.
* TODO: It is better if we could have a callback to know when we can disconnect the call.
*/
private static void hangUpAsync(final Connection connection) {
@@ -135,7 +135,7 @@
@Override
public void run() {
try {
- Thread.sleep(1000);
+ Thread.sleep(5000);
connection.setDisconnected(new DisconnectCause(cause));
} catch (InterruptedException ex) {
// let it be
@@ -143,4 +143,4 @@
}
}).start();
}
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java b/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java
index 96096fb..c17436b 100644
--- a/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java
+++ b/hostsidetests/gputools/src/android/gputools/cts/CtsRootlessGpuDebugHostTest.java
@@ -15,15 +15,10 @@
*/
package android.gputools.cts;
-import android.platform.test.annotations.Presubmit;
-
-import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.IDeviceTest;
-import com.android.ddmlib.Log;
-
import java.util.Scanner;
import org.junit.After;
@@ -218,11 +213,14 @@
setupLayer(LAYER_A_LIB);
setupLayer(LAYER_B_LIB);
+
// Copy them over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|", "run-as", DEBUG_APP,
- "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_B_LIB, "|", "run-as", DEBUG_APP,
- "sh", "-c", "\'cat", ">", LAYER_B_LIB, ";", "chmod", "700", LAYER_B_LIB + "\'");
+ mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
+ mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_B_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ "sh", "-c", "\'cat", ">", LAYER_B_LIB, ";", "chmod", "700", LAYER_B_LIB + "\'");
// Kick off our DEBUG app
mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
@@ -259,8 +257,9 @@
setupLayer(LAYER_A_LIB);
// Attempt to copy them over to our RELEASE app (this should fail)
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|", "run-as", RELEASE_APP,
- "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'", "||", "echo", "run-as", "failed");
+ mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+ "run-as", RELEASE_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'", "||", "echo", "run-as", "failed");
// Kick off our RELEASE app
mDevice.executeAdbCommand("shell", "am", "start", "-n", RELEASE_APP + "/" + ACTIVITY);
@@ -291,8 +290,9 @@
setupLayer(LAYER_A_LIB);
// Copy it over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|", "run-as", DEBUG_APP,
- "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
+ mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
// Kick off our DEBUG app
mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
@@ -323,8 +323,9 @@
setupLayer(LAYER_A_LIB);
// Copy it over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|", "run-as", DEBUG_APP,
- "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
+ mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
// Kick off our DEBUG app
mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
@@ -355,8 +356,9 @@
setupLayer(LAYER_A_LIB);
// Copy it over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|", "run-as", DEBUG_APP,
- "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
+ mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
// Kick off our DEBUG app
mDevice.executeAdbCommand("shell", "am", "start", "-n", DEBUG_APP + "/" + ACTIVITY);
@@ -418,10 +420,12 @@
setupLayer(LAYER_B_LIB);
// Copy them over to our DEBUG app
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|", "run-as", DEBUG_APP,
- "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
- mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_B_LIB, "|", "run-as", DEBUG_APP,
- "sh", "-c", "\'cat", ">", LAYER_B_LIB, ";", "chmod", "700", LAYER_B_LIB + "\'");
+ mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_A_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ "sh", "-c", "\'cat", ">", LAYER_A_LIB, ";", "chmod", "700", LAYER_A_LIB + "\'");
+ mDevice.executeAdbCommand("shell", "cat", "/data/local/tmp/" + LAYER_B_LIB, "|",
+ "run-as", DEBUG_APP, "--user", Integer.toString(mDevice.getCurrentUser()),
+ "sh", "-c", "\'cat", ">", LAYER_B_LIB, ";", "chmod", "700", LAYER_B_LIB + "\'");
// Enable layerB with system properties
mDevice.executeAdbCommand("shell", "setprop", "debug.vulkan.layers " + LAYER_B_NAME);
diff --git a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java b/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
index 348ea99..9b8e4e0 100644
--- a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
+++ b/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
@@ -50,6 +50,7 @@
import android.inputmethodservice.cts.devicetest.SequenceMatcher.MatchResult;
import android.os.SystemClock;
import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiObject2;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -211,7 +212,8 @@
final long startActivityTime = SystemClock.uptimeMillis();
helper.launchActivity(EditTextAppConstants.PACKAGE, EditTextAppConstants.CLASS,
EditTextAppConstants.URI);
- helper.findUiObject(EditTextAppConstants.EDIT_TEXT_RES_NAME).click();
+ final UiObject2 editText = helper.findUiObject(EditTextAppConstants.EDIT_TEXT_RES_NAME);
+ editText.click();
pollingCheck(() -> helper.queryAllEvents()
.filter(isNewerThan(startActivityTime))
@@ -226,7 +228,7 @@
helper.shell(ShellCommandUtils.uninstallPackage(Ime1Constants.PACKAGE));
helper.shell(ShellCommandUtils.setCurrentImeSync(Ime2Constants.IME_ID));
- helper.findUiObject(EditTextAppConstants.EDIT_TEXT_RES_NAME).click();
+ editText.click();
pollingCheck(() -> helper.queryAllEvents()
.filter(isNewerThan(imeForceStopTime))
.anyMatch(isFrom(Ime2Constants.CLASS).and(isType(ON_START_INPUT))),
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
index c14a89f..351826c 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
@@ -152,8 +152,9 @@
* Gets the uid of the test app.
*/
protected int getUid() throws Exception {
- String uidLine = getDevice().executeShellCommand("cmd package list packages -U "
- + DEVICE_SIDE_TEST_PACKAGE);
+ int currentUser = getDevice().getCurrentUser();
+ String uidLine = getDevice().executeShellCommand("cmd package list packages -U --user "
+ + currentUser + " " + DEVICE_SIDE_TEST_PACKAGE);
String[] uidLineParts = uidLine.split(":");
// 3rd entry is package uid
assertTrue(uidLineParts.length > 2);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java
index 9983699..b59b3eb 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java
@@ -71,7 +71,8 @@
return;
}
final int startingVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_ACCESSIBILITY);
- final int otherVolume = (startingVolume == 0) ? 1 : startingVolume - 1;
+ final int minVolume = mAudioManager.getStreamMinVolume(AudioManager.STREAM_ACCESSIBILITY);
+ final int otherVolume = (startingVolume == minVolume) ? (minVolume + 1) : startingVolume - 1;
final InstrumentedAccessibilityService service = InstrumentedAccessibilityService
.enableService(mInstrumentation, InstrumentedAccessibilityService.class);
try {
diff --git a/tests/admin/AndroidTest.xml b/tests/admin/AndroidTest.xml
index 7f1a7ad..94115bd 100644
--- a/tests/admin/AndroidTest.xml
+++ b/tests/admin/AndroidTest.xml
@@ -16,6 +16,10 @@
<configuration description="Config for the CTS device admin tests">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="framework" />
+ <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/AndroidTest.xml b/tests/app/AndroidTest.xml
index fbc5c38..69505c3 100644
--- a/tests/app/AndroidTest.xml
+++ b/tests/app/AndroidTest.xml
@@ -27,6 +27,7 @@
<option name="test-file-name" value="CtsCantSaveState2.apk" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
<option name="package" value="android.app.cts" />
<option name="runtime-hint" value="6m38s" />
<option name="hidden-api-checks" value="false"/>
diff --git a/tests/app/src/android/app/cts/SystemFeaturesTest.java b/tests/app/src/android/app/cts/SystemFeaturesTest.java
index e119b27..15e7ed7 100644
--- a/tests/app/src/android/app/cts/SystemFeaturesTest.java
+++ b/tests/app/src/android/app/cts/SystemFeaturesTest.java
@@ -502,16 +502,14 @@
}
public void testUsbAccessory() {
- // USB accessory mode is only a requirement for devices with USB ports supporting
- // peripheral mode. As there is no public API to distinguish a device with only host
- // mode support from having both peripheral and host support, the test may have
- // false negatives.
if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) &&
!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION) &&
!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH) &&
!mPackageManager.hasSystemFeature(PackageManager.FEATURE_EMBEDDED) &&
!isAndroidEmulator() &&
- !mPackageManager.hasSystemFeature(PackageManager.FEATURE_PC)) {
+ !mPackageManager.hasSystemFeature(PackageManager.FEATURE_PC) &&
+ mPackageManager.hasSystemFeature(PackageManager.FEATURE_MICROPHONE) &&
+ mPackageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) {
// USB accessory mode is only a requirement for devices with USB ports supporting
// peripheral mode. As there is no public API to distinguish a device with only host
// mode support from having both peripheral and host support, the test may have
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionWithLinkTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionWithLinkTestCase.java
index a32351a..f5a4f89 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionWithLinkTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CustomDescriptionWithLinkTestCase.java
@@ -19,6 +19,8 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assume.assumeTrue;
+
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 5eefb0d..d6199eb 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -93,6 +93,9 @@
"autofill_picker_accessibility_title";
private static final String RESOURCE_STRING_SAVE_SNACKBAR_ACCESSIBILITY_TITLE =
"autofill_save_accessibility_title";
+ private static final String RESOURCE_BOOLEAN_CONFIG_FORCE_DEFAULT_ORIENTATION =
+ "config_forceDefaultOrientation";
+
static final BySelector DATASET_PICKER_SELECTOR = By.res("android", RESOURCE_ID_DATASET_PICKER);
private static final BySelector SAVE_UI_SELECTOR = By.res("android", RESOURCE_ID_SAVE_SNACKBAR);
@@ -865,4 +868,24 @@
SystemClock.sleep(timeout);
}
}
-}
+
+ private boolean getBoolean(String id) {
+ final Resources resources = mContext.getResources();
+ final int booleanId = resources.getIdentifier(id, "bool", "android");
+ return resources.getBoolean(booleanId);
+ }
+
+ /**
+ * Returns {@code true} if display rotation is supported, {@code false} otherwise.
+ */
+ public boolean isScreenRotationSupported() {
+ try {
+ return !getBoolean(RESOURCE_BOOLEAN_CONFIG_FORCE_DEFAULT_ORIENTATION);
+ } catch (Resources.NotFoundException e) {
+ Log.d(TAG, "Resource not found: "
+ + RESOURCE_BOOLEAN_CONFIG_FORCE_DEFAULT_ORIENTATION
+ + ". Assume rotation supported");
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/backup/AndroidTest.xml b/tests/backup/AndroidTest.xml
index 8e0bfa0..9b6ab65 100644
--- a/tests/backup/AndroidTest.xml
+++ b/tests/backup/AndroidTest.xml
@@ -17,6 +17,11 @@
<configuration description="Config for CTS Backup test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="backup" />
+
+ <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="test-file-name" value="CtsFullBackupApp.apk" />
diff --git a/tests/camera/src/android/hardware/cts/CameraTest.java b/tests/camera/src/android/hardware/cts/CameraTest.java
index 81b42ef..9bced25 100644
--- a/tests/camera/src/android/hardware/cts/CameraTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraTest.java
@@ -1219,14 +1219,14 @@
Camera.Parameters parameters = mCamera.getParameters();
SurfaceHolder surfaceHolder;
surfaceHolder = getActivity().getSurfaceView().getHolder();
- CamcorderProfile profile = CamcorderProfile.get(cameraId,
- CamcorderProfile.QUALITY_LOW);
+ CamcorderProfile profile = null; // Used for built-in camera
Camera.Size videoSize = null; // Used for external camera
// Set the preview size.
if (mIsExternalCamera) {
videoSize = setupExternalCameraRecord(parameters);
} else {
+ profile = CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_LOW);
setPreviewSizeByProfile(parameters, profile);
}
@@ -2729,13 +2729,13 @@
Parameters parameters = mCamera.getParameters();
SurfaceHolder holder = getActivity().getSurfaceView().getHolder();
- CamcorderProfile profile = CamcorderProfile.get(cameraId,
- CamcorderProfile.QUALITY_LOW);
+ CamcorderProfile profile = null; // for built-in camera
Camera.Size videoSize = null; // for external camera
if (mIsExternalCamera) {
videoSize = setupExternalCameraRecord(parameters);
} else {
+ profile = CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_LOW);
setPreviewSizeByProfile(parameters, profile);
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java
index 5b466f4..af15187 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java
@@ -247,6 +247,12 @@
try (final RotationSession rotationSession = new RotationSession()) {
rotationSession.set(ROTATION_0);
+ mAmWmState.waitForWithWmState((wmState1) -> {
+ Rect db = wmState1.getPinnedStackMovementBounds();
+ Rect sb = wmState1.getStableBounds();
+ return (db.width() > 0 && db.height() > 0) &&
+ (sb.contains(db));
+ }, "Waiting for valid bounds...");
WindowManagerState wmState = mAmWmState.getWmState();
wmState.computeState();
Rect pipMovementBounds = wmState.getPinnedStackMovementBounds();
@@ -255,6 +261,12 @@
assertTrue(stableBounds.contains(pipMovementBounds));
rotationSession.set(ROTATION_90);
+ mAmWmState.waitForWithWmState((wmState1) -> {
+ Rect db = wmState1.getPinnedStackMovementBounds();
+ Rect sb = wmState1.getStableBounds();
+ return (db.width() > 0 && db.height() > 0) &&
+ (sb.contains(db));
+ }, "Waiting for valid bounds...");
wmState = mAmWmState.getWmState();
wmState.computeState();
pipMovementBounds = wmState.getPinnedStackMovementBounds();
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
index aebad86..5c5ac89 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
@@ -25,6 +25,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
import static android.content.pm.PackageManager.FEATURE_EMBEDDED;
import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
@@ -516,7 +517,8 @@
protected boolean supportsInsecureLock() {
return !hasDeviceFeature(FEATURE_LEANBACK)
&& !hasDeviceFeature(FEATURE_WATCH)
- && !hasDeviceFeature(FEATURE_EMBEDDED);
+ && !hasDeviceFeature(FEATURE_EMBEDDED)
+ && !hasDeviceFeature(FEATURE_AUTOMOTIVE);
}
protected boolean isWatch() {
diff --git a/tests/tests/midi/AndroidTest.xml b/tests/tests/midi/AndroidTest.xml
index d8d12e2..23c305e 100644
--- a/tests/tests/midi/AndroidTest.xml
+++ b/tests/tests/midi/AndroidTest.xml
@@ -16,6 +16,9 @@
<configuration description="Config for CTS MIDI test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="media" />
+ <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="test-file-name" value="CtsMidiTestCases.apk" />
diff --git a/tests/tests/packageinstaller/adminpackageinstaller/AndroidTest.xml b/tests/tests/packageinstaller/adminpackageinstaller/AndroidTest.xml
index 2e4a4fe..c83c612 100644
--- a/tests/tests/packageinstaller/adminpackageinstaller/AndroidTest.xml
+++ b/tests/tests/packageinstaller/adminpackageinstaller/AndroidTest.xml
@@ -18,6 +18,10 @@
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="framework" />
+ <target_preparer class="com.android.tradefed.targetprep.SwitchUserTargetPreparer">
+ <option name="user-type" value="system"/>
+ </target_preparer>
+
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="run-command" value="mkdir -p /data/local/tmp/cts/packageinstaller/" />
<option name="teardown-command" value="rm -rf /data/local/tmp/cts"/>
diff --git a/tests/tests/preference2/src/android/preference2/cts/TestUtils.java b/tests/tests/preference2/src/android/preference2/cts/TestUtils.java
index e00e658..dd25f59 100644
--- a/tests/tests/preference2/src/android/preference2/cts/TestUtils.java
+++ b/tests/tests/preference2/src/android/preference2/cts/TestUtils.java
@@ -69,10 +69,16 @@
// Crop the right side for scrollbar which might or might not be visible. On wearable
// devices the scroll bar is a curve and occupies 20% of the right side.
int xToCut = isOnWatchUiMode() ? bt.getWidth() / 5 : bt.getWidth() / 20;
+ int yToCut = statusBarHeight;
+
+ if (isLandscape()) {
+ xToCut += navigationBarHeight;
+ } else {
+ yToCut += navigationBarHeight;
+ }
bt = Bitmap.createBitmap(
- bt, 0, statusBarHeight, bt.getWidth() - xToCut,
- bt.getHeight() - statusBarHeight - navigationBarHeight);
+ bt, 0, statusBarHeight, bt.getWidth() - xToCut, bt.getHeight() - yToCut);
return bt;
}
@@ -240,4 +246,9 @@
throw new RuntimeException("Failed to run command: " + cmd, e);
}
}
+
+ private boolean isLandscape() {
+ return mInstrumentation.getTargetContext().getResources().getConfiguration().orientation ==
+ Configuration.ORIENTATION_LANDSCAPE;
+ }
}
diff --git a/tests/tests/provider/AndroidTest.xml b/tests/tests/provider/AndroidTest.xml
index 123931c..b1dbcc6 100644
--- a/tests/tests/provider/AndroidTest.xml
+++ b/tests/tests/provider/AndroidTest.xml
@@ -16,6 +16,9 @@
<configuration description="Config for CTS Provider test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="framework" />
+ <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="test-file-name" value="CtsProviderTestCases.apk" />
diff --git a/tests/tests/telecom/AndroidManifest.xml b/tests/tests/telecom/AndroidManifest.xml
index cce9785..6d2ed72 100644
--- a/tests/tests/telecom/AndroidManifest.xml
+++ b/tests/tests/telecom/AndroidManifest.xml
@@ -71,6 +71,15 @@
</intent-filter>
</service>
+ <service android:name="com.android.compatibility.common.util.BlockedNumberService"
+ android:exported="true"
+ android:singleUser="true" >
+ <intent-filter>
+ <action android:name="android.telecom.cts.InsertBlockedNumber"/>
+ <action android:name="android.telecom.cts.DeleteBlockedNumber"/>
+ </intent-filter>
+ </service>
+
<receiver android:name="android.telecom.cts.MockMissedCallNotificationReceiver">
<intent-filter>
<action android:name="android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION" />
diff --git a/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
index 871f3e4..954112b 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
@@ -17,13 +17,14 @@
package android.telecom.cts;
import static android.telecom.cts.TestUtils.*;
+import static com.android.compatibility.common.util.BlockedNumberUtil.deleteBlockedNumber;
+import static com.android.compatibility.common.util.BlockedNumberUtil.insertBlockedNumber;
import android.app.UiModeManager;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
-import android.provider.BlockedNumberContract;
import android.telecom.CallAudioState;
import android.telecom.Call;
import android.telecom.Connection;
@@ -393,17 +394,17 @@
assertNull(mInCallCallbacks.getService());
} finally {
if (blockedUri != null) {
- mContext.getContentResolver().delete(blockedUri, null, null);
+ unblockNumber(blockedUri);
}
}
}
private Uri blockNumber(Uri phoneNumberUri) {
- ContentValues cv = new ContentValues();
- cv.put(BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER,
- phoneNumberUri.getSchemeSpecificPart());
- return mContext.getContentResolver().insert(
- BlockedNumberContract.BlockedNumbers.CONTENT_URI, cv);
+ return insertBlockedNumber(mContext, phoneNumberUri.getSchemeSpecificPart());
+ }
+
+ private int unblockNumber(Uri uri) {
+ return deleteBlockedNumber(mContext, uri);
}
public void testAnswerIncomingCallAsVideo_SendsCorrectVideoState() {
diff --git a/tests/tests/telephony/AndroidManifest.xml b/tests/tests/telephony/AndroidManifest.xml
index b6840a3..2360145 100644
--- a/tests/tests/telephony/AndroidManifest.xml
+++ b/tests/tests/telephony/AndroidManifest.xml
@@ -30,6 +30,7 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.telephony.embms.cts.permission.TEST_BROADCAST"/>
<permission android:name="android.telephony.embms.cts.permission.TEST_BROADCAST"
@@ -119,6 +120,15 @@
</service>
+ <service android:name="com.android.compatibility.common.util.BlockedNumberService"
+ android:exported="true"
+ android:singleUser="true" >
+ <intent-filter>
+ <action android:name="android.telecom.cts.InsertBlockedNumber"/>
+ <action android:name="android.telecom.cts.DeleteBlockedNumber"/>
+ </intent-filter>
+ </service>
+
<activity android:name="android.telephony.cts.StubDialerActvity">
<intent-filter>
<action android:name="android.intent.action.DIAL"/>
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
index 74f9d13..89814aa 100755
--- a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
@@ -16,11 +16,12 @@
package android.telephony.cts;
+import static com.android.compatibility.common.util.BlockedNumberUtil.deleteBlockedNumber;
+import static com.android.compatibility.common.util.BlockedNumberUtil.insertBlockedNumber;
import android.app.PendingIntent;
import android.app.UiAutomation;
import android.content.BroadcastReceiver;
-import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -29,7 +30,6 @@
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
-import android.provider.BlockedNumberContract;
import android.provider.Telephony;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
@@ -118,7 +118,7 @@
@Override
protected void tearDown() throws Exception {
if (mBlockedNumberUri != null) {
- mContext.getContentResolver().delete(mBlockedNumberUri, null, null);
+ unblockNumber(mBlockedNumberUri);
mBlockedNumberUri = null;
}
if (mTestAppSetAsDefaultSmsApp) {
@@ -398,17 +398,18 @@
getSmsManager().sendTextMessage(destAddr, null, text, sentIntent, deliveredIntent);
}
- private void blockNumber(String phoneNumber) {
- ContentValues cv = new ContentValues();
- cv.put(BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER, phoneNumber);
- mBlockedNumberUri = mContext.getContentResolver().insert(
- BlockedNumberContract.BlockedNumbers.CONTENT_URI, cv);
+ private void blockNumber(String number) {
+ mBlockedNumberUri = insertBlockedNumber(mContext, number);
+ }
+
+ private void unblockNumber(Uri uri) {
+ deleteBlockedNumber(mContext, uri);
}
private void setDefaultSmsApp(boolean setToSmsApp)
throws Exception {
String command = String.format(
- "appops set %s WRITE_SMS %s",
+ "appops set --user 0 %s WRITE_SMS %s",
mContext.getPackageName(),
setToSmsApp ? "allow" : "default");
assertTrue("Setting default SMS app failed : " + setToSmsApp,
diff --git a/tests/tests/view/res/values-ldpi/dimens.xml b/tests/tests/view/res/values-ldpi/dimens.xml
new file mode 100644
index 0000000..5b79a3e
--- /dev/null
+++ b/tests/tests/view/res/values-ldpi/dimens.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<resources>
+ <dimen name="hover_target_margin">6dp</dimen>
+ <dimen name="hover_target_size">12dp</dimen>
+ <dimen name="hover_target_size_double">24dp</dimen>
+</resources>
diff --git a/tests/tests/view/src/android/view/cts/PixelCopyViewProducerActivity.java b/tests/tests/view/src/android/view/cts/PixelCopyViewProducerActivity.java
index 69e1e7f..054de45 100644
--- a/tests/tests/view/src/android/view/cts/PixelCopyViewProducerActivity.java
+++ b/tests/tests/view/src/android/view/cts/PixelCopyViewProducerActivity.java
@@ -65,6 +65,8 @@
mContent = new ColoredGrid(this);
setContentView(mContent);
+ View view = this.getWindow().getDecorView();
+ view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
mContent.getViewTreeObserver().addOnDrawListener(this);
mContent.setOnApplyWindowInsetsListener(this);
}
diff --git a/tests/tests/view/src/android/view/cts/PixelCopyWideGamutViewProducerActivity.java b/tests/tests/view/src/android/view/cts/PixelCopyWideGamutViewProducerActivity.java
index f697095..d8a512d 100644
--- a/tests/tests/view/src/android/view/cts/PixelCopyWideGamutViewProducerActivity.java
+++ b/tests/tests/view/src/android/view/cts/PixelCopyWideGamutViewProducerActivity.java
@@ -64,6 +64,8 @@
mContent = new WideGamutBitmapView(this);
setContentView(mContent);
+ View view = this.getWindow().getDecorView();
+ view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
mContent.getViewTreeObserver().addOnDrawListener(this);
}
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 8cfaec3..a9b0d9e 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -105,10 +105,9 @@
* compatibility definition (tokens in angle brackets are variables, tokens in square
* brackets are optional):
* <p/>
- * Mozilla/5.0 (Linux;[ U;] Android <version>;[ <language>-<country>;]
- * [<devicemodel>;] Build/<buildID>; wv) AppleWebKit/<major>.<minor> (KHTML, like Gecko)
- * Version/<major>.<minor> Chrome/<major>.<minor>.<branch>.<build>[ Mobile]
- * Safari/<major>.<minor>
+ * Mozilla/5.0 (Linux; Android <version>; [<devicemodel>;] [Build/<buildID>;] wv)
+ * AppleWebKit/<major>.<minor> (KHTML, like Gecko) Version/<major>.<minor>
+ * Chrome/<major>.<minor>.<branch>.<build>[ Mobile] Safari/<major>.<minor>
*/
public void testUserAgentString_default() {
if (!NullWebViewUtils.isWebViewAvailable()) {
@@ -116,43 +115,34 @@
}
final String actualUserAgentString = mSettings.getUserAgentString();
Log.i(LOG_TAG, String.format("Checking user agent string %s", actualUserAgentString));
+
+ String expectedRelease, expectedModel;
+ if ("REL".equals(Build.VERSION.CODENAME)) {
+ expectedRelease = Pattern.quote(Build.VERSION.RELEASE);
+ expectedModel = Pattern.quote(Build.MODEL);
+ } else {
+ // Non-release builds don't include real release version/model, be lenient.
+ expectedRelease = expectedModel = "[^;]+";
+ }
+
+ // Build expected regex inserting the appropriate variables, as this is easier to
+ // understand and get right than matching any possible useragent and comparing the
+ // variables afterward.
final String patternString =
- "Mozilla/5\\.0 \\(Linux;( U;)? Android ([^;]+);( (\\w+)-(\\w+);)?" +
- "\\s?(.*)\\sBuild/(.+); wv\\) AppleWebKit/(\\d+)\\.(\\d+) " +
- "\\(KHTML, like Gecko\\) " +
- "Version/\\d+\\.\\d+ Chrome/\\d+\\.\\d+\\.\\d+\\.\\d+( Mobile)? " +
- "Safari/(\\d+)\\.(\\d+)";
- // Groups used:
- // 1 - SSL encryption strength token " U;" (optional)
- // 2 - Android version
- // 3 - full locale string (optional)
- // 4 - country
- // 5 - language
- // 6 - device model (optional)
- // 7 - build ID
- // 8 - AppleWebKit major version number
- // 9 - AppleWebKit minor version number
- // 10 - " Mobile" string (optional)
- // 11 - Safari major version number
- // 12 - Safari minor version number
+ Pattern.quote("Mozilla/5.0 (Linux; Android ") + expectedRelease + "; " +
+ "(" + expectedModel + "; )?" + // Optional
+ "(Build/" + Pattern.quote(Build.ID) + "; )?" + // Optional
+ Pattern.quote("wv) ") +
+ "AppleWebKit/\\d+\\.\\d+ " +
+ Pattern.quote("(KHTML, like Gecko) Version/4.0 ") +
+ "Chrome/\\d+\\.\\d+\\.\\d+\\.\\d+ " +
+ "(Mobile )?Safari/\\d+\\.\\d+";
Log.i(LOG_TAG, String.format("Trying to match pattern %s", patternString));
final Pattern userAgentExpr = Pattern.compile(patternString);
Matcher patternMatcher = userAgentExpr.matcher(actualUserAgentString);
assertTrue(String.format("User agent string did not match expected pattern. \nExpected " +
"pattern:\n%s\nActual:\n%s", patternString, actualUserAgentString),
patternMatcher.find());
- if (patternMatcher.group(3) != null) {
- Locale currentLocale = Locale.getDefault();
- assertEquals(currentLocale.getLanguage().toLowerCase(), patternMatcher.group(4));
- assertEquals(currentLocale.getCountry().toLowerCase(), patternMatcher.group(5));
- }
- if ("REL".equals(Build.VERSION.CODENAME)) {
- // Model is only added in release builds
- assertEquals(Build.MODEL, patternMatcher.group(6));
- // Release version is valid only in release builds
- assertEquals(Build.VERSION.RELEASE, patternMatcher.group(2));
- }
- assertEquals(Build.ID, patternMatcher.group(7));
}
public void testAccessUserAgentString() throws Exception {