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 {