Merge "Fix JobThrottling tests, take 2." into rvc-dev
diff --git a/apps/CrossProfileTestApp/Android.bp b/apps/CrossProfileTestApp/Android.bp
new file mode 100644
index 0000000..cbf092b
--- /dev/null
+++ b/apps/CrossProfileTestApp/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test_helper_app {
+    name: "CrossProfileTestApp",
+    defaults: ["cts_defaults"],
+    srcs: ["src/**/*.java"],
+    resource_dirs: ["res"],
+    sdk_version: "current",
+    min_sdk_version: "12",
+    // tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts",
+        "general-tests",
+    ],
+}
diff --git a/apps/CrossProfileTestApp/AndroidManifest.xml b/apps/CrossProfileTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..ab04e55
--- /dev/null
+++ b/apps/CrossProfileTestApp/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.crossprofilepermissioncontrol" >
+
+    <application android:label="Cross Profile Test App">
+        <activity android:name=".TestActivity"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <intent-filter>
+            <action android:name="com.android.cts.verifier.managedprovisioning.action.OPEN_CROSS_PROFILE_TEST_APP" />
+            <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_PROFILES"/>
+</manifest>
diff --git a/apps/CrossProfileTestApp/OWNERS b/apps/CrossProfileTestApp/OWNERS
new file mode 100644
index 0000000..e889bfe
--- /dev/null
+++ b/apps/CrossProfileTestApp/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 149743808
+sandness@google.com
+arangelov@google.com
+alexkershaw@google.com
+scottjonathan@google.com
+kholoudm@google.com
diff --git a/apps/CrossProfileTestApp/res/layout/main.xml b/apps/CrossProfileTestApp/res/layout/main.xml
new file mode 100644
index 0000000..1b199ea
--- /dev/null
+++ b/apps/CrossProfileTestApp/res/layout/main.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical"
+              android:gravity="center">
+    <Button
+        android:id="@+id/cross_profile_settings"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/open_settings"/>
+
+    <TextView
+        android:id="@+id/cross_profile_app_text"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textSize="30sp"
+        android:textAlignment="center"
+        android:gravity="center"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CrossProfileTestApp/res/values/strings.xml b/apps/CrossProfileTestApp/res/values/strings.xml
new file mode 100644
index 0000000..93c0174
--- /dev/null
+++ b/apps/CrossProfileTestApp/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="open_settings">Open Settings</string>
+    <string name="cross_profile_enabled">INTERACTING ACROSS PROFILES ALLOWED</string>
+    <string name="cross_profile_disabled">INTERACTING ACROSS PROFILES NOT ALLOWED</string>
+
+</resources>
\ No newline at end of file
diff --git a/apps/CrossProfileTestApp/src/com/android/cts/crossprofilepermissioncontrol/TestActivity.java b/apps/CrossProfileTestApp/src/com/android/cts/crossprofilepermissioncontrol/TestActivity.java
new file mode 100644
index 0000000..e4364f1
--- /dev/null
+++ b/apps/CrossProfileTestApp/src/com/android/cts/crossprofilepermissioncontrol/TestActivity.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.crossprofilepermissioncontrol;
+
+import android.app.Activity;
+import android.app.AppOpsManager;
+import android.content.pm.CrossProfileApps;
+import android.os.Bundle;
+import android.os.Process;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Test activity to check if the app can interact across profiles.
+ */
+public class TestActivity extends Activity {
+    private static final String INTERACT_ACROSS_PROFILES =
+            "android.permission.INTERACT_ACROSS_PROFILES";
+    private AppOpsManager mAppOpsManager;
+    private CrossProfileApps mCrossProfileApps;
+    private TextView mTextView;
+    private Button mSettingsButton;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+        mTextView = findViewById(R.id.cross_profile_app_text);
+        mSettingsButton = findViewById(R.id.cross_profile_settings);
+
+        mAppOpsManager = getSystemService(AppOpsManager.class);
+        mCrossProfileApps = getSystemService(CrossProfileApps.class);
+
+        mSettingsButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                startActivity(mCrossProfileApps.createRequestInteractAcrossProfilesIntent());
+            }
+        });
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        updateText();
+    }
+
+    private void updateText() {
+        final String op = AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES);
+        if (AppOpsManager.MODE_ALLOWED == mAppOpsManager.checkOpNoThrow(
+                op, Process.myUid(), getPackageName())) {
+            mTextView.setText(R.string.cross_profile_enabled);
+        } else {
+            mTextView.setText(R.string.cross_profile_disabled);
+        }
+    }
+}
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index f5f0d5e..a7651b6 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -113,7 +113,8 @@
     CtsEmptyDeviceOwner \
     CtsPermissionApp \
     CtsForceStopHelper \
-    NotificationBot
+    NotificationBot \
+    CrossProfileTestApp
 
 # Apps to be installed as Instant App using adb install --instant
 pre-installed-instant-app := CtsVerifierInstantApp
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 0703a59..0d5b5b1 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -2871,6 +2871,14 @@
                 android:label="@string/provisioning_byod_keyguard_disabled_features">
         </activity>
 
+        <activity android:name=".managedprovisioning.CrossProfilePermissionControlActivity"
+                  android:label="@string/provisioning_byod_cross_profile_permission_control">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.CROSS_PROFILE_PERMISSION_CONTROL" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".managedprovisioning.DisallowAppsControlActivity"
                 android:label="@string/provisioning_byod_disallow_apps_control">
         </activity>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 4f9cc0a9..bbc663c 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -2775,6 +2775,44 @@
         \n
         Verify that you are prompted with the above choices and both options work as intended. Then mark this test accordingly.
     </string>
+    <string name="provisioning_byod_cross_profile_permission_control">Cross profile permission control</string>
+    <string name="provisioning_byod_cross_profile_permission_control_info">
+        This test exercises cross profile permission controls. Follow instructions above.
+    </string>
+    <string name="provisioning_byod_cross_profile_permission_control_instruction">
+        For this test you need to install CrossProfileTestApp.apk by running
+        adb install -r -t /path/to/CrossProfileTestApp.apk. Make sure the app is installed
+        on both the personal and work profiles.\n
+        Press the \"Prepare test\" button to enable configuring cross profile for the test app.\n
+        Then press through the following verification steps.\n
+        Mark the test as passed if all the following test cases are verified.
+    </string>
+    <string name="provisioning_byod_cross_profile_permission_control_prepare_button">Prepare test</string>
+    <string name="provisioning_byod_cross_profile_permission_disabled_by_default">Cross profile permission disabled by default</string>
+    <string name="provisioning_byod_cross_profile_permission_disabled_by_default_instruction">
+        Press the Go button to go to Settings &gt; Apps &amp; notifications &gt; Special app access >\n
+        Connected personal and work apps.\n
+        Choose the \"Cross profile test app\" from the list and check that the switch is disabled.\n
+        Go back to CTS Verifier and mark the test as \"Pass\" or \"Fail\".
+    </string>
+    <string name="provisioning_byod_cross_profile_permission_enabled">Cross profile permission enabled</string>
+    <string name="provisioning_byod_cross_profile_permission_enabled_instruction">
+        Press the Go button to open the \"Cross Profile Test App\".\n
+        Press the \"Open Settings\" button to go to Settings &gt; Apps &amp; notifications &gt; Special app access >
+        Connected personal and work apps > Cross profile test app, then enable the switch.\n
+        Verify that when you go back it takes you to the \"Cross Profile Test App\".\n
+        Now verify that it shows \"INTERACTING ACROSS PROFILES ALLOWED\" message.\n
+        Go back to CTS Verifier and mark the test as \"Pass\" or \"Fail\".
+    </string>
+    <string name="provisioning_byod_cross_profile_permission_disabled">Cross profile permission disabled</string>
+    <string name="provisioning_byod_cross_profile_permission_disabled_instruction">
+        Press the Go button to open the \"Cross Profile Test App\".\n
+        Press the \"Open Settings\" button to go to Settings &gt; Apps &amp; notifications &gt; Special app access >
+        Connected personal and work apps > Cross profile test app, then disable the switch.\n
+        Verify that when you go back it takes you to the \"Cross Profile Test App\".\n
+        Now verify that it shows \"INTERACTING ACROSS PROFILES NOT ALLOWED\" message.\n
+        Go back to CTS Verifier and mark the test as \"Pass\" or \"Fail\".
+    </string>
     <string name="provisioning_byod_app_linking_instruction">
         Please press the Go button to start an action.\n
         \n
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index b13e3aa..656cd89 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -23,7 +23,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
@@ -90,6 +89,7 @@
     private DialogTestListItem mWorkAppVisibleTest;
     private DialogTestListItem mCrossProfileIntentFiltersTestFromPersonal;
     private DialogTestListItem mCrossProfileIntentFiltersTestFromWork;
+    private TestListItem mCrossProfilePermissionControl;
     private DialogTestListItem mAppLinkingTest;
     private TestListItem mNonMarketAppsTest;
     private DialogTestListItem mWorkNotificationBadgedTest;
@@ -451,6 +451,13 @@
             }
         };
 
+        mCrossProfilePermissionControl = TestListItem.newTest(this,
+                R.string.provisioning_byod_cross_profile_permission_control,
+                CrossProfilePermissionControlActivity.class.getName(),
+                new Intent(
+                        CrossProfilePermissionControlActivity.ACTION_CROSS_PROFILE_PERMISSION_CONTROL),
+                        null);
+
         mTurnOffWorkFeaturesTest = TestListItem.newTest(this,
                 R.string.provisioning_byod_turn_off_work,
                 TurnOffWorkActivity.class.getName(),
@@ -544,6 +551,7 @@
         adapter.add(mAppLinkingTest);
         */
         adapter.add(mIntentFiltersTest);
+        adapter.add(mCrossProfilePermissionControl);
         adapter.add(mNonMarketAppsTest);
         adapter.add(mPermissionLockdownTest);
         adapter.add(mKeyguardDisabledFeaturesTest);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestHelper.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestHelper.java
index 24e0919..2bb1046 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestHelper.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestHelper.java
@@ -58,6 +58,7 @@
                 AuthenticationBoundKeyTestActivity.class.getName(),
                 VpnTestActivity.class.getName(),
                 AlwaysOnVpnSettingsTestActivity.class.getName(),
+                CrossProfilePermissionControlActivity.class.getName(),
                 IntermediateRecentActivity.class.getName(),
                 CommandReceiverActivity.class.getName(),
                 SetSupportMessageActivity.class.getName(),
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CrossProfilePermissionControlActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CrossProfilePermissionControlActivity.java
new file mode 100644
index 0000000..ef7dd67
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CrossProfilePermissionControlActivity.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.managedprovisioning;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.DialogTestListActivity;
+import com.android.cts.verifier.R;
+
+import java.util.Set;
+
+public class CrossProfilePermissionControlActivity extends DialogTestListActivity {
+    static final String ACTION_CROSS_PROFILE_PERMISSION_CONTROL =
+            "com.android.cts.verifier.managedprovisioning.action.CROSS_PROFILE_PERMISSION_CONTROL";
+    private static final String TEST_APP_PACKAGE_NAME =
+            "com.android.cts.crossprofilepermissioncontrol";
+    private static final String OPEN_TEST_APP_ACTION =
+            "com.android.cts.verifier.managedprovisioning.action.OPEN_CROSS_PROFILE_TEST_APP";
+
+    protected DevicePolicyManager mDpm;
+
+    public CrossProfilePermissionControlActivity() {
+        super(R.layout.provisioning_byod,
+                R.string.provisioning_byod_cross_profile_permission_control,
+                R.string.provisioning_byod_cross_profile_permission_control_info,
+                R.string.provisioning_byod_cross_profile_permission_control_instruction);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mDpm = getSystemService(DevicePolicyManager.class);
+        mPrepareTestButton.setText(
+                R.string.provisioning_byod_cross_profile_permission_control_prepare_button);
+        mPrepareTestButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    whitelistTestApp();
+                }
+            });
+    }
+
+    protected void whitelistTestApp() {
+        mDpm.setCrossProfilePackages(getAdminComponent(), Set.of(TEST_APP_PACKAGE_NAME));
+    }
+
+    protected ComponentName getAdminComponent() {
+        return DeviceAdminTestReceiver.getReceiverComponentName();
+    }
+
+    protected void setupInteractAcrossProfilesDisabledByDefault(ArrayTestListAdapter adapter) {
+        adapter.add(new DialogTestListItem(
+                this, R.string.provisioning_byod_cross_profile_permission_disabled_by_default,
+                getTestIdPrefix() + "interactAcrossProfilesDisabledByDefault",
+                R.string.provisioning_byod_cross_profile_permission_disabled_by_default_instruction,
+                new Intent(Settings.ACTION_MANAGE_CROSS_PROFILE_ACCESS)));
+    }
+
+    protected void setupInteractAcrossProfilesEnabled(ArrayTestListAdapter adapter) {
+        adapter.add(new DialogTestListItem(
+                this, R.string.provisioning_byod_cross_profile_permission_enabled,
+                getTestIdPrefix() + "interactAcrossProfilesEnabled",
+                R.string.provisioning_byod_cross_profile_permission_enabled_instruction,
+                new Intent(OPEN_TEST_APP_ACTION)));
+    }
+
+    protected void setupInteractAcrossProfilesDisabled(ArrayTestListAdapter adapter) {
+        adapter.add(new DialogTestListItem(this,
+                R.string.provisioning_byod_cross_profile_permission_disabled,
+                getTestIdPrefix() + "DisableUnredactedNotifications",
+                R.string.provisioning_byod_cross_profile_permission_disabled_instruction,
+                new Intent(OPEN_TEST_APP_ACTION)));
+    }
+
+    protected String getTestIdPrefix() {
+        return "BYOD_";
+    }
+
+    @Override
+    protected void setupTests(ArrayTestListAdapter adapter) {
+        setupInteractAcrossProfilesDisabledByDefault(adapter);
+        setupInteractAcrossProfilesEnabled(adapter);
+        setupInteractAcrossProfilesDisabled(adapter);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
index 11351ec..c9e2449 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
@@ -181,6 +181,8 @@
         filter.addAction(KeyChainTestActivity.ACTION_KEYCHAIN);
         filter.addAction(CommandReceiverActivity.ACTION_EXECUTE_COMMAND);
         filter.addAction(WorkProfileWidgetActivity.ACTION_TEST_WORK_PROFILE_WIDGET);
+        filter.addAction(
+                CrossProfilePermissionControlActivity.ACTION_CROSS_PROFILE_PERMISSION_CONTROL);
         dpm.addCrossProfileIntentFilter(getWho(context), filter,
                 DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
 
@@ -192,6 +194,7 @@
         filter.addAction(ByodFlowTestActivity.ACTION_TEST_RESULT);
         filter.addAction(CrossProfileTestActivity.ACTION_CROSS_PROFILE_TO_PERSONAL);
         filter.addAction(LocationListenerActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES);
+
         dpm.addCrossProfileIntentFilter(getWho(context), filter,
                 DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
 
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/res/values/strings.xml b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/res/values/strings.xml
index e5300ab..2a322aa 100755
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/res/values/strings.xml
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/res/values/strings.xml
@@ -5,4 +5,5 @@
     <string name="Ask">Ask every time</string>
     <string name="Allow">Allow</string>
     <string name="AllowAll">Allow all the time</string>
+    <string name="AllowForeground">Allow only while using the app</string>
 </resources>
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/res/values/strings.xml b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/res/values/strings.xml
index e5300ab..2a322aa 100755
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/res/values/strings.xml
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/res/values/strings.xml
@@ -5,4 +5,5 @@
     <string name="Ask">Ask every time</string>
     <string name="Allow">Allow</string>
     <string name="AllowAll">Allow all the time</string>
+    <string name="AllowForeground">Allow only while using the app</string>
 </resources>
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
index 8b5630c..da6e44b 100755
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
@@ -16,18 +16,16 @@
 
 package com.android.cts.usepermission;
 
-import static com.android.compatibility.common.util.UiAutomatorUtils.waitFindObject;
 import static com.android.compatibility.common.util.UiAutomatorUtils.getUiDevice;
+import static com.android.compatibility.common.util.UiAutomatorUtils.waitFindObject;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.TestCase.assertTrue;
 
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
 
 import android.Manifest;
 import android.app.Activity;
@@ -36,20 +34,16 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
-import android.icu.text.CaseMap;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.BySelector;
-import android.support.test.uiautomator.Direction;
-import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject2;
 import android.support.test.uiautomator.UiObjectNotFoundException;
 import android.support.test.uiautomator.UiScrollable;
 import android.support.test.uiautomator.UiSelector;
-import android.support.test.uiautomator.Until;
 import android.text.Spanned;
 import android.text.style.ClickableSpan;
 import android.util.ArrayMap;
@@ -67,7 +61,6 @@
 import com.android.compatibility.common.util.UiDumpUtils;
 
 import junit.framework.Assert;
-import junit.framework.TestCase;
 
 import org.junit.Before;
 import org.junit.runner.RunWith;
@@ -76,7 +69,6 @@
 import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.regex.Pattern;
 
@@ -449,19 +441,27 @@
                     waitForIdle();
                 }
 
-                final boolean wasGranted = isTv() ? false : !(waitFindObject(byText(R.string.Deny)).isChecked() || (!legacyApp && waitFindObject(byText(R.string.Ask)).isChecked()));
+                final boolean wasGranted = isTv()
+                        ? false
+                        : !(waitFindObject(byText(R.string.Deny)).isChecked()
+                                || (legacyApp
+                                    && hasAskButton(permission)
+                                    && waitFindObject(byText(R.string.Ask)).isChecked()));
                 boolean alreadyChecked = false;
                 if (isTv()) {
                     waitFindObject(By.text(permissionLabel)).click();
                 } else if (state == STATE_ALLOWED) {
-                    UiObject2 object = waitFindObject(byText(R.string.Allow));
+                    UiObject2 object = waitFindObject(byText(
+                            showsForegroundOnlyButton(permission)
+                                    ? R.string.AllowForeground
+                                    : R.string.Allow));
                     alreadyChecked = object.isChecked();
                     if (!alreadyChecked) {
                         object.click();
                     }
                 } else if (state == STATE_DENIED){
                     UiObject2 object;
-                    if (legacyApp) {
+                    if (legacyApp || !hasAskButton(permission)) {
                         object = waitFindObject(byText(R.string.Deny));
                     } else {
                         object = waitFindObject(byText(R.string.Ask));
@@ -529,6 +529,19 @@
         return mPlatformResources.getString(resourceId);
     }
 
+    private boolean hasAskButton(String permission) {
+        return Manifest.permission.CAMERA.equals(permission)
+                || Manifest.permission.RECORD_AUDIO.equals(permission)
+                || Manifest.permission.ACCESS_FINE_LOCATION.equals(permission)
+                || Manifest.permission.ACCESS_COARSE_LOCATION.equals(permission)
+                || Manifest.permission.ACCESS_BACKGROUND_LOCATION.equals(permission);
+    }
+
+    private boolean showsForegroundOnlyButton(String permission) {
+        return Manifest.permission.CAMERA.equals(permission)
+                || Manifest.permission.RECORD_AUDIO.equals(permission);
+    }
+
     private void startActivity(final Intent intent) throws Exception {
         getInstrumentation().getUiAutomation().executeAndWaitForEvent(
                 () -> {
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
index a958816..3be949d 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
@@ -285,9 +285,9 @@
     public void testGrantPreviouslyRevokedWithPrejudiceShowsPrompt_part1() throws Exception {
         // Make sure we don't have the permission
         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
-                .checkSelfPermission(Manifest.permission.READ_CALENDAR));
+                .checkSelfPermission(Manifest.permission.CAMERA));
 
-        String[] permissions = new String[] {Manifest.permission.READ_CALENDAR};
+        String[] permissions = new String[] {Manifest.permission.CAMERA};
 
         // Request the permission and deny it
         BasePermissionActivity.Result firstResult = requestPermissions(permissions, () -> {
@@ -300,7 +300,7 @@
 
         // Request the permission and choose don't ask again
         BasePermissionActivity.Result secondResult = requestPermissions(new String[]{
-                Manifest.permission.READ_CALENDAR}, () -> {
+                Manifest.permission.CAMERA}, () -> {
             denyWithPrejudice();
             getUiDevice().waitForIdle();
         });
@@ -309,8 +309,8 @@
         assertPermissionRequestResult(secondResult, permissions, new boolean[] {false});
 
         // Clear the denial with prejudice
-        grantPermission(Manifest.permission.READ_CALENDAR);
-        revokePermission(Manifest.permission.READ_CALENDAR);
+        grantPermission(Manifest.permission.CAMERA);
+        revokePermission(Manifest.permission.CAMERA);
 
         // We just committed a suicide by revoking the permission. See part2 below...
     }
@@ -319,17 +319,17 @@
     public void testGrantPreviouslyRevokedWithPrejudiceShowsPrompt_part2() throws Exception {
         // Make sure we don't have the permission
         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
-                .checkSelfPermission(Manifest.permission.READ_CALENDAR));
+                .checkSelfPermission(Manifest.permission.CAMERA));
 
         // Request the permission and allow it
         BasePermissionActivity.Result thirdResult = requestPermissions(new String[]{
-                Manifest.permission.READ_CALENDAR}, () -> {
-            clickAllowButton();
+                Manifest.permission.CAMERA}, () -> {
+            clickAllowForegroundButton();
             getUiDevice().waitForIdle();
         });
 
         // Make sure the permission is granted
-        assertPermissionRequestResult(thirdResult, new String[] {Manifest.permission.READ_CALENDAR},
+        assertPermissionRequestResult(thirdResult, new String[] {Manifest.permission.CAMERA},
                 new boolean[] {true});
     }
 
diff --git a/hostsidetests/content/src/android/content/cts/ContextCrossProfileHostTest.java b/hostsidetests/content/src/android/content/cts/ContextCrossProfileHostTest.java
index ed8c59a..509bf75 100644
--- a/hostsidetests/content/src/android/content/cts/ContextCrossProfileHostTest.java
+++ b/hostsidetests/content/src/android/content/cts/ContextCrossProfileHostTest.java
@@ -74,7 +74,7 @@
 
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                mParentUserId, /* extraArgs= */"-t");
+                mParentUserId, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
     }
 
     @After
@@ -89,7 +89,7 @@
     public void setBuild(IBuildInfo buildInfo) {
         mCtsBuild = buildInfo;
     }
-    
+
     @Test
     public void testBindServiceAsUser_differentUser_bindsServiceToCorrectUser()
             throws Exception {
@@ -98,13 +98,13 @@
         mTestArgs.put("testUser", Integer.toString(userInSameProfileGroup));
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         File testServiceApkFile = buildHelper.getTestFile(TEST_SERVICE_WITH_PERMISSION_APK);
         getDevice().installPackageForUser(
                 testServiceApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         runDeviceTests(
                 getDevice(),
@@ -125,13 +125,13 @@
         mTestArgs.put("testUser", Integer.toString(userInSameProfileGroup));
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         File testServiceApkFile = buildHelper.getTestFile(TEST_SERVICE_WITH_PERMISSION_APK);
         getDevice().installPackageForUser(
                 testServiceApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         runDeviceTests(
                 getDevice(),
@@ -152,13 +152,13 @@
         mTestArgs.put("testUser", Integer.toString(userInSameProfileGroup));
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         File testServiceApkFile = buildHelper.getTestFile(TEST_SERVICE_WITH_PERMISSION_APK);
         getDevice().installPackageForUser(
                 testServiceApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         runDeviceTests(
                 getDevice(),
@@ -179,13 +179,13 @@
         mTestArgs.put("testUser", Integer.toString(userInSameProfileGroup));
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         File testServiceApkFile = buildHelper.getTestFile(TEST_SERVICE_WITH_PERMISSION_APK);
         getDevice().installPackageForUser(
                 testServiceApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         runDeviceTests(
                 getDevice(),
@@ -206,13 +206,13 @@
         mTestArgs.put("testUser", Integer.toString(userInSameProfileGroup));
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         File testServiceApkFile = buildHelper.getTestFile(TEST_SERVICE_WITH_PERMISSION_APK);
         getDevice().installPackageForUser(
                 testServiceApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         runDeviceTests(
                 getDevice(),
@@ -233,13 +233,13 @@
         mTestArgs.put("testUser", Integer.toString(userInSameProfileGroup));
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         File testServiceApkFile = buildHelper.getTestFile(TEST_SERVICE_WITH_PERMISSION_APK);
         getDevice().installPackageForUser(
                 testServiceApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         runDeviceTests(
                 getDevice(),
@@ -260,13 +260,13 @@
         mTestArgs.put("testUser", Integer.toString(userInSameProfileGroup));
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         File testServiceApkFile = buildHelper.getTestFile(TEST_SERVICE_WITH_PERMISSION_APK);
         getDevice().installPackageForUser(
                 testServiceApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         runDeviceTests(
                 getDevice(),
@@ -287,13 +287,15 @@
         mTestArgs.put("testUser", Integer.toString(userInDifferentProfileGroup));
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInDifferentProfileGroup, /* extraArgs= */"-t");
+                userInDifferentProfileGroup, /* extraArgs= */"-t",
+                /* extraArgs= */"--force-queryable");
 
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         File testServiceApkFile = buildHelper.getTestFile(TEST_SERVICE_WITH_PERMISSION_APK);
         getDevice().installPackageForUser(
                 testServiceApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInDifferentProfileGroup, /* extraArgs= */"-t");
+                userInDifferentProfileGroup, /* extraArgs= */"-t",
+                /* extraArgs= */"--force-queryable");
 
         runDeviceTests(
                 getDevice(),
@@ -314,13 +316,15 @@
         mTestArgs.put("testUser", Integer.toString(userInDifferentProfileGroup));
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInDifferentProfileGroup, /* extraArgs= */"-t");
+                userInDifferentProfileGroup, /* extraArgs= */"-t",
+                /* extraArgs= */"--force-queryable");
 
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         File testServiceApkFile = buildHelper.getTestFile(TEST_SERVICE_WITH_PERMISSION_APK);
         getDevice().installPackageForUser(
                 testServiceApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInDifferentProfileGroup, /* extraArgs= */"-t");
+                userInDifferentProfileGroup, /* extraArgs= */"-t",
+                /* extraArgs= */"--force-queryable");
 
         runDeviceTests(
                 getDevice(),
@@ -341,13 +345,15 @@
         mTestArgs.put("testUser", Integer.toString(userInDifferentProfileGroup));
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInDifferentProfileGroup, /* extraArgs= */"-t");
+                userInDifferentProfileGroup, /* extraArgs= */"-t",
+                /* extraArgs= */"--force-queryable");
 
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         File testServiceApkFile = buildHelper.getTestFile(TEST_SERVICE_WITH_PERMISSION_APK);
         getDevice().installPackageForUser(
                 testServiceApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInDifferentProfileGroup, /* extraArgs= */"-t");
+                userInDifferentProfileGroup, /* extraArgs= */"-t",
+                /* extraArgs= */"--force-queryable");
 
         runDeviceTests(
                 getDevice(),
@@ -368,13 +374,13 @@
         mTestArgs.put("testUser", Integer.toString(userInSameProfileGroup));
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         File testServiceApkFile = buildHelper.getTestFile(TEST_SERVICE_WITH_PERMISSION_APK);
         getDevice().installPackageForUser(
                 testServiceApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         runDeviceTests(
                 getDevice(),
@@ -395,13 +401,13 @@
         mTestArgs.put("testUser", Integer.toString(userInSameProfileGroup));
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         File testServiceApkFile = buildHelper.getTestFile(TEST_SERVICE_WITH_PERMISSION_APK);
         getDevice().installPackageForUser(
                 testServiceApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         runDeviceTests(
                 getDevice(),
@@ -422,13 +428,13 @@
         mTestArgs.put("testUser", Integer.toString(userInSameProfileGroup));
         getDevice().installPackageForUser(
                 mApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
         File testServiceApkFile = buildHelper.getTestFile(TEST_SERVICE_WITH_PERMISSION_APK);
         getDevice().installPackageForUser(
                 testServiceApkFile, /* reinstall= */true, /* grantPermissions= */true,
-                userInSameProfileGroup, /* extraArgs= */"-t");
+                userInSameProfileGroup, /* extraArgs= */"-t", /* extraArgs= */"--force-queryable");
 
         runDeviceTests(
                 getDevice(),
diff --git a/hostsidetests/incident/Android.bp b/hostsidetests/incident/Android.bp
index 1589078..3a3801b 100644
--- a/hostsidetests/incident/Android.bp
+++ b/hostsidetests/incident/Android.bp
@@ -26,5 +26,6 @@
         "tradefed",
         "compatibility-host-util",
         "platformprotos",
+        "truth-prebuilt",
     ],
 }
diff --git a/hostsidetests/incident/apps/graphicsstatsapp/Android.bp b/hostsidetests/incident/apps/graphicsstatsapp/Android.bp
index 52b5c74..c64f8a8 100644
--- a/hostsidetests/incident/apps/graphicsstatsapp/Android.bp
+++ b/hostsidetests/incident/apps/graphicsstatsapp/Android.bp
@@ -24,6 +24,7 @@
         "ctstestrunner-axt",
         "compatibility-device-util-axt",
         "androidx.legacy_legacy-support-v4",
+        "truth-prebuilt",
     ],
     sdk_version: "test_current",
     // tag this module as a cts test artifact
diff --git a/hostsidetests/incident/apps/graphicsstatsapp/AndroidManifest.xml b/hostsidetests/incident/apps/graphicsstatsapp/AndroidManifest.xml
index be9d645..88e1eaf 100644
--- a/hostsidetests/incident/apps/graphicsstatsapp/AndroidManifest.xml
+++ b/hostsidetests/incident/apps/graphicsstatsapp/AndroidManifest.xml
@@ -22,6 +22,8 @@
         <uses-library android:name="android.test.runner" />
         <activity android:name=".DrawFramesActivity"
                   android:label="GraphicsStats Test Activity"
+                  android:screenOrientation="locked"
+                  android:resizeableActivity="false"
                   android:theme="@style/DefaultTheme"/>
     </application>
 
diff --git a/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java b/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java
index 1bbc601..fd1206f 100644
--- a/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java
+++ b/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java
@@ -144,10 +144,6 @@
         }
     }
 
-    public void drawFrames(final int frameCount) throws InterruptedException, TimeoutException {
-        drawFrames(new int[frameCount]);
-    }
-
     public void waitForReady() throws InterruptedException, TimeoutException {
         if (!mReady.await(4, TimeUnit.SECONDS)) {
             throw new TimeoutException();
diff --git a/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/SimpleDrawFrameTests.java b/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/SimpleDrawFrameTests.java
index 56413f8..1a93309 100644
--- a/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/SimpleDrawFrameTests.java
+++ b/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/SimpleDrawFrameTests.java
@@ -15,13 +15,14 @@
  */
 package com.android.server.cts.device.graphicsstats;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
 
 import androidx.test.filters.LargeTest;
 import androidx.test.rule.ActivityTestRule;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.google.common.collect.Range;
+
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -38,25 +39,37 @@
     public ActivityTestRule<DrawFramesActivity> mActivityRule =
             new ActivityTestRule<>(DrawFramesActivity.class);
 
-    @Test
-    public void testDrawTenFrames() throws Throwable {
+    void runTest(final int frameCount) throws Throwable {
+        runTest(new int[frameCount]);
+    }
+
+    void runTest(final int[] framesToDraw) throws Throwable {
         DrawFramesActivity activity = mActivityRule.getActivity();
         activity.waitForReady();
         int initialFrames = activity.getRenderedFramesCount();
-        assertTrue(initialFrames < 5);
-        assertEquals(0, activity.getDroppedReportsCount());
-        activity.drawFrames(10);
-        assertEquals(initialFrames + 10, activity.getRenderedFramesCount());
-        assertEquals(0, activity.getDroppedReportsCount());
+        assertThat(initialFrames).isLessThan(5);
+        assertThat(activity.getDroppedReportsCount()).isEqualTo(0);
+        activity.drawFrames(framesToDraw);
+        final int expectedFrameCount = initialFrames + framesToDraw.length;
+        assertThat(activity.getRenderedFramesCount()).isIn(
+                Range.closedOpen(expectedFrameCount, expectedFrameCount + 5));
+        assertThat(activity.getDroppedReportsCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testNothing() throws Throwable {
+        DrawFramesActivity activity = mActivityRule.getActivity();
+        activity.waitForReady();
+        activity.drawFrames(new int[10]);
+    }
+
+    @Test
+    public void testDrawTenFrames() throws Throwable {
+        runTest(10);
     }
 
     @Test
     public void testDrawJankyFrames() throws Throwable {
-        DrawFramesActivity activity = mActivityRule.getActivity();
-        activity.waitForReady();
-        int initialFrames = activity.getRenderedFramesCount();
-        assertTrue(initialFrames < 5);
-        assertEquals(0, activity.getDroppedReportsCount());
         int[] frames = new int[50];
         for (int i = 0; i < 10; i++) {
             int indx = i * 5;
@@ -65,26 +78,17 @@
             frames[indx + 2] = DrawFramesActivity.FRAME_JANK_LAYOUT;
             frames[indx + 3] = DrawFramesActivity.FRAME_JANK_MISS_VSYNC;
         }
-        activity.drawFrames(frames);
-        assertEquals(initialFrames + 50, activity.getRenderedFramesCount());
-        assertEquals(0, activity.getDroppedReportsCount());
+        runTest(frames);
     }
 
     @Test
     public void testDrawDaveyFrames() throws Throwable {
-        DrawFramesActivity activity = mActivityRule.getActivity();
-        activity.waitForReady();
-        int initialFrames = activity.getRenderedFramesCount();
-        assertTrue(initialFrames < 5);
-        assertEquals(0, activity.getDroppedReportsCount());
         int[] frames = new int[40];
         for (int i = 0; i < 10; i++) {
             int indx = i * 4;
             frames[indx] = DrawFramesActivity.FRAME_JANK_DAVEY;
             frames[indx + 2] = DrawFramesActivity.FRAME_JANK_DAVEY_JR;
         }
-        activity.drawFrames(frames);
-        assertEquals(initialFrames + 40, activity.getRenderedFramesCount());
-        assertEquals(0, activity.getDroppedReportsCount());
+        runTest(frames);
     }
 }
diff --git a/hostsidetests/incident/src/com/android/server/cts/GraphicsStatsValidationTest.java b/hostsidetests/incident/src/com/android/server/cts/GraphicsStatsValidationTest.java
index ea1f803..843531d 100644
--- a/hostsidetests/incident/src/com/android/server/cts/GraphicsStatsValidationTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/GraphicsStatsValidationTest.java
@@ -15,12 +15,14 @@
  */
 package com.android.server.cts;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import android.service.GraphicsStatsHistogramBucketProto;
 import android.service.GraphicsStatsJankSummaryProto;
 import android.service.GraphicsStatsProto;
 import android.service.GraphicsStatsServiceDumpProto;
 
-import com.android.tradefed.log.LogUtil.CLog;
+import com.google.common.collect.Range;
 
 import java.util.ArrayList;
 import java.util.Date;
@@ -46,7 +48,7 @@
         turnScreenOn();
         // Ensure that we have a starting point for our stats
         runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".SimpleDrawFrameTests",
-                "testDrawTenFrames");
+                "testNothing");
         // Kill to ensure that stats persist/merge across process death
         killTestApp();
     }
@@ -91,24 +93,24 @@
         int jankyDelta = summaryAfter.getJankyFrames() - summaryBefore.getJankyFrames();
         // Test draws 50 frames + 1 initial frame. We expect 40 of them to be janky,
         // 10 of each of ANIMATION, LAYOUT, RECORD_DRAW, and MISSED_VSYNC
-        assertTrue(frameDelta < 55);
-        assertTrue(jankyDelta >= 40);
-        assertTrue(jankyDelta < 45);
+
+        assertThat(frameDelta).isAtLeast(50);
+        assertThat(jankyDelta).isAtLeast(40);
+        assertThat(jankyDelta).isLessThan(45);
 
         // Although our current stats don't distinguish between ANIMATION, LAYOUT, and RECORD_DRAW
         // so this will just be slowUi +30
         int slowUiDelta = summaryAfter.getSlowUiThreadCount() - summaryBefore.getSlowUiThreadCount();
-        assertTrue(slowUiDelta >= 30);
+        assertThat(slowUiDelta).isAtLeast(28);
         int missedVsyncDelta = summaryAfter.getMissedVsyncCount()
                 - summaryBefore.getMissedVsyncCount();
-        assertTrue(missedVsyncDelta >= 10);
-        assertTrue(missedVsyncDelta <= 11);
+        assertThat(missedVsyncDelta).isIn(Range.closed(10, 11));
 
         int veryJankyDelta = countFramesAbove(statsAfter, 60) - countFramesAbove(statsBefore, 60);
         // The 1st frame could be >40ms, but nothing after that should be
-        assertTrue(veryJankyDelta <= 2);
+        assertThat(veryJankyDelta).isAtMost(2);
         int noGPUJank = countGPUFramesAbove(statsAfter, 60) - countGPUFramesAbove(statsBefore, 60);
-        assertTrue(noGPUJank == 0);
+        assertThat(noGPUJank).isEqualTo(0);
     }
 
     public void testDaveyDrawFrame() throws Exception {
@@ -123,13 +125,12 @@
         int jankyDelta = summaryAfter.getJankyFrames() - summaryBefore.getJankyFrames();
         // Test draws 40 frames + 1 initial frame. We expect 10 of them to be daveys,
         // 10 of them to be daveyjrs, and 20 to jank from missed vsync (from the davey/daveyjr prior to it)
-        assertTrue(frameDelta < 45);
-        assertTrue(jankyDelta >= 20);
-        assertTrue(jankyDelta < 25);
+        assertThat(frameDelta).isAtLeast(40);
+        assertThat(jankyDelta).isAtLeast(20);
+        assertThat(jankyDelta).isLessThan(25);
 
         int gt150msDelta = countFramesAbove(statsAfter, 150) - countFramesAbove(statsBefore, 150);
-        assertTrue(gt150msDelta >= 20); // 10 davey jrs + 10 daveys + maybe first 2 frames
-        assertTrue(gt150msDelta <= 22);
+        assertThat(gt150msDelta).isIn(Range.closed(20, 22));
         int gt700msDelta = countFramesAbove(statsAfter, 700) - countFramesAbove(statsBefore, 700);
         assertEquals(10, gt700msDelta); // 10 daveys
     }
@@ -139,10 +140,10 @@
     }
 
     private GraphicsStatsProto[] doRunDrawTest(String testName, boolean canRetry) throws Exception {
-        GraphicsStatsProto statsBefore = fetchStats();
-        assertNotNull(statsBefore);
         killTestApp();
         turnScreenOn();
+        GraphicsStatsProto statsBefore = fetchStats();
+        assertNotNull(statsBefore);
         runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".SimpleDrawFrameTests",  testName);
         killTestApp();
         GraphicsStatsProto statsAfter = fetchStats();
diff --git a/hostsidetests/securitybulletin/res/CVE-2018-9490.pac b/hostsidetests/securitybulletin/res/CVE-2018-9490.pac
index 9fb7ba8..999518a 100644
--- a/hostsidetests/securitybulletin/res/CVE-2018-9490.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2018-9490.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     alert("enter");
     let arr = [];
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2045.pac b/hostsidetests/securitybulletin/res/CVE-2019-2045.pac
index 1cb28ff..a6b0166 100644
--- a/hostsidetests/securitybulletin/res/CVE-2019-2045.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2045.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     opttest();
     opttest();
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2047.pac b/hostsidetests/securitybulletin/res/CVE-2019-2047.pac
index 5e39e9b..b70e24a 100644
--- a/hostsidetests/securitybulletin/res/CVE-2019-2047.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2047.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     for(var i = 0;i<0x10000;i++){
         change_elements_kind(x);
@@ -40,4 +56,4 @@
 var evil = new Array(1.1,2.2);
 evil.x = {};
 
-var x = new Array({});
\ No newline at end of file
+var x = new Array({});
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2051.pac b/hostsidetests/securitybulletin/res/CVE-2019-2051.pac
index b014a16..b24b160 100644
--- a/hostsidetests/securitybulletin/res/CVE-2019-2051.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2051.pac
@@ -1,5 +1,21 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     this.__defineGetter__("x", (a = (function f() { return; (function() {}); })()) => { });
     x;
     return "DIRECT";
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2052.pac b/hostsidetests/securitybulletin/res/CVE-2019-2052.pac
index ab5ed69..670e870 100644
--- a/hostsidetests/securitybulletin/res/CVE-2019-2052.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2052.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     for(var i = 0;i < 0x1000;i++){
         tt();
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2097.pac b/hostsidetests/securitybulletin/res/CVE-2019-2097.pac
index 6c0a8b0..4880f54 100644
--- a/hostsidetests/securitybulletin/res/CVE-2019-2097.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2097.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     for (var  i = 0; i < 0x10000; i++){
         f();
@@ -19,4 +35,4 @@
         array[i][0] = {"abcd":0x4321};
     }
     double_arr[1] = 6.176516726456e-312;
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2130.pac b/hostsidetests/securitybulletin/res/CVE-2019-2130.pac
index 79d1967..77a0cb5 100644
--- a/hostsidetests/securitybulletin/res/CVE-2019-2130.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2130.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     function opt() {
         opt['x'] = 1.1;
@@ -18,4 +34,4 @@
     return "DIRECT";
 }
 
-var object;
\ No newline at end of file
+var object;
diff --git a/hostsidetests/securitybulletin/res/bug_138441919.pac b/hostsidetests/securitybulletin/res/bug_138441919.pac
index 61a9ee2..006fb6a 100644
--- a/hostsidetests/securitybulletin/res/bug_138441919.pac
+++ b/hostsidetests/securitybulletin/res/bug_138441919.pac
@@ -1,6 +1,22 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     Object.defineProperty(Promise, Symbol.species, { value: 0 });
     var p = new Promise(function() {});
     p.then();
     return "DIRECT";
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/securitybulletin/res/bug_139806216.pac b/hostsidetests/securitybulletin/res/bug_139806216.pac
index 3a1e34d..256108d 100644
--- a/hostsidetests/securitybulletin/res/bug_139806216.pac
+++ b/hostsidetests/securitybulletin/res/bug_139806216.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     var x = new ArrayBuffer(1);
     return "DIRECT";
diff --git a/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp b/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp
index ef0a5cb..1a7e5b6 100755
--- a/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp
@@ -49,6 +49,8 @@
         case InputMessage::Type::KEY: {
             // uint32_t seq
             outMsg->body.key.seq = msg.body.key.seq;
+            // int32_t eventId
+            outMsg->body.key.eventId = msg.body.key.eventId;
             // nsecs_t eventTime
             outMsg->body.key.eventTime = msg.body.key.eventTime;
             // int32_t deviceId
@@ -78,6 +80,8 @@
         case InputMessage::Type::MOTION: {
             // uint32_t seq
             outMsg->body.motion.seq = msg.body.motion.seq;
+            // int32_t eventId
+            outMsg->body.motion.eventId = msg.body.key.eventId;
             // nsecs_t eventTime
             outMsg->body.motion.eventTime = msg.body.motion.eventTime;
             // int32_t deviceId
@@ -146,6 +150,7 @@
         }
         case InputMessage::Type::FOCUS: {
             outMsg->body.focus.seq = msg.body.focus.seq;
+            outMsg->body.focus.eventId = msg.body.focus.eventId;
             outMsg->body.focus.hasFocus = msg.body.focus.hasFocus;
             outMsg->body.focus.inTouchMode = msg.body.focus.inTouchMode;
             break;
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/poc.c
index 238bb0b..b5386e1 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/poc.c
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/poc.c
@@ -1,4 +1,20 @@
 /*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
  * CVE-2016-5862
  */
 
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/poc.c
index c8e4a20..3b8771f 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/poc.c
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/poc.c
@@ -1,4 +1,20 @@
 /*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
  * CVE-2016-5867
  */
 
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0333/local_poc.h b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0333/local_poc.h
index 1622b39..8dad1b8 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0333/local_poc.h
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0333/local_poc.h
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 #ifndef __LOCAL_POC_H__
 #define __LOCAL_POC_H__
 
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9515/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9515/poc.c
index a89d596..d8f3471 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9515/poc.c
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9515/poc.c
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 #define _GNU_SOURCE
 #include <pthread.h>
 #include <err.h>
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9539/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9539/poc.cpp
index 5f9bd37..0b464e5 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9539/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9539/poc.cpp
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 #include <android/hardware/cas/1.0/ICas.h>
 #include <android/hardware/cas/1.0/IMediaCasService.h>
 #include <android/hardware/cas/native/1.0/IDescrambler.h>
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/HostsideMainlineModuleDetector.java b/hostsidetests/securitybulletin/src/android/security/cts/HostsideMainlineModuleDetector.java
index e62a7b3..1d57cb6 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/HostsideMainlineModuleDetector.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/HostsideMainlineModuleDetector.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package android.security.cts;
 
 import com.android.ddmlib.Log;
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
index 9c55177..7458be5 100644
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
+++ b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
@@ -22,7 +22,10 @@
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningServiceInfo;
 import android.app.AlarmManager;
+import android.app.AppOpsManager;
 import android.app.PendingIntent;
 import android.app.job.JobInfo;
 import android.app.job.JobScheduler;
@@ -61,6 +64,8 @@
 
 import androidx.test.InstrumentationRegistry;
 
+import com.android.compatibility.common.util.ShellIdentityUtils;
+
 import org.junit.Test;
 
 import java.util.Arrays;
@@ -71,6 +76,8 @@
 public class AtomTests {
     private static final String TAG = AtomTests.class.getSimpleName();
 
+    private static final String MY_PACKAGE_NAME = "com.android.server.cts.device.statsd";
+
     @Test
     public void testAudioState() {
         // TODO: This should surely be getTargetContext(), here and everywhere, but test first.
@@ -230,6 +237,58 @@
     }
 
     @Test
+    public void testForegroundServiceAccessAppOp() throws Exception {
+        Context context = InstrumentationRegistry.getContext();
+        Intent fgsIntent = new Intent(context, StatsdCtsForegroundService.class);
+        AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
+
+        // No foreground service session
+        noteAppOp(appOpsManager, AppOpsManager.OPSTR_COARSE_LOCATION, true);
+
+        // Foreground service session 1
+        context.startService(fgsIntent);
+        while (!checkIfServiceRunning(context, StatsdCtsForegroundService.class.getName())) {
+            sleep(50);
+        }
+        noteAppOp(appOpsManager, AppOpsManager.OPSTR_CAMERA, true);
+        noteAppOp(appOpsManager, AppOpsManager.OPSTR_FINE_LOCATION, true);
+        noteAppOp(appOpsManager, AppOpsManager.OPSTR_CAMERA, true);
+        noteAppOp(appOpsManager, AppOpsManager.OPSTR_RECORD_AUDIO, false);
+        noteAppOp(appOpsManager, AppOpsManager.OPSTR_RECORD_AUDIO, true);
+        context.stopService(fgsIntent);
+
+        // No foreground service session
+        noteAppOp(appOpsManager, AppOpsManager.OPSTR_COARSE_LOCATION, true);
+
+        // TODO(b/149098800): Start fgs a second time and log OPSTR_CAMERA again
+    }
+
+    /** @param doNote true if should use noteOp; false if should use startOp. */
+    private void noteAppOp(AppOpsManager appOpsManager, String opStr, boolean doNote) {
+        if (doNote) {
+            ShellIdentityUtils.invokeMethodWithShellPermissions(appOpsManager,
+                    (aom) -> aom.noteOp(opStr, android.os.Process.myUid(), MY_PACKAGE_NAME, null,
+                            "statsdTest"));
+        } else {
+            ShellIdentityUtils.invokeMethodWithShellPermissions(appOpsManager,
+                    (aom) -> aom.startOp(opStr, android.os.Process.myUid(),
+                            MY_PACKAGE_NAME, null, "statsdTest"));
+        }
+        sleep(500);
+    }
+
+    /** Check if service is running. */
+    public boolean checkIfServiceRunning(Context context, String serviceName) {
+        ActivityManager manager = context.getSystemService(ActivityManager.class);
+        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
+            if (serviceName.equals(service.service.getClassName()) && service.foreground) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Test
     public void testGpsScan() {
         Context context = InstrumentationRegistry.getContext();
         final LocationManager locManager = context.getSystemService(LocationManager.class);
@@ -396,7 +455,7 @@
 
     @Test
     public void testScheduledJob() throws Exception {
-        final ComponentName name = new ComponentName("com.android.server.cts.device.statsd",
+        final ComponentName name = new ComponentName(MY_PACKAGE_NAME,
                 StatsdJobService.class.getName());
 
         Context context = InstrumentationRegistry.getContext();
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index 1d4b2d6..ac45c06 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -22,7 +22,6 @@
 import android.os.WakeLockLevelEnum;
 import android.server.ErrorSource;
 
-import com.android.internal.os.StatsdConfigProto.FieldMatcher;
 import com.android.internal.os.StatsdConfigProto.StatsdConfig;
 import com.android.os.AtomsProto;
 import com.android.os.AtomsProto.ANROccurred;
@@ -40,12 +39,13 @@
 import com.android.os.AtomsProto.DangerousPermissionStateSampled;
 import com.android.os.AtomsProto.DeviceCalculatedPowerBlameUid;
 import com.android.os.AtomsProto.FlashlightStateChanged;
+import com.android.os.AtomsProto.ForegroundServiceAppOpSessionEnded;
 import com.android.os.AtomsProto.ForegroundServiceStateChanged;
 import com.android.os.AtomsProto.GpsScanStateChanged;
 import com.android.os.AtomsProto.HiddenApiUsed;
 import com.android.os.AtomsProto.IonHeapSize;
-import com.android.os.AtomsProto.LooperStats;
 import com.android.os.AtomsProto.LmkKillOccurred;
+import com.android.os.AtomsProto.LooperStats;
 import com.android.os.AtomsProto.MediaCodecStateChanged;
 import com.android.os.AtomsProto.OverlayStateChanged;
 import com.android.os.AtomsProto.PackageNotificationPreferences;
@@ -73,7 +73,6 @@
 import java.lang.ProcessBuilder;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -544,6 +543,51 @@
                 atom -> atom.getForegroundServiceStateChanged().getState().getNumber());
     }
 
+
+    public void testForegroundServiceAccessAppOp() throws Exception {
+        if (statsdDisabled()) {
+            return;
+        }
+        final int atomTag = Atom.FOREGROUND_SERVICE_APP_OP_SESSION_ENDED_FIELD_NUMBER;
+        final String name = "testForegroundServiceAccessAppOp";
+
+        createAndUploadConfig(atomTag, false);
+        Thread.sleep(WAIT_TIME_SHORT);
+
+        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", name);
+
+        // Sorted list of events in order in which they occurred.
+        List<EventMetricData> data = getEventMetricDataList();
+
+        assertWithMessage("Wrong atom size").that(data.size()).isEqualTo(3);
+        for (int i = 0; i < data.size(); i++) {
+            ForegroundServiceAppOpSessionEnded atom
+                    = data.get(i).getAtom().getForegroundServiceAppOpSessionEnded();
+            final int opName = atom.getAppOpName().getNumber();
+            final int acceptances = atom.getCountOpsAccepted();
+            final int rejections = atom.getCountOpsRejected();
+            final int count = acceptances + rejections;
+            int expectedCount = 0;
+            switch (opName) {
+                case ForegroundServiceAppOpSessionEnded.AppOpName.OP_CAMERA_VALUE:
+                    expectedCount = 2;
+                    break;
+                case ForegroundServiceAppOpSessionEnded.AppOpName.OP_FINE_LOCATION_VALUE:
+                    expectedCount = 1;
+                    break;
+                case ForegroundServiceAppOpSessionEnded.AppOpName.OP_RECORD_AUDIO_VALUE:
+                    expectedCount = 2;
+                    break;
+                case ForegroundServiceAppOpSessionEnded.AppOpName.OP_COARSE_LOCATION_VALUE:
+                    // fall-through
+                default:
+                    fail("Unexpected opName " + opName);
+            }
+            assertWithMessage("Wrong count for " + opName).that(count).isEqualTo(expectedCount);
+
+        }
+    }
+
     public void testGpsScan() throws Exception {
         if (statsdDisabled()) {
             return;
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/TriggerContentTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/TriggerContentTest.java
index 0c9cebb..32f5a1a 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/TriggerContentTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/TriggerContentTest.java
@@ -133,12 +133,10 @@
     private JobInfo makePhotosJobInfo() {
         JobInfo.Builder builder = new JobInfo.Builder(TRIGGER_CONTENT_JOB_ID,
                 kTriggerContentServiceComponent);
-        // Look for specific changes to images in the provider.
+        // Look for general reports of changes in the overall provider.
         builder.addTriggerContentUri(new JobInfo.TriggerContentUri(
-                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+                MEDIA_URI,
                 JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
-        // Also look for general reports of changes in the overall provider.
-        builder.addTriggerContentUri(new JobInfo.TriggerContentUri(MEDIA_URI, 0));
         // For testing purposes, react quickly.
         builder.setTriggerContentUpdateDelay(500);
         builder.setTriggerContentMaxDelay(500);
diff --git a/tests/accessibility/res/drawable/size_48x48.jpg b/tests/accessibility/res/drawable/jpg_48_48.jpg
similarity index 100%
rename from tests/accessibility/res/drawable/size_48x48.jpg
rename to tests/accessibility/res/drawable/jpg_48_48.jpg
Binary files differ
diff --git a/tests/accessibility/res/drawable/png_72_72.png b/tests/accessibility/res/drawable/png_72_72.png
new file mode 100644
index 0000000..941458d
--- /dev/null
+++ b/tests/accessibility/res/drawable/png_72_72.png
Binary files differ
diff --git a/tests/accessibility/res/drawable/vector_drawable_6kdp_6kdp.xml b/tests/accessibility/res/drawable/vector_drawable_6kdp_6kdp.xml
new file mode 100644
index 0000000..0d11dc0
--- /dev/null
+++ b/tests/accessibility/res/drawable/vector_drawable_6kdp_6kdp.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="6000dp"
+        android:height="6000dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M6,18c0,0.55 0.45,1 1,1h1v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L11,19h2v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L16,19h1c0.55,0 1,-0.45 1,-1L18,8L6,8v10zM3.5,8C2.67,8 2,8.67 2,9.5v7c0,0.83 0.67,1.5 1.5,1.5S5,17.33 5,16.5v-7C5,8.67 4.33,8 3.5,8zM20.5,8c-0.83,0 -1.5,0.67 -1.5,1.5v7c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5v-7c0,-0.83 -0.67,-1.5 -1.5,-1.5zM15.53,2.16l1.3,-1.3c0.2,-0.2 0.2,-0.51 0,-0.71 -0.2,-0.2 -0.51,-0.2 -0.71,0l-1.48,1.48C13.85,1.23 12.95,1 12,1c-0.96,0 -1.86,0.23 -2.66,0.63L7.85,0.15c-0.2,-0.2 -0.51,-0.2 -0.71,0 -0.2,0.2 -0.2,0.51 0,0.71l1.31,1.31C6.97,3.26 6,5.01 6,7h12c0,-1.99 -0.97,-3.75 -2.47,-4.84zM10,5L9,5L9,4h1v1zM15,5h-1L14,4h1v1z"/>
+</vector>
diff --git a/tests/accessibility/res/raw/test_file b/tests/accessibility/res/raw/test_file
new file mode 100644
index 0000000..acea7ed
--- /dev/null
+++ b/tests/accessibility/res/raw/test_file
@@ -0,0 +1,12 @@
+10101010110101010101101010101011010101010110101010101101010101011010101010110
+1010101011010101010110101010101101010101011010101011010101101101010101011011011010101101101
+1011010101010011010101010110101011011010101010110101011011010101010110110110101010101101
+10110101010101101010101011010101010110101010101101010101010101101010101011010101
+101101010101011010101010110101010101101010101011010101101011010101010110101010101101010101011010101
+101101010101101010101011010101101101010101011010101001010110101011011010101010110110101010101
+10110101010101101010101011010101010110101010101101010101010101101
+101101010101010110101010101101010110110101010101101010101011010101011101010101011010101101101010
+10110101010101011010101101101010101011010101101010101011010101101010101011010101
+101101010101011010101011010101010110101011011010101010110101010101101010101
+
+
diff --git a/tests/accessibility/res/values/strings.xml b/tests/accessibility/res/values/strings.xml
index de1539a..40c3359 100644
--- a/tests/accessibility/res/values/strings.xml
+++ b/tests/accessibility/res/values/strings.xml
@@ -32,8 +32,26 @@
     <!-- Description of the speaking accessibility service -->
     <string name="some_description">Some description</string>
 
+    <!-- Html description of the vibrating accessibility service -->
+    <string name="html_description_vibrating_accessibility_service"><![CDATA[
+    <A href=\"fake_link\">Test link</a> <IMG src = \"R.drawable.file_name\">
+    ]]></string>
+
     <!-- Html description of the speaking accessibility service -->
-    <string name="some_html_description">Some html description</string>
+    <string name="html_description_speaking_accessibility_service"><![CDATA[
+    <a href=\"fake_link\"> <img src=\"R.drawable.file_name\">
+    ]]></string>
+
+    <!-- Html description of the speaking and vibrating accessibility service -->
+    <string name="html_description_speaking_and_vibrating_accessibility_service"><![CDATA[
+    <a href=fake_link> <img src=R.drawable.file_name>
+    ]]></string>
+
+    <!-- Html description of the accessibility button service -->
+    <string name="html_description_accessibility_button_service"><![CDATA[
+    <img src=\"r.drawable.file_name\"> <img alt=\"foo\" src=\"R.drawable.file_name\">
+    <img src=\"file://path\"> <img src=\"http://path\">
+    ]]></string>
 
     <!-- Summary of the speaking accessibility service -->
     <string name="some_summary">Some summary</string>
diff --git a/tests/accessibility/res/xml/accessibility_button_service.xml b/tests/accessibility/res/xml/accessibility_button_service.xml
index d475266..e483fd4 100644
--- a/tests/accessibility/res/xml/accessibility_button_service.xml
+++ b/tests/accessibility/res/xml/accessibility_button_service.xml
@@ -18,4 +18,6 @@
                        android:accessibilityEventTypes="typeAllMask"
                        android:accessibilityFeedbackType="feedbackGeneric"
                        android:accessibilityFlags="flagRequestAccessibilityButton"
+                       android:animatedImageDrawable="@raw/test_file"
+                       android:htmlDescription="@string/html_description_accessibility_button_service"
                        android:notificationTimeout="0" />
\ No newline at end of file
diff --git a/tests/accessibility/res/xml/speaking_accessibilityservice.xml b/tests/accessibility/res/xml/speaking_accessibilityservice.xml
index ede686d..9128309 100644
--- a/tests/accessibility/res/xml/speaking_accessibilityservice.xml
+++ b/tests/accessibility/res/xml/speaking_accessibilityservice.xml
@@ -21,9 +21,9 @@
     android:canRequestTouchExplorationMode="true"
     android:canRequestFilterKeyEvents="true"
     android:settingsActivity="foo.bar.Activity"
-    android:animatedImageDrawable="@drawable/size_48x48"
+    android:animatedImageDrawable="@drawable/jpg_48_48"
     android:description="@string/some_description"
-    android:htmlDescription="@string/some_html_description"
+    android:htmlDescription="@string/html_description_speaking_accessibility_service"
     android:summary="@string/some_summary"
     android:nonInteractiveUiTimeout="1000"
     android:interactiveUiTimeout="6000"/>
\ No newline at end of file
diff --git a/tests/accessibility/res/xml/speaking_and_vibrating_accessibilityservice.xml b/tests/accessibility/res/xml/speaking_and_vibrating_accessibilityservice.xml
index 3ac8661..09d36c6 100644
--- a/tests/accessibility/res/xml/speaking_and_vibrating_accessibilityservice.xml
+++ b/tests/accessibility/res/xml/speaking_and_vibrating_accessibilityservice.xml
@@ -22,7 +22,7 @@
     android:canRequestFilterKeyEvents="true"
     android:canRequestEnhancedWebAccessibility="true"
     android:settingsActivity="foo.bar.Activity"
-    android:animatedImageDrawable="@drawable/size_48x48"
+    android:animatedImageDrawable="@drawable/vector_drawable_6kdp_6kdp"
     android:description="@string/some_description"
-    android:htmlDescription="@string/some_html_description"
+    android:htmlDescription="@string/html_description_speaking_and_vibrating_accessibility_service"
     android:summary="@string/some_summary" />
diff --git a/tests/accessibility/res/xml/vibrating_accessibilityservice.xml b/tests/accessibility/res/xml/vibrating_accessibilityservice.xml
index 93d9f0d..ddf4018 100644
--- a/tests/accessibility/res/xml/vibrating_accessibilityservice.xml
+++ b/tests/accessibility/res/xml/vibrating_accessibilityservice.xml
@@ -20,4 +20,6 @@
     android:canRetrieveWindowContent="true"
     android:canRequestTouchExplorationMode="true"
     android:nonInteractiveUiTimeout="2000"
+    android:animatedImageDrawable="@drawable/png_72_72"
+    android:htmlDescription="@string/html_description_vibrating_accessibility_service"
     android:interactiveUiTimeout="5000"/>
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
index d2f7c2d..2c8535d 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
@@ -26,13 +26,14 @@
 import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibility.cts.common.InstrumentedAccessibilityServiceTestRule;
 import android.accessibilityservice.AccessibilityServiceInfo;
-import android.app.Service;
+import android.content.pm.PackageManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 
 import androidx.test.filters.MediumTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
@@ -49,22 +50,42 @@
  */
 @RunWith(AndroidJUnit4.class)
 public class AccessibilityServiceInfoTest {
+    private AccessibilityManager mAccessibilityManager;
+    private PackageManager mPackageManager;
 
-    private InstrumentedAccessibilityServiceTestRule<SpeakingAccessibilityService>
+    private final InstrumentedAccessibilityServiceTestRule<SpeakingAccessibilityService>
             mSpeakingAccessibilityServiceRule = new InstrumentedAccessibilityServiceTestRule<>(
-                    SpeakingAccessibilityService.class);
+            SpeakingAccessibilityService.class);
 
-    private InstrumentedAccessibilityServiceTestRule<VibratingAccessibilityService>
+    private final InstrumentedAccessibilityServiceTestRule<VibratingAccessibilityService>
             mVibratingAccessibilityServiceRule = new InstrumentedAccessibilityServiceTestRule<>(
-                    VibratingAccessibilityService.class);
+            VibratingAccessibilityService.class);
+
+    private final InstrumentedAccessibilityServiceTestRule<SpeakingAndVibratingAccessibilityService>
+            mSpeakingAndVibratingAccessibilityServiceRule =
+            new InstrumentedAccessibilityServiceTestRule<>(
+                    SpeakingAndVibratingAccessibilityService.class, /* enableService= */ false);
+
+    private final InstrumentedAccessibilityServiceTestRule<AccessibilityButtonService>
+            mA11yButtonServiceRule = new InstrumentedAccessibilityServiceTestRule<>(
+            AccessibilityButtonService.class, /* enableService= */ false);
 
     @Rule
     public final RuleChain mRuleChain = RuleChain
             .outerRule(mVibratingAccessibilityServiceRule)
             .around(mSpeakingAccessibilityServiceRule)
+            .around(mSpeakingAndVibratingAccessibilityServiceRule)
+            .around(mA11yButtonServiceRule)
             // Inner rule capture failure and dump data before finishing a11y service
             .around(new AccessibilityDumpOnFailureRule());
 
+    @Before
+    public void setUp() throws Exception {
+        mAccessibilityManager = getInstrumentation().getContext().getSystemService(
+                AccessibilityManager.class);
+        mPackageManager = getInstrumentation().getContext().getPackageManager();
+    }
+
     /**
      * Tests whether a service can that requested it can retrieve
      * window content.
@@ -73,13 +94,12 @@
     @SuppressWarnings("deprecation")
     @Test
     public void testAccessibilityServiceInfoForEnabledService() {
-        AccessibilityManager accessibilityManager = (AccessibilityManager)
-                getInstrumentation().getContext().getSystemService(Service.ACCESSIBILITY_SERVICE);
-        List<AccessibilityServiceInfo> enabledServices =
-            accessibilityManager.getEnabledAccessibilityServiceList(
-                    AccessibilityServiceInfo.FEEDBACK_SPOKEN);
-        assertSame("There should be one speaking service.", 1, enabledServices.size());
-        AccessibilityServiceInfo speakingService = enabledServices.get(0);
+        final List<AccessibilityServiceInfo> enabledServices =
+                mAccessibilityManager.getEnabledAccessibilityServiceList(
+                        AccessibilityServiceInfo.FEEDBACK_SPOKEN);
+        assertSame(/* message= */ "There should be one speaking service.",
+                /* expected= */ 1, enabledServices.size());
+        final AccessibilityServiceInfo speakingService = enabledServices.get(0);
         assertSame(AccessibilityEvent.TYPES_ALL_MASK, speakingService.eventTypes);
         assertSame(AccessibilityServiceInfo.FEEDBACK_SPOKEN, speakingService.feedbackType);
         assertEquals(AccessibilityServiceInfo.DEFAULT
@@ -89,8 +109,8 @@
                 | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS
                 | AccessibilityServiceInfo.FLAG_REQUEST_SHORTCUT_WARNING_DIALOG_SPOKEN_FEEDBACK,
                 speakingService.flags);
-        assertSame(0l, speakingService.notificationTimeout);
-        assertEquals("Some description", speakingService.getDescription());
+        assertSame(/* expected= */ 0l, speakingService.notificationTimeout);
+        assertEquals(/* expected= */ "Some description", speakingService.getDescription());
         assertNull(speakingService.packageNames /*all packages*/);
         assertNotNull(speakingService.getId());
         assertSame(speakingService.getCapabilities(),
@@ -98,15 +118,14 @@
                 | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
                 | AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT);
         assertEquals("foo.bar.Activity", speakingService.getSettingsActivityName());
-        assertNotNull(speakingService.loadAnimatedImage(getInstrumentation().getContext()));
-        assertEquals("Some description", speakingService.loadDescription(
-                getInstrumentation().getContext().getPackageManager()));
-        assertEquals("Some html description", speakingService.loadHtmlDescription(
-                getInstrumentation().getContext().getPackageManager()));
-        assertEquals("Some summary", speakingService.loadSummary(
-                getInstrumentation().getContext().getPackageManager()));
+        assertEquals(/* expected= */ "Some description",
+                speakingService.loadDescription(mPackageManager));
+        assertEquals(/* expected= */ "Some summary",
+                speakingService.loadSummary(mPackageManager));
         assertNotNull(speakingService.getResolveInfo());
-        assertEquals(6000, speakingService.getInteractiveUiTimeoutMillis());
-        assertEquals(1000, speakingService.getNonInteractiveUiTimeoutMillis());
+        assertEquals(/* expected= */ 6000,
+                speakingService.getInteractiveUiTimeoutMillis());
+        assertEquals(/* expected= */ 1000,
+                speakingService.getNonInteractiveUiTimeoutMillis());
     }
 }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedHierarchyTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedHierarchyTest.java
index 4111baf..8f79102 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedHierarchyTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedHierarchyTest.java
@@ -18,6 +18,7 @@
 
 import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchActivityAndWaitForItToBeOnscreen;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
@@ -69,6 +70,8 @@
     private final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
             new AccessibilityDumpOnFailureRule();
 
+    private AccessibilityEmbeddedHierarchyActivity mActivity;
+
     @Rule
     public final RuleChain mRuleChain = RuleChain
             .outerRule(mActivityRule)
@@ -90,8 +93,9 @@
 
     @Before
     public void setUp() throws Throwable {
-        launchActivityAndWaitForItToBeOnscreen(sInstrumentation, sUiAutomation, mActivityRule)
-                .waitForEmbeddedHierarchy();
+        mActivity = launchActivityAndWaitForItToBeOnscreen(sInstrumentation, sUiAutomation,
+                mActivityRule);
+        mActivity.waitForEmbeddedHierarchy();
     }
 
     @Test
@@ -114,6 +118,7 @@
         final AccessibilityNodeInfo target =
                 findEmbeddedAccessibilityNodeInfo(sUiAutomation.getRootInActiveWindow());
         final AccessibilityNodeInfo parent = target.getParent();
+
         final Rect hostViewBoundsInScreen = new Rect();
         final Rect embeddedViewBoundsInScreen = new Rect();
         parent.getBoundsInScreen(hostViewBoundsInScreen);
@@ -125,6 +130,36 @@
                 hostViewBoundsInScreen.contains(embeddedViewBoundsInScreen));
     }
 
+    @Test
+    public void testEmbeddedViewHasCorrectBoundAfterHostViewMove() {
+        final AccessibilityNodeInfo target =
+                findEmbeddedAccessibilityNodeInfo(sUiAutomation.getRootInActiveWindow());
+
+        final Rect hostViewBoundsInScreen = new Rect();
+        final Rect newEmbeddedViewBoundsInScreen = new Rect();
+        final Rect oldEmbeddedViewBoundsInScreen = new Rect();
+        target.getBoundsInScreen(oldEmbeddedViewBoundsInScreen);
+
+        // Move Host SurfaceView from (0, 0) to (100, 100).
+        mActivity.requestNewLayoutForTest();
+
+        final AccessibilityNodeInfo newTarget =
+                findEmbeddedAccessibilityNodeInfo(sUiAutomation.getRootInActiveWindow());
+        final AccessibilityNodeInfo parent = newTarget.getParent();
+
+        newTarget.getBoundsInScreen(newEmbeddedViewBoundsInScreen);
+        parent.getBoundsInScreen(hostViewBoundsInScreen);
+
+        assertTrue("hostViewBoundsInScreen" + hostViewBoundsInScreen.toShortString()
+                        + " doesn't contain newEmbeddedViewBoundsInScreen"
+                        + newEmbeddedViewBoundsInScreen.toShortString(),
+                hostViewBoundsInScreen.contains(newEmbeddedViewBoundsInScreen));
+        assertFalse("newEmbeddedViewBoundsInScreen" + newEmbeddedViewBoundsInScreen.toShortString()
+                        + " shouldn't be the same with oldEmbeddedViewBoundsInScreen"
+                        + oldEmbeddedViewBoundsInScreen.toShortString(),
+                newEmbeddedViewBoundsInScreen.equals(oldEmbeddedViewBoundsInScreen));
+    }
+
     private AccessibilityNodeInfo findEmbeddedAccessibilityNodeInfo(AccessibilityNodeInfo root) {
         final int childCount = root.getChildCount();
         for (int i = 0; i < childCount; i++) {
@@ -150,8 +185,11 @@
             AccessibilityTestActivity implements SurfaceHolder.Callback {
         private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
 
-        private static final int DEFAULT_WIDTH = 200;
-        private static final int DEFAULT_HEIGHT = 200;
+        private static final int DEFAULT_WIDTH = 150;
+        private static final int DEFAULT_HEIGHT = 150;
+
+        private static final int POSITION_X = 50;
+        private static final int POSITION_Y = 50;
 
         private SurfaceView mSurfaceView;
         private SurfaceControlViewHost mViewHost;
@@ -195,5 +233,13 @@
                 throw new AssertionError(e);
             }
         }
+
+        public void requestNewLayoutForTest() {
+            sInstrumentation.runOnMainSync(() -> {
+                mSurfaceView.setX(POSITION_X);
+                mSurfaceView.setY(POSITION_Y);
+                mSurfaceView.requestLayout();
+            });
+        }
     }
 }
diff --git a/tests/autofillservice/res/layout/login_activity.xml b/tests/autofillservice/res/layout/login_activity.xml
index ee21a00..e39e6ae 100644
--- a/tests/autofillservice/res/layout/login_activity.xml
+++ b/tests/autofillservice/res/layout/login_activity.xml
@@ -42,6 +42,7 @@
             android:maxLength="25"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:textCursorDrawable="@android:color/transparent"
             android:imeOptions="flagNoFullscreen" />
     </LinearLayout>
 
@@ -61,6 +62,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:inputType="textPassword"
+            android:textCursorDrawable="@android:color/transparent"
             android:imeOptions="flagNoFullscreen" />
     </LinearLayout>
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
index e496c24..e7c0cf7 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
@@ -48,13 +48,6 @@
     }
 
     /**
-     * Performs a click on username.
-     */
-    protected void requestClickOnUsername() throws TimeoutException {
-        mUiBot.waitForWindowChange(() -> mActivity.onUsername(View::performClick));
-    }
-
-    /**
      * Requests focus on username and expect no Window event happens.
      */
     protected void requestFocusOnUsernameNoWindowChange() {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java b/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java
index 92821a3..200e184 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AuthenticationTest.java
@@ -692,12 +692,12 @@
                 ? AuthenticationActivity.createSender(mContext, 1,
                         dataset)
                 : AuthenticationActivity.createSender(mContext, 1,
-                        dataset, newClientState("CSI", "FromIntent"));
+                        dataset, Helper.newClientState("CSI", "FromIntent"));
 
         // Configure the service behavior
         sReplier.addResponse(new CannedFillResponse.Builder()
                 .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_USERNAME, ID_PASSWORD)
-                .setExtras(newClientState("CSI", "FromResponse"))
+                .setExtras(Helper.newClientState("CSI", "FromResponse"))
                 .addDataset(new CannedDataset.Builder()
                         .setField(ID_USERNAME, UNUSED_AUTOFILL_VALUE)
                         .setField(ID_PASSWORD, UNUSED_AUTOFILL_VALUE)
@@ -728,13 +728,14 @@
         mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
 
         // Assert client state on authentication activity.
-        assertClientState("auth activity", AuthenticationActivity.getData(), "CSI", "FromResponse");
+        Helper.assertAuthenticationClientState("auth activity", AuthenticationActivity.getData(),
+                "CSI", "FromResponse");
 
         // Assert client state on save request.
         final SaveRequest saveRequest = sReplier.getNextSaveRequest();
         final String expectedValue = where == ClientStateLocation.FILL_RESPONSE_ONLY
                 ? "FromResponse" : "FromIntent";
-        assertClientState("on save", saveRequest.data, "CSI", expectedValue);
+        Helper.assertAuthenticationClientState("on save", saveRequest.data, "CSI", expectedValue);
     }
 
     @Test
@@ -1066,21 +1067,23 @@
                         .build());
 
         if (where == ClientStateLocation.FILL_RESPONSE_ONLY || where == ClientStateLocation.BOTH) {
-            authenticatedResponseBuilder.setExtras(newClientState("CSI", "FromAuthResponse"));
+            authenticatedResponseBuilder.setExtras(
+                    Helper.newClientState("CSI", "FromAuthResponse"));
         }
 
         final IntentSender authentication = where == ClientStateLocation.FILL_RESPONSE_ONLY
                 ? AuthenticationActivity.createSender(mContext, 1,
-                        authenticatedResponseBuilder.build())
+                authenticatedResponseBuilder.build())
                 : AuthenticationActivity.createSender(mContext, 1,
-                        authenticatedResponseBuilder.build(), newClientState("CSI", "FromIntent"));
+                        authenticatedResponseBuilder.build(),
+                        Helper.newClientState("CSI", "FromIntent"));
 
         // Configure the service behavior
         sReplier.addResponse(new CannedFillResponse.Builder()
                 .setAuthentication(authentication, ID_USERNAME)
                 .setIgnoreFields(ID_PASSWORD)
                 .setPresentation(createPresentation("Tap to auth response"))
-                .setExtras(newClientState("CSI", "FromResponse"))
+                .setExtras(Helper.newClientState("CSI", "FromResponse"))
                 .build());
 
         // Set expectation for the activity
@@ -1108,29 +1111,14 @@
         mUiBot.updateForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
 
         // Assert client state on authentication activity.
-        assertClientState("auth activity", AuthenticationActivity.getData(), "CSI", "FromResponse");
+        Helper.assertAuthenticationClientState("auth activity", AuthenticationActivity.getData(),
+                "CSI", "FromResponse");
 
         // Assert client state on save request.
         final SaveRequest saveRequest = sReplier.getNextSaveRequest();
         final String expectedValue = where == ClientStateLocation.FILL_RESPONSE_ONLY
                 ? "FromAuthResponse" : "FromIntent";
-        assertClientState("on save", saveRequest.data, "CSI", expectedValue);
-    }
-
-    // TODO(on master): move to helper / reuse in other places
-    private void assertClientState(String where, Bundle data, String expectedKey,
-            String expectedValue) {
-        assertWithMessage("no client state on %s", where).that(data).isNotNull();
-        final String extraValue = data.getString(expectedKey);
-        assertWithMessage("invalid value for %s on %s", expectedKey, where)
-            .that(extraValue).isEqualTo(expectedValue);
-    }
-
-    // TODO(on master): move to helper / reuse in other places
-    private Bundle newClientState(String key, String value) {
-        final Bundle clientState = new Bundle();
-        clientState.putString(key, value);
-        return clientState;
+        Helper.assertAuthenticationClientState("on save", saveRequest.data, "CSI", expectedValue);
     }
 
     @Test
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
index 74f9fd9..aa5c29d 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
@@ -1309,6 +1309,20 @@
         return false;
     }
 
+    public static Bundle newClientState(String key, String value) {
+        final Bundle clientState = new Bundle();
+        clientState.putString(key, value);
+        return clientState;
+    }
+
+    public static void assertAuthenticationClientState(String where, Bundle data,
+            String expectedKey, String expectedValue) {
+        assertWithMessage("no client state on %s", where).that(data).isNotNull();
+        final String extraValue = data.getString(expectedKey);
+        assertWithMessage("invalid value for %s on %s", expectedKey, where)
+                .that(extraValue).isEqualTo(expectedValue);
+    }
+
     /**
      * Asserts that 2 bitmaps have are the same. If they aren't throws an exception and dump them
      * locally so their can be visually inspected.
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAuthenticationTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAuthenticationTest.java
new file mode 100644
index 0000000..d27f6fc
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAuthenticationTest.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.autofillservice.cts.inline;
+
+import static android.app.Activity.RESULT_CANCELED;
+import static android.app.Activity.RESULT_OK;
+import static android.autofillservice.cts.Helper.ID_PASSWORD;
+import static android.autofillservice.cts.Helper.ID_USERNAME;
+import static android.autofillservice.cts.Helper.UNUSED_AUTOFILL_VALUE;
+import static android.autofillservice.cts.Helper.getContext;
+import static android.autofillservice.cts.LoginActivity.getWelcomeMessage;
+import static android.autofillservice.cts.Timeouts.MOCK_IME_TIMEOUT_MS;
+import static android.autofillservice.cts.inline.InstrumentedAutoFillServiceInlineEnabled.SERVICE_NAME;
+import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_PASSWORD;
+
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectBindInput;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.autofillservice.cts.AbstractLoginActivityTestCase;
+import android.autofillservice.cts.AuthenticationActivity;
+import android.autofillservice.cts.CannedFillResponse;
+import android.autofillservice.cts.CannedFillResponse.CannedDataset;
+import android.autofillservice.cts.Helper;
+import android.autofillservice.cts.InstrumentedAutoFillService.SaveRequest;
+import android.content.IntentSender;
+import android.os.Process;
+import android.platform.test.annotations.AppModeFull;
+
+import com.android.cts.mockime.ImeEventStream;
+import com.android.cts.mockime.MockImeSession;
+
+import org.junit.Test;
+
+import java.util.regex.Pattern;
+
+public class InlineAuthenticationTest extends AbstractLoginActivityTestCase {
+
+    private static final String TAG = "InlineAuthenticationTest";
+
+    // TODO: move common part to the other places
+    enum ClientStateLocation {
+        INTENT_ONLY,
+        FILL_RESPONSE_ONLY,
+        BOTH
+    }
+
+    @Override
+    protected void enableService() {
+        Helper.enableAutofillService(getContext(), SERVICE_NAME);
+    }
+
+    @Test
+    public void testDatasetAuthTwoFields() throws Exception {
+        datasetAuthTwoFields(/* cancelFirstAttempt */ false);
+    }
+
+    @Test
+    @AppModeFull(reason = "testDatasetAuthTwoFields() is enough")
+    public void testDatasetAuthTwoFieldsUserCancelsFirstAttempt() throws Exception {
+        datasetAuthTwoFields(/* cancelFirstAttempt */ true);
+    }
+
+    private void datasetAuthTwoFields(boolean cancelFirstAttempt) throws Exception {
+        // Set service.
+        enableService();
+
+        final MockImeSession mockImeSession = sMockImeSessionRule.getMockImeSession();
+        assumeTrue("MockIME not available", mockImeSession != null);
+
+        // Prepare the authenticated response
+        final IntentSender authentication = AuthenticationActivity.createSender(mContext, 1,
+                new CannedFillResponse.CannedDataset.Builder()
+                        .setField(ID_USERNAME, "dude")
+                        .setField(ID_PASSWORD, "sweet")
+                        .build());
+        final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
+                .addDataset(new CannedFillResponse.CannedDataset.Builder()
+                        .setField(ID_USERNAME, UNUSED_AUTOFILL_VALUE)
+                        .setField(ID_PASSWORD, UNUSED_AUTOFILL_VALUE)
+                        .setPresentation(createPresentation("auth"))
+                        .setInlinePresentation(createInlinePresentation("auth"))
+                        .setAuthentication(authentication)
+                        .build());
+        sReplier.addResponse(builder.build());
+        mActivity.expectAutoFill("dude", "sweet");
+
+        final ImeEventStream stream = mockImeSession.openEventStream();
+        mockImeSession.callRequestShowSelf(0);
+
+        // Wait until the MockIme gets bound to the TestActivity.
+        expectBindInput(stream, Process.myPid(), MOCK_IME_TIMEOUT_MS);
+
+        // Trigger auto-fill.
+        assertSuggestionShownBySelectViewId(ID_USERNAME, /* childrenCount */ 1);
+        sReplier.getNextFillRequest();
+
+        // Make sure UI is show on 2nd field as well
+        assertSuggestionShownBySelectViewId(ID_PASSWORD, /* childrenCount */ 1);
+
+        // Now tap on 1st field to show it again...
+        assertSuggestionShownBySelectViewId(ID_USERNAME, /* childrenCount */ 1);
+
+        // TODO(b/149891961): add logic for cancelFirstAttempt
+        if (cancelFirstAttempt) {
+            // Trigger the auth dialog, but emulate cancel.
+            AuthenticationActivity.setResultCode(RESULT_CANCELED);
+            mUiBot.selectSuggestion(0);
+            mUiBot.waitForIdle();
+            mUiBot.assertSuggestionStrip(1);
+
+            // Make sure it's still shown on other fields...
+            assertSuggestionShownBySelectViewId(ID_PASSWORD, /* childrenCount */ 1);
+
+            // Tap on 1st field to show it again...
+            assertSuggestionShownBySelectViewId(ID_USERNAME, /* childrenCount */ 1);
+        }
+
+        // ...and select it this time
+        AuthenticationActivity.setResultCode(RESULT_OK);
+        mUiBot.selectSuggestion(0);
+        mUiBot.waitForIdle();
+
+        // Check the results.
+        mActivity.assertAutoFilled();
+    }
+
+    @Test
+    public void testDatasetAuthFilteringUsingRegex() throws Exception {
+        // Set service.
+        enableService();
+
+        final MockImeSession mockImeSession = sMockImeSessionRule.getMockImeSession();
+        assumeTrue("MockIME not available", mockImeSession != null);
+
+        // Create the authentication intents
+        final CannedDataset unlockedDataset = new CannedDataset.Builder()
+                .setField(ID_USERNAME, "dude")
+                .setField(ID_PASSWORD, "sweet")
+                .build();
+        final IntentSender authentication = AuthenticationActivity.createSender(mContext, 1,
+                unlockedDataset);
+        final Pattern min2Chars = Pattern.compile(".{2,}");
+        sReplier.addResponse(new CannedFillResponse.Builder()
+                .addDataset(new CannedDataset.Builder()
+                        .setField(ID_USERNAME, UNUSED_AUTOFILL_VALUE, min2Chars)
+                        .setField(ID_PASSWORD, UNUSED_AUTOFILL_VALUE)
+                        .setPresentation(createPresentation("auth"))
+                        .setInlinePresentation(createInlinePresentation("auth"))
+                        .setAuthentication(authentication)
+                        .build())
+                .build());
+        // Set expectation for the activity
+        mActivity.expectAutoFill("dude", "sweet");
+
+        final ImeEventStream stream = mockImeSession.openEventStream();
+        mockImeSession.callRequestShowSelf(0);
+
+        // Wait until the MockIme gets bound to the TestActivity.
+        expectBindInput(stream, Process.myPid(), MOCK_IME_TIMEOUT_MS);
+
+        // Trigger auto-fill, make sure it's showing initially.
+        assertSuggestionShownBySelectViewId(ID_USERNAME, /* childrenCount */ 1);
+        sReplier.getNextFillRequest();
+
+        // ...then type something to hide it.
+        mActivity.onUsername((v) -> v.setText("a"));
+        // Suggestion strip was not shown.
+        mUiBot.assertNoSuggestionStripEver();
+        mUiBot.waitForIdle();
+
+        // ...now type something again to show it, as the input will have 2 chars.
+        mActivity.onUsername((v) -> v.setText("aa"));
+        mUiBot.waitForIdle();
+        mUiBot.assertSuggestionStrip(1);
+
+        // Delete the char and assert it's not shown again...
+        mActivity.onUsername((v) -> v.setText("a"));
+        mUiBot.waitForIdle();
+        mUiBot.assertNoSuggestionStripEver();
+
+        // ...then type something again to show it, as the input will have 2 chars.
+        mActivity.onUsername((v) -> v.setText("aa"));
+        mUiBot.waitForIdle();
+        mUiBot.assertSuggestionStrip(1);
+
+        // ...and select it this time
+        mUiBot.selectSuggestion(0);
+        mUiBot.waitForIdle();
+        mUiBot.assertNoSuggestionStripEver();
+
+        // Check the results.
+        mActivity.assertAutoFilled();
+    }
+
+    @Test
+    public void testDatasetAuthClientStateSetOnIntentOnly() throws Exception {
+        fillDatasetAuthWithClientState(ClientStateLocation.INTENT_ONLY);
+    }
+
+    @Test
+    @AppModeFull(reason = "testDatasetAuthClientStateSetOnIntentOnly() is enough")
+    public void testDatasetAuthClientStateSetOnFillResponseOnly() throws Exception {
+        fillDatasetAuthWithClientState(ClientStateLocation.FILL_RESPONSE_ONLY);
+    }
+
+    @Test
+    @AppModeFull(reason = "testDatasetAuthClientStateSetOnIntentOnly() is enough")
+    public void testDatasetAuthClientStateSetOnIntentAndFillResponse() throws Exception {
+        fillDatasetAuthWithClientState(ClientStateLocation.BOTH);
+    }
+
+    private void fillDatasetAuthWithClientState(ClientStateLocation where) throws Exception {
+        // Set service.
+        enableService();
+
+        final MockImeSession mockImeSession = sMockImeSessionRule.getMockImeSession();
+        assumeTrue("MockIME not available", mockImeSession != null);
+
+        // Prepare the authenticated response
+        final CannedDataset dataset = new CannedDataset.Builder()
+                .setField(ID_USERNAME, "dude")
+                .setField(ID_PASSWORD, "sweet")
+                .build();
+        final IntentSender authentication = where == ClientStateLocation.FILL_RESPONSE_ONLY
+                ? AuthenticationActivity.createSender(mContext, 1,
+                dataset)
+                : AuthenticationActivity.createSender(mContext, 1,
+                        dataset, Helper.newClientState("CSI", "FromIntent"));
+
+        // Configure the service behavior
+        sReplier.addResponse(new CannedFillResponse.Builder()
+                .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, ID_USERNAME, ID_PASSWORD)
+                .setExtras(Helper.newClientState("CSI", "FromResponse"))
+                .addDataset(new CannedDataset.Builder()
+                        .setField(ID_USERNAME, UNUSED_AUTOFILL_VALUE)
+                        .setField(ID_PASSWORD, UNUSED_AUTOFILL_VALUE)
+                        .setPresentation(createPresentation("auth"))
+                        .setInlinePresentation(createInlinePresentation("auth"))
+                        .setAuthentication(authentication)
+                        .build())
+                .build());
+
+        // Set expectation for the activity
+        mActivity.expectAutoFill("dude", "sweet");
+
+        final ImeEventStream stream = mockImeSession.openEventStream();
+        mockImeSession.callRequestShowSelf(0);
+
+        // Wait until the MockIme gets bound to the TestActivity.
+        expectBindInput(stream, Process.myPid(), MOCK_IME_TIMEOUT_MS);
+
+        // Trigger auto-fill, make sure it's showing initially.
+        assertSuggestionShownBySelectViewId(ID_USERNAME, /* childrenCount */ 1);
+        sReplier.getNextFillRequest();
+
+        // Tap authentication request.
+        mUiBot.selectSuggestion(0);
+        mUiBot.waitForIdle();
+
+        // Check the results.
+        mActivity.assertAutoFilled();
+        mUiBot.waitForIdle();
+
+        // Now trigger save.
+        mActivity.onUsername((v) -> v.setText("malkovich"));
+        mUiBot.waitForIdle();
+        mActivity.onPassword((v) -> v.setText("malkovich"));
+        mUiBot.waitForIdle();
+
+
+        final String expectedMessage = getWelcomeMessage("malkovich");
+        final String actualMessage = mActivity.tapLogin();
+        mUiBot.waitForIdle();
+        assertWithMessage("Wrong welcome msg").that(actualMessage).isEqualTo(expectedMessage);
+
+        mUiBot.updateForAutofill(/* yesDoIt */ true, SAVE_DATA_TYPE_PASSWORD);
+        mUiBot.waitForIdle();
+
+        // Assert client state on authentication activity.
+        Helper.assertAuthenticationClientState("auth activity", AuthenticationActivity.getData(),
+                "CSI", "FromResponse");
+
+        // Assert client state on save request.
+        final SaveRequest saveRequest = sReplier.getNextSaveRequest();
+        final String expectedValue = where == ClientStateLocation.FILL_RESPONSE_ONLY
+                ? "FromResponse" : "FromIntent";
+        Helper.assertAuthenticationClientState("on save", saveRequest.data, "CSI", expectedValue);
+    }
+
+    private void assertSuggestionShownBySelectViewId(String id, int childrenCount)
+            throws Exception {
+        mUiBot.selectByRelativeId(id);
+        mUiBot.waitForIdle();
+        mUiBot.assertSuggestionStrip(childrenCount);
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFillEventHistoryTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFillEventHistoryTest.java
new file mode 100644
index 0000000..941ebe2
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineFillEventHistoryTest.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.autofillservice.cts.inline;
+
+import static android.autofillservice.cts.CannedFillResponse.DO_NOT_REPLY_RESPONSE;
+import static android.autofillservice.cts.CannedFillResponse.NO_RESPONSE;
+import static android.autofillservice.cts.Helper.ID_PASSWORD;
+import static android.autofillservice.cts.Helper.ID_USERNAME;
+import static android.autofillservice.cts.Helper.NULL_DATASET_ID;
+import static android.autofillservice.cts.Helper.assertFillEventForDatasetAuthenticationSelected;
+import static android.autofillservice.cts.Helper.assertFillEventForDatasetSelected;
+import static android.autofillservice.cts.Helper.assertFillEventForDatasetShown;
+import static android.autofillservice.cts.Helper.assertFillEventForSaveShown;
+import static android.autofillservice.cts.Helper.assertNoDeprecatedClientState;
+import static android.autofillservice.cts.Helper.getContext;
+import static android.autofillservice.cts.InstrumentedAutoFillService.waitUntilConnected;
+import static android.autofillservice.cts.InstrumentedAutoFillService.waitUntilDisconnected;
+import static android.autofillservice.cts.inline.InstrumentedAutoFillServiceInlineEnabled.SERVICE_NAME;
+import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_GENERIC;
+
+import android.autofillservice.cts.AbstractLoginActivityTestCase;
+import android.autofillservice.cts.AuthenticationActivity;
+import android.autofillservice.cts.CannedFillResponse;
+import android.autofillservice.cts.CannedFillResponse.CannedDataset;
+import android.autofillservice.cts.Helper;
+import android.autofillservice.cts.InstrumentedAutoFillService;
+import android.autofillservice.cts.LoginActivity;
+import android.content.IntentSender;
+import android.os.Bundle;
+import android.platform.test.annotations.AppModeFull;
+import android.service.autofill.FillEventHistory;
+import android.service.autofill.FillEventHistory.Event;
+import android.support.test.uiautomator.UiObject2;
+import android.view.View;
+
+import org.junit.Test;
+
+import java.util.List;
+
+/**
+ * Test that uses {@link LoginActivity} to test {@link FillEventHistory}.
+ */
+@AppModeFull(reason = "Service-specific test")
+public class InlineFillEventHistoryTest extends AbstractLoginActivityTestCase {
+
+    @Override
+    protected void enableService() {
+        Helper.enableAutofillService(getContext(), SERVICE_NAME);
+    }
+
+    @Test
+    public void testNoDatasetAndSave() throws Exception {
+        enableService();
+
+        // Set expectations.
+        sReplier.addResponse(new CannedFillResponse.Builder()
+                .setRequiredSavableIds(SAVE_DATA_TYPE_GENERIC, ID_USERNAME)
+                .build());
+
+        // Trigger auto-fill and IME.
+        mUiBot.selectByRelativeId(ID_USERNAME);
+        mUiBot.waitForIdle();
+
+        sReplier.getNextFillRequest();
+
+        // Suggestion strip was never shown.
+        mUiBot.assertNoSuggestionStripEver();
+
+        // Change username
+        mActivity.syncRunOnUiThread(() ->  mActivity.onUsername((v) -> v.setText("ID")));
+        mUiBot.waitForIdle();
+
+        // Trigger save UI.
+        mActivity.tapSave();
+        mUiBot.waitForIdle();
+
+        // Confirm the save UI shown
+        final UiObject2 saveUi = mUiBot.assertSaveShowing(SAVE_DATA_TYPE_GENERIC);
+
+        // Save it...
+        mUiBot.saveForAutofill(saveUi, true);
+        mUiBot.waitForIdle();
+        sReplier.getNextSaveRequest();
+
+        // Verify save event
+        final FillEventHistory selection = InstrumentedAutoFillService.getFillEventHistory(1);
+        assertNoDeprecatedClientState(selection);
+        final List<Event> events = selection.getEvents();
+        assertFillEventForSaveShown(events.get(0), NULL_DATASET_ID);
+    }
+
+    @Test
+    public void testOneDatasetAndSave() throws Exception {
+        enableService();
+
+        // Set expectations.
+        sReplier.addResponse(new CannedFillResponse.Builder()
+                .setRequiredSavableIds(SAVE_DATA_TYPE_GENERIC, ID_USERNAME)
+                .addDataset(new CannedDataset.Builder()
+                        .setField(ID_USERNAME, "id")
+                        .setField(ID_PASSWORD, "pass")
+                        .setPresentation(createPresentation("Dataset"))
+                        .setInlinePresentation(createInlinePresentation("Dataset"))
+                        .build())
+                .build());
+
+        // Trigger auto-fill and IME.
+        mUiBot.selectByRelativeId(ID_USERNAME);
+        mUiBot.waitForIdle();
+        sReplier.getNextFillRequest();
+
+        // Suggestion strip was shown.
+        mUiBot.assertSuggestionStrip(1);
+        mUiBot.waitForIdle();
+
+        mUiBot.selectSuggestion(0);
+
+        // Change username and password
+        mActivity.syncRunOnUiThread(() ->  mActivity.onUsername((v) -> v.setText("ID")));
+        mActivity.syncRunOnUiThread(() ->  mActivity.onPassword((v) -> v.setText("PASS")));
+        mUiBot.waitForIdle();
+
+        // Trigger save UI.
+        mActivity.tapSave();
+        mUiBot.waitForIdle();
+
+        // Confirm the save UI shown
+        final UiObject2 saveUi = mUiBot.assertUpdateShowing(SAVE_DATA_TYPE_GENERIC);
+
+        // Save it...
+        mUiBot.saveForAutofill(saveUi, true);
+        mUiBot.waitForIdle();
+        sReplier.getNextSaveRequest();
+
+        // Verify events history
+        final FillEventHistory selection = InstrumentedAutoFillService.getFillEventHistory(4);
+        assertNoDeprecatedClientState(selection);
+        final List<Event> events = selection.getEvents();
+        assertFillEventForDatasetShown(events.get(0));
+        assertFillEventForDatasetSelected(events.get(1), NULL_DATASET_ID);
+        assertFillEventForDatasetShown(events.get(0));
+        assertFillEventForSaveShown(events.get(3), NULL_DATASET_ID);
+    }
+
+    @Test
+    public void testDatasetAuthenticationSelected() throws Exception {
+        enableService();
+
+        // Set up FillResponse with dataset authentication
+        Bundle clientState = new Bundle();
+        clientState.putCharSequence("clientStateKey", "clientStateValue");
+
+        // Prepare the authenticated response
+        final IntentSender authentication = AuthenticationActivity.createSender(mContext, 1,
+                new CannedDataset.Builder()
+                        .setField(ID_USERNAME, "dude")
+                        .setField(ID_PASSWORD, "sweet")
+                        .setPresentation(createPresentation("Dataset"))
+                        .setInlinePresentation(createInlinePresentation("Dataset"))
+                        .build());
+
+        sReplier.addResponse(new CannedFillResponse.Builder().addDataset(
+                new CannedDataset.Builder()
+                        .setField(ID_USERNAME, "username")
+                        .setId("name")
+                        .setPresentation(createPresentation("authentication"))
+                        .setInlinePresentation(createInlinePresentation("authentication"))
+                        .setAuthentication(authentication)
+                        .build())
+                .setExtras(clientState).build());
+        mActivity.expectAutoFill("dude", "sweet");
+
+        // Trigger auto-fill and IME.
+        mUiBot.selectByRelativeId(ID_USERNAME);
+        mUiBot.waitForIdle();
+
+        // ...
+        sReplier.getNextFillRequest();
+        mUiBot.assertSuggestionStrip(1);
+
+        // Authenticate
+        mUiBot.selectSuggestion(0);
+        mUiBot.waitForIdle();
+        mActivity.assertAutoFilled();
+
+        // Verify fill selection
+        final List<Event> events = InstrumentedAutoFillService.getFillEvents(2);
+        assertFillEventForDatasetShown(events.get(0), "clientStateKey", "clientStateValue");
+        assertFillEventForDatasetAuthenticationSelected(events.get(1), "name",
+                "clientStateKey", "clientStateValue");
+    }
+
+    @Test
+    public void testNoEvents_whenServiceReturnsNullResponse() throws Exception {
+        enableService();
+
+        // First reset
+        sReplier.addResponse(new CannedFillResponse.Builder().addDataset(
+                new CannedDataset.Builder()
+                        .setField(ID_USERNAME, "username")
+                        .setPresentation(createPresentation("dataset1"))
+                        .setInlinePresentation(createInlinePresentation("dataset1"))
+                        .build())
+                .build());
+        mActivity.expectAutoFill("username");
+
+        // Trigger auto-fill and IME.
+        mUiBot.selectByRelativeId(ID_USERNAME);
+        waitUntilConnected();
+        sReplier.getNextFillRequest();
+        mUiBot.selectSuggestion(0);
+        mUiBot.waitForIdle();
+        mActivity.assertAutoFilled();
+
+        {
+            // Verify fill selection
+            final FillEventHistory selection = InstrumentedAutoFillService.getFillEventHistory(2);
+            assertNoDeprecatedClientState(selection);
+            final List<Event> events = selection.getEvents();
+            assertFillEventForDatasetShown(events.get(0));
+            assertFillEventForDatasetSelected(events.get(1), NULL_DATASET_ID);
+        }
+
+        // Second request
+        sReplier.addResponse(NO_RESPONSE);
+        mActivity.onPassword(View::requestFocus);
+        sReplier.getNextFillRequest();
+        mUiBot.assertNoSuggestionStripEver();
+        waitUntilDisconnected();
+
+        InstrumentedAutoFillService.assertNoFillEventHistory();
+    }
+
+    @Test
+    public void testNoEvents_whenServiceReturnsFailure() throws Exception {
+        enableService();
+
+        // First reset
+        sReplier.addResponse(new CannedFillResponse.Builder().addDataset(
+                new CannedDataset.Builder()
+                        .setField(ID_USERNAME, "username")
+                        .setPresentation(createPresentation("dataset1"))
+                        .setInlinePresentation(createInlinePresentation("dataset1"))
+                        .build())
+                .build());
+        mActivity.expectAutoFill("username");
+
+        // Trigger auto-fill and IME.
+        mUiBot.selectByRelativeId(ID_USERNAME);
+        waitUntilConnected();
+        sReplier.getNextFillRequest();
+        mUiBot.selectSuggestion(0);
+        mUiBot.waitForIdle();
+        mActivity.assertAutoFilled();
+
+        {
+            // Verify fill selection
+            final FillEventHistory selection = InstrumentedAutoFillService.getFillEventHistory(2);
+            assertNoDeprecatedClientState(selection);
+            final List<Event> events = selection.getEvents();
+            assertFillEventForDatasetShown(events.get(0));
+            assertFillEventForDatasetSelected(events.get(1), NULL_DATASET_ID);
+        }
+
+        // Second request
+        sReplier.addResponse(new CannedFillResponse.Builder().returnFailure("D'OH!").build());
+        mActivity.onPassword(View::requestFocus);
+        sReplier.getNextFillRequest();
+        mUiBot.assertNoSuggestionStripEver();
+        waitUntilDisconnected();
+
+        InstrumentedAutoFillService.assertNoFillEventHistory();
+    }
+
+    @Test
+    public void testNoEvents_whenServiceTimesout() throws Exception {
+        enableService();
+
+        // First reset
+        sReplier.addResponse(new CannedFillResponse.Builder().addDataset(
+                new CannedDataset.Builder()
+                        .setField(ID_USERNAME, "username")
+                        .setPresentation(createPresentation("dataset1"))
+                        .setInlinePresentation(createInlinePresentation("dataset1"))
+                        .build())
+                .build());
+        mActivity.expectAutoFill("username");
+
+        // Trigger auto-fill and IME.
+        mUiBot.selectByRelativeId(ID_USERNAME);
+        waitUntilConnected();
+        sReplier.getNextFillRequest();
+        mUiBot.selectSuggestion(0);
+        mUiBot.waitForIdle();
+        mActivity.assertAutoFilled();
+
+        {
+            // Verify fill selection
+            final FillEventHistory selection = InstrumentedAutoFillService.getFillEventHistory(2);
+            assertNoDeprecatedClientState(selection);
+            final List<Event> events = selection.getEvents();
+            assertFillEventForDatasetShown(events.get(0));
+            assertFillEventForDatasetSelected(events.get(1), NULL_DATASET_ID);
+        }
+
+        // Second request
+        sReplier.addResponse(DO_NOT_REPLY_RESPONSE);
+        mActivity.onPassword(View::requestFocus);
+        sReplier.getNextFillRequest();
+        waitUntilDisconnected();
+
+        InstrumentedAutoFillService.assertNoFillEventHistory();
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
index 39139eb..f19087d 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
@@ -170,4 +170,90 @@
         assertWithMessage("Password node is focused").that(
                 findNodeByResourceId(request.structure, ID_PASSWORD).isFocused()).isFalse();
     }
+
+    @Test
+    public void testAutofill_disjointDatasets() throws Exception {
+        // Set service.
+        enableService();
+
+        final MockImeSession mockImeSession = sMockImeSessionRule.getMockImeSession();
+        assumeTrue("MockIME not available", mockImeSession != null);
+
+        final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
+                .addDataset(new CannedFillResponse.CannedDataset.Builder()
+                        .setField(ID_USERNAME, "dude")
+                        .setPresentation(createPresentation("The Username"))
+                        .setInlinePresentation(createInlinePresentation("The Username"))
+                        .build())
+                .addDataset(new CannedFillResponse.CannedDataset.Builder()
+                        .setField(ID_PASSWORD, "sweet")
+                        .setPresentation(createPresentation("The Password"))
+                        .setInlinePresentation(createInlinePresentation("The Password"))
+                        .build())
+                .addDataset(new CannedFillResponse.CannedDataset.Builder()
+                        .setField(ID_PASSWORD, "lollipop")
+                        .setPresentation(createPresentation("The Password2"))
+                        .setInlinePresentation(createInlinePresentation("The Password2"))
+                        .build());
+
+        sReplier.addResponse(builder.build());
+        mActivity.expectAutoFill("dude");
+
+        final ImeEventStream stream = mockImeSession.openEventStream();
+
+        // Wait until the MockIme gets bound to the TestActivity.
+        expectBindInput(stream, Process.myPid(), MOCK_IME_TIMEOUT_MS);
+
+        // Wait until IME is displaying.
+        mockImeSession.callRequestShowSelf(0);
+        expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()),
+                MOCK_IME_TIMEOUT_MS);
+        expectEvent(stream, event -> "onStartInputView".equals(event.getEventName()),
+                MOCK_IME_TIMEOUT_MS);
+
+        // Trigger auto-fill.
+        requestFocusOnUsername();
+        expectEvent(stream, editorMatcher("onStartInput", mActivity.getUsername().getId()),
+                MOCK_IME_TIMEOUT_MS);
+
+        // Wait until suggestion strip is updated
+        expectEvent(stream, event -> "onSuggestionViewUpdated".equals(event.getEventName()),
+                MOCK_IME_TIMEOUT_MS);
+
+        mUiBot.assertNoDatasetsEver();
+
+        mUiBot.assertSuggestionStrip(1);
+
+        // Switch focus to password
+        requestFocusOnPassword();
+        expectEvent(stream, event -> "onSuggestionViewUpdated".equals(event.getEventName()),
+                MOCK_IME_TIMEOUT_MS);
+
+        mUiBot.assertSuggestionStrip(2);
+
+        // Switch focus back to username
+        requestFocusOnUsername();
+        expectEvent(stream, event -> "onSuggestionViewUpdated".equals(event.getEventName()),
+                MOCK_IME_TIMEOUT_MS);
+
+        mUiBot.assertSuggestionStrip(1);
+        mUiBot.selectSuggestion(0);
+
+        // Check the results.
+        mActivity.assertAutoFilled();
+
+        // Make sure input was sanitized.
+        final InstrumentedAutoFillService.FillRequest request = sReplier.getNextFillRequest();
+        assertWithMessage("CancelationSignal is null").that(request.cancellationSignal).isNotNull();
+        assertTextIsSanitized(request.structure, ID_PASSWORD);
+        final FillContext fillContext = request.contexts.get(request.contexts.size() - 1);
+        assertThat(fillContext.getFocusedId())
+                .isEqualTo(findAutofillIdByResourceId(fillContext, ID_USERNAME));
+
+        // Make sure initial focus was properly set.
+        assertWithMessage("Username node is not focused").that(
+                findNodeByResourceId(request.structure, ID_USERNAME).isFocused()).isTrue();
+        assertWithMessage("Password node is focused").that(
+                findNodeByResourceId(request.structure, ID_PASSWORD).isFocused()).isFalse();
+    }
 }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineSimpleSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineSimpleSaveActivityTest.java
new file mode 100644
index 0000000..17bcc2f
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineSimpleSaveActivityTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.autofillservice.cts.inline;
+
+import static android.autofillservice.cts.Helper.assertTextAndValue;
+import static android.autofillservice.cts.Helper.findNodeByResourceId;
+import static android.autofillservice.cts.Helper.getContext;
+import static android.autofillservice.cts.SimpleSaveActivity.ID_COMMIT;
+import static android.autofillservice.cts.SimpleSaveActivity.ID_INPUT;
+import static android.autofillservice.cts.SimpleSaveActivity.ID_PASSWORD;
+import static android.autofillservice.cts.inline.InstrumentedAutoFillServiceInlineEnabled.SERVICE_NAME;
+import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_GENERIC;
+
+import android.autofillservice.cts.AutoFillServiceTestCase;
+import android.autofillservice.cts.AutofillActivityTestRule;
+import android.autofillservice.cts.CannedFillResponse;
+import android.autofillservice.cts.Helper;
+import android.autofillservice.cts.InstrumentedAutoFillService;
+import android.autofillservice.cts.SimpleSaveActivity;
+import android.support.test.uiautomator.UiObject2;
+
+import androidx.annotation.NonNull;
+
+import org.junit.Test;
+
+public class InlineSimpleSaveActivityTest
+        extends AutoFillServiceTestCase.AutoActivityLaunch<SimpleSaveActivity> {
+
+    private static final String TAG = "InlineSimpleSaveActivityTest";
+    protected SimpleSaveActivity mActivity;
+
+    @Override
+    protected void enableService() {
+        Helper.enableAutofillService(getContext(), SERVICE_NAME);
+    }
+
+    @NonNull
+    @Override
+    protected AutofillActivityTestRule<SimpleSaveActivity> getActivityRule() {
+        return new AutofillActivityTestRule<SimpleSaveActivity>(SimpleSaveActivity.class) {
+            @Override
+            protected void afterActivityLaunched() {
+                mActivity = getActivity();
+            }
+        };
+    }
+
+    @Test
+    public void testAutofillSave() throws Exception {
+        // Set service.
+        enableService();
+
+         // Set expectations.
+        sReplier.addResponse(new CannedFillResponse.Builder()
+                .setRequiredSavableIds(SAVE_DATA_TYPE_GENERIC, ID_INPUT)
+                .build());
+
+        // Trigger auto-fill and IME.
+        mUiBot.selectByRelativeId(ID_INPUT);
+        mUiBot.waitForIdle();
+
+        sReplier.getNextFillRequest();
+
+        // Suggestion strip was never shown.
+        mUiBot.assertNoSuggestionStripEver();
+
+        // Change input
+        mActivity.syncRunOnUiThread(() -> mActivity.getInput().setText("ID"));
+        mUiBot.waitForIdle();
+
+        // Trigger save UI.
+        mUiBot.selectByRelativeId(ID_COMMIT);
+        mUiBot.waitForIdle();
+
+        // Confirm the save UI shown
+        final UiObject2 saveUi = mUiBot.assertSaveShowing(SAVE_DATA_TYPE_GENERIC);
+
+        // Save it...
+        mUiBot.saveForAutofill(saveUi, true);
+
+        // ... and assert results
+        final InstrumentedAutoFillService.SaveRequest saveRequest = sReplier.getNextSaveRequest();
+        assertTextAndValue(findNodeByResourceId(saveRequest.structure, ID_INPUT), "ID");
+    }
+
+    @Test
+    public void testAutofill_oneDatasetAndSave() throws Exception {
+        // Set service.
+        enableService();
+
+        final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
+                .setRequiredSavableIds(SAVE_DATA_TYPE_GENERIC, ID_INPUT, ID_PASSWORD)
+                .addDataset(new CannedFillResponse.CannedDataset.Builder()
+                        .setField(ID_INPUT, "id")
+                        .setField(ID_PASSWORD, "pass")
+                        .setPresentation(createPresentation("YO"))
+                        .setInlinePresentation(createInlinePresentation("YO"))
+                        .build());
+        sReplier.addResponse(builder.build());
+        mActivity.expectAutoFill("id", "pass");
+
+        // Trigger auto-fill and IME.
+        mUiBot.selectByRelativeId(ID_INPUT);
+        mUiBot.waitForIdle();
+
+        sReplier.getNextFillRequest();
+
+        // Confirm one suggestion
+        mUiBot.assertSuggestionStrip(1);
+
+        // Select suggestion
+        mUiBot.selectSuggestion(0);
+        mUiBot.waitForIdle();
+
+        // Check the results.
+        mActivity.expectAutoFill("id", "pass");
+
+        // Change input
+        mActivity.syncRunOnUiThread(() -> mActivity.getInput().setText("ID"));
+        mUiBot.waitForIdle();
+
+        // Trigger save UI.
+        mUiBot.selectByRelativeId(ID_COMMIT);
+        mUiBot.waitForIdle();
+
+        // Confirm the save UI shown
+        final UiObject2 saveUi = mUiBot.assertUpdateShowing(SAVE_DATA_TYPE_GENERIC);
+
+        // Save it...
+        mUiBot.saveForAutofill(saveUi, true);
+
+        // ... and assert results
+        final InstrumentedAutoFillService.SaveRequest saveRequest = sReplier.getNextSaveRequest();
+        assertTextAndValue(findNodeByResourceId(saveRequest.structure, ID_INPUT), "ID");
+        assertTextAndValue(findNodeByResourceId(saveRequest.structure, ID_PASSWORD), "pass");
+    }
+}
diff --git a/tests/framework/base/windowmanager/app/AndroidManifest.xml b/tests/framework/base/windowmanager/app/AndroidManifest.xml
index f6113bf..507859b 100755
--- a/tests/framework/base/windowmanager/app/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/app/AndroidManifest.xml
@@ -477,6 +477,16 @@
             </meta-data>
         </service>
 
+        <service
+            android:name=".TestDream"
+            android:exported="true"
+            android:permission="android.permission.BIND_DREAM_SERVICE">
+            <intent-filter>
+                <action android:name="android.service.dreams.DreamService" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </service>
+
         <!-- Disable home activities by default or it may disturb other tests by
              showing ResolverActivity when start home activity -->
         <activity-alias android:name=".HomeActivity"
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
index 300398d..6751a1a 100644
--- a/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
@@ -204,6 +204,9 @@
     public static final ComponentName POPUP_MPP_ACTIVITY =
             component("PopupMinimalPostProcessingActivity");
 
+    public static final ComponentName TEST_DREAM_SERVICE =
+            component("TestDream");
+
     /**
      * Action and extra key constants for {@link #INPUT_METHOD_TEST_ACTIVITY}.
      */
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/TestDream.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/TestDream.java
new file mode 100644
index 0000000..3a6cca0
--- /dev/null
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/TestDream.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.server.wm.app;
+
+import android.service.dreams.DreamService;
+
+public class TestDream extends DreamService {
+}
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/single-instance_for-result.json b/tests/framework/base/windowmanager/intent_tests/forResult/single-instance_for-result.json
deleted file mode 100644
index 78fe375..0000000
--- a/tests/framework/base/windowmanager/intent_tests/forResult/single-instance_for-result.json
+++ /dev/null
@@ -1,66 +0,0 @@
-{
-    "setup": {
-        "initialIntents": [
-            {
-                "flags": "FLAG_ACTIVITY_NEW_TASK",
-                "class": "android.server.wm.intent.Activities$TaskAffinity1Activity",
-                "package": "android.server.wm.cts",
-                "startForResult": false
-            }
-        ],
-        "act": [
-            {
-                "flags": "",
-                "class": "android.server.wm.intent.Activities$SingleInstanceActivity",
-                "package": "android.server.wm.cts",
-                "startForResult": true
-            }
-        ]
-    },
-    "initialState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$TaskAffinity1Activity",
-                                "state": "STOPPED"
-                            }
-                        ]
-                    }
-                ]
-            }
-        ]
-    }
-}
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/single-top_for-result.json b/tests/framework/base/windowmanager/intent_tests/forResult/single-top_for-result.json
deleted file mode 100644
index a288a9e..0000000
--- a/tests/framework/base/windowmanager/intent_tests/forResult/single-top_for-result.json
+++ /dev/null
@@ -1,54 +0,0 @@
-{
-    "setup": {
-        "initialIntents": [
-            {
-                "flags": "FLAG_ACTIVITY_NEW_TASK",
-                "class": "android.server.wm.intent.Activities$SingleTopActivity",
-                "package": "android.server.wm.cts",
-                "startForResult": false
-            }
-        ],
-        "act": [
-            {
-                "flags": "",
-                "class": "android.server.wm.intent.Activities$SingleTopActivity",
-                "package": "android.server.wm.cts",
-                "startForResult": true
-            }
-        ]
-    },
-    "initialState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity"
-            }
-        ]
-    },
-    "endState": {
-        "stacks": [
-            {
-                "tasks": [
-                    {
-                        "activities": [
-                            {
-                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
-                                "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity"
-            }
-        ]
-    }
-}
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
index a80e56b..6e97377 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-2.json
@@ -43,6 +43,10 @@
                             {
                                 "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
                                 "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
+                                "state": "STOPPED"
                             }
                         ]
                     }
diff --git a/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json b/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
index a288a9e..2ed6023 100644
--- a/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
+++ b/tests/framework/base/windowmanager/intent_tests/forResult/test-4.json
@@ -43,6 +43,10 @@
                             {
                                 "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
                                 "state": "RESUMED"
+                            },
+                            {
+                                "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleTopActivity",
+                                "state": "STOPPED"
                             }
                         ]
                     }
diff --git a/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json b/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
index be49412..33419d6 100644
--- a/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
+++ b/tests/framework/base/windowmanager/intent_tests/newTask/test-15.json
@@ -43,23 +43,15 @@
                             {
                                 "name": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity",
                                 "state": "RESUMED"
-                            }
-                        ]
-                    }
-                ],
-                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
-            },
-            {
-                "tasks": [
-                    {
-                        "activities": [
+                            },
                             {
                                 "name": "android.server.wm.cts\/android.server.wm.intent.Activities$SingleInstanceActivity",
                                 "state": "STOPPED"
                             }
                         ]
                     }
-                ]
+                ],
+                "resumedActivity": "android.server.wm.cts\/android.server.wm.intent.Activities$RegularActivity"
             }
         ]
     }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java
index 915bb8d..49ef515 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DisplayCutoutTests.java
@@ -27,6 +27,7 @@
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
+import static org.hamcrest.Matchers.anyOf;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.everyItem;
 import static org.hamcrest.Matchers.greaterThan;
@@ -79,7 +80,10 @@
 @Presubmit
 @android.server.wm.annotation.Group3
 public class DisplayCutoutTests {
-    static final Rect ZERO_RECT = new Rect();
+    static final String LEFT = "left";
+    static final String TOP = "top";
+    static final String RIGHT = "right";
+    static final String BOTTOM = "bottom";
 
     @Rule
     public final ErrorCollector mErrorCollector = new ErrorCollector();
@@ -164,8 +168,12 @@
     public void testDisplayCutout_shortEdges_portrait() {
         runTest(LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES, (a, insets, displayCutout, which) -> {
             if (which == ROOT) {
-                assertThat("Display.getCutout() must equal view root cutout",
-                        a.getDisplay().getCutout(), equalTo(displayCutout));
+                assertThat("cutout is either null or the short edge insets must be equal to "
+                                + "those of the Display.getCutout() and the long edge "
+                                + "side insets must be 0",
+                        safeInsets(displayCutout),
+                        anyOf(is(nullValue()), onlyHasShortEdgeInsetsAndEqualsTo(
+                                safeInsets(a.getDisplay().getCutout()))));
             }
         });
     }
@@ -200,29 +208,26 @@
         final DisplayCutout displayCutout = insets.getDisplayCutout();
         final DisplayCutout dispatchedDisplayCutout = dispatchedInsets.getDisplayCutout();
         if (displayCutout != null) {
-            commonAsserts(activity, insets, displayCutout);
+            commonAsserts(activity, displayCutout);
             if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
                 shortEdgeAsserts(activity, insets, displayCutout);
             }
-            assertCutoutsAreConsistentWithInsets(displayCutout);
+            assertCutoutsAreConsistentWithInsets(activity, displayCutout);
         }
         test.run(activity, insets, displayCutout, ROOT);
 
         if (dispatchedDisplayCutout != null) {
-            commonAsserts(activity, dispatchedInsets, dispatchedDisplayCutout);
+            commonAsserts(activity, dispatchedDisplayCutout);
             if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
                 shortEdgeAsserts(activity, insets, displayCutout);
             }
-            assertCutoutsAreConsistentWithInsets(dispatchedDisplayCutout);
+            assertCutoutsAreConsistentWithInsets(activity, dispatchedDisplayCutout);
         }
         test.run(activity, dispatchedInsets, dispatchedDisplayCutout, DISPATCHED);
     }
 
-    private void commonAsserts(TestActivity activity, WindowInsets insets, DisplayCutout cutout) {
+    private void commonAsserts(TestActivity activity, DisplayCutout cutout) {
         assertSafeInsetsValid(cutout);
-        assertThat("systemWindowInsets (also known as content insets) must be at least as large as "
-                        + "cutout safe insets",
-                safeInsets(cutout), insetsLessThanOrEqualTo(systemWindowInsets(insets)));
         assertCutoutsAreWithinSafeInsets(activity, cutout);
         assertBoundsAreNonEmpty(cutout);
         assertAtMostOneCutoutPerEdge(activity, cutout);
@@ -231,26 +236,29 @@
     private void shortEdgeAsserts(
             TestActivity activity, WindowInsets insets, DisplayCutout cutout) {
         assertOnlyShortEdgeHasInsets(activity, cutout);
-        assertOnlyShortEdgeHasBounds(activity, insets, cutout);
+        assertOnlyShortEdgeHasBounds(activity, cutout);
+        assertThat("systemWindowInsets (also known as content insets) must be at least as "
+                        + "large as cutout safe insets",
+                safeInsets(cutout), insetsLessThanOrEqualTo(systemWindowInsets(insets)));
     }
 
-    private void assertCutoutIsConsistentWithInset(String position, int insetSize, Rect bound) {
-        if (insetSize > 0) {
-            assertThat("cutout must have a bound on the " + position, bound,
-                    not(equalTo(ZERO_RECT)));
+    private void assertCutoutIsConsistentWithInset(String position, DisplayCutout cutout,
+            int safeInsetSize, Rect appBound) {
+        if (safeInsetSize > 0) {
+            assertThat("cutout must have a bound on the " + position,
+                    hasBound(position, cutout, appBound), is(true));
         } else {
-            assertThat("cutout  must have no bound on the " + position, bound,
-                    equalTo(ZERO_RECT));
+            assertThat("cutout  must have no bound on the " + position,
+                    hasBound(position, cutout, appBound), is(false));
         }
     }
 
-    public void assertCutoutsAreConsistentWithInsets(DisplayCutout cutout) {
-        final Rect safeInsets = safeInsets(cutout);
-        assertCutoutIsConsistentWithInset("top", safeInsets.top, cutout.getBoundingRectTop());
-        assertCutoutIsConsistentWithInset("bottom", safeInsets.bottom,
-                cutout.getBoundingRectBottom());
-        assertCutoutIsConsistentWithInset("left", safeInsets.left, cutout.getBoundingRectLeft());
-        assertCutoutIsConsistentWithInset("right", safeInsets.right, cutout.getBoundingRectRight());
+    public void assertCutoutsAreConsistentWithInsets(TestActivity activity, DisplayCutout cutout) {
+        final Rect appBounds = getAppBounds(activity);
+        assertCutoutIsConsistentWithInset(TOP, cutout, cutout.getSafeInsetTop(), appBounds);
+        assertCutoutIsConsistentWithInset(BOTTOM, cutout, cutout.getSafeInsetBottom(), appBounds);
+        assertCutoutIsConsistentWithInset(LEFT, cutout, cutout.getSafeInsetLeft(), appBounds);
+        assertCutoutIsConsistentWithInset(RIGHT, cutout, cutout.getSafeInsetRight(), appBounds);
     }
 
     private void assertSafeInsetsValid(DisplayCutout displayCutout) {
@@ -312,32 +320,55 @@
         }
     }
 
-    private void assertOnlyShortEdgeHasBounds(TestActivity activity, WindowInsets insets,
-                                              DisplayCutout cutout) {
+    private void assertOnlyShortEdgeHasBounds(TestActivity activity, DisplayCutout cutout) {
         final Point displaySize = new Point();
         runOnMainSync(() -> activity.getDecorView().getDisplay().getRealSize(displaySize));
+        final Rect appBounds = getAppBounds(activity);
         if (displaySize.y > displaySize.x) {
             // Portrait display
             assertThat("left edge has a cutout despite being long edge",
-                    cutout.getBoundingRectLeft(), is(ZERO_RECT));
+                    hasBound(LEFT, cutout, appBounds), is(false));
+
             assertThat("right edge has a cutout despite being long edge",
-                    cutout.getBoundingRectRight(), is(ZERO_RECT));
+                    hasBound(RIGHT, cutout, appBounds), is(false));
         }
         if (displaySize.y < displaySize.x) {
             // Landscape display
             assertThat("top edge has a cutout despite being long edge",
-                    cutout.getBoundingRectTop(), is(ZERO_RECT));
+                    hasBound(TOP, cutout, appBounds), is(false));
+
             assertThat("bottom edge has a cutout despite being long edge",
-                    cutout.getBoundingRectBottom(), is(ZERO_RECT));
+                    hasBound(BOTTOM, cutout, appBounds), is(false));
         }
     }
 
+    private boolean hasBound(String position, DisplayCutout cutout, Rect appBound) {
+        final Rect cutoutRect;
+        final int waterfallSize;
+        if (LEFT.equals(position)) {
+            cutoutRect = cutout.getBoundingRectLeft();
+            waterfallSize = cutout.getWaterfallInsets().left;
+        } else if (TOP.equals(position)) {
+            cutoutRect = cutout.getBoundingRectTop();
+            waterfallSize = cutout.getWaterfallInsets().top;
+        } else if (RIGHT.equals(position)) {
+            cutoutRect = cutout.getBoundingRectRight();
+            waterfallSize = cutout.getWaterfallInsets().right;
+        } else {
+            cutoutRect = cutout.getBoundingRectBottom();
+            waterfallSize = cutout.getWaterfallInsets().bottom;
+        }
+        return Rect.intersects(cutoutRect, appBound) || waterfallSize > 0;
+    }
+
     private List<Rect> boundsWith(DisplayCutout cutout, Predicate<Rect> predicate) {
         return cutout.getBoundingRects().stream().filter(predicate).collect(Collectors.toList());
     }
 
-
     private static Rect safeInsets(DisplayCutout displayCutout) {
+        if (displayCutout == null) {
+            return null;
+        }
         return new Rect(displayCutout.getSafeInsetLeft(), displayCutout.getSafeInsetTop(),
                 displayCutout.getSafeInsetRight(), displayCutout.getSafeInsetBottom());
     }
@@ -359,6 +390,15 @@
         return safeRect;
     }
 
+    private Rect getAppBounds(TestActivity a) {
+        final Rect appBounds = new Rect();
+        runOnMainSync(() -> {
+            appBounds.right = a.getDecorView().getWidth();
+            appBounds.bottom = a.getDecorView().getHeight();
+        });
+        return appBounds;
+    }
+
     private static Matcher<Rect> insetsLessThanOrEqualTo(Rect max) {
         return new CustomTypeSafeMatcher<Rect>("must be smaller on each side than " + max) {
             @Override
@@ -369,6 +409,18 @@
         };
     }
 
+    private static Matcher<Rect> onlyHasShortEdgeInsetsAndEqualsTo(Rect expect) {
+        return new CustomTypeSafeMatcher<Rect>(
+                "must be 0 on long edge insets and equal on short edge insets to "
+                        + expect) {
+            @Override
+            protected boolean matchesSafely(Rect actual) {
+                return actual != null && actual.left == 0 && actual.top == expect.top
+                        && actual.right == 0 && actual.bottom == expect.bottom;
+            }
+        };
+    }
+
     private static Matcher<Rect> intersectsWith(Rect safeRect) {
         return new CustomTypeSafeMatcher<Rect>("intersects with " + safeRect) {
             @Override
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DreamManagerServiceTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DreamManagerServiceTests.java
new file mode 100644
index 0000000..78ef876
--- /dev/null
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DreamManagerServiceTests.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.server.wm;
+
+import static android.server.wm.app.Components.TEST_DREAM_SERVICE;
+
+import android.app.DreamManager;
+import android.content.ComponentName;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.FlakyTest;
+
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.Test;
+
+@Presubmit
+@FlakyTest(detail = "Promote once confirmed non-flaky")
+public class DreamManagerServiceTests extends ActivityManagerTestBase {
+
+    private static final ComponentName DREAM_ACTIVITY_COMPONENT_NAME =
+            new ComponentName(TEST_DREAM_SERVICE.getPackageName(),
+                              "android.service.dreams.DreamActivity");
+
+    private void startDream(ComponentName name) {
+        DreamManager dreamer = mContext.getSystemService(DreamManager.class);
+        SystemUtil.runWithShellPermissionIdentity(() -> {
+            dreamer.startDream(name);
+        });
+    }
+
+    private void stopDream() {
+        DreamManager dreamer = mContext.getSystemService(DreamManager.class);
+        SystemUtil.runWithShellPermissionIdentity(() -> {
+            dreamer.stopDream();
+        });
+    }
+
+    private void setActiveDream(ComponentName dream) {
+        DreamManager dreamer = mContext.getSystemService(DreamManager.class);
+        SystemUtil.runWithShellPermissionIdentity(() -> {
+            dreamer.setActiveDream(dream);
+        });
+    }
+
+    @Test
+    public void testStartAndStopDream() throws Exception {
+        setActiveDream(TEST_DREAM_SERVICE);
+
+        startDream(TEST_DREAM_SERVICE);
+        mWmState.waitForValidState(DREAM_ACTIVITY_COMPONENT_NAME);
+        mWmState.assertVisibility(DREAM_ACTIVITY_COMPONENT_NAME, true);
+        mWmState.assertHomeActivityVisible(false);
+
+        stopDream();
+        mWmState.waitAndAssertActivityRemoved(DREAM_ACTIVITY_COMPONENT_NAME);
+
+        mWmState.assertHomeActivityVisible(true);
+    }
+}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySystemDecorationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySystemDecorationTests.java
index c454c84..5121a39 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySystemDecorationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplaySystemDecorationTests.java
@@ -292,7 +292,6 @@
      * Tests launching a single instance home activity on virtual display with system decoration
      * support.
      */
-    @FlakyTest(bugId = 149070587)
     @Test
     public void testLaunchSingleHomeActivityOnDisplayWithDecorations() {
         createManagedHomeActivitySession(SINGLE_HOME_ACTIVITY);
@@ -316,7 +315,6 @@
      * Tests launching a single instance home activity with SECONDARY_HOME on virtual display with
      * system decoration support.
      */
-    @FlakyTest(bugId = 149070587)
     @Test
     public void testLaunchSingleSecondaryHomeActivityOnDisplayWithDecorations() {
         createManagedHomeActivitySession(SINGLE_SECONDARY_HOME_ACTIVITY);
@@ -340,7 +338,6 @@
      * Tests launching a multi-instance home activity on virtual display with system decoration
      * support.
      */
-    @FlakyTest(bugId = 149070587)
     @Test
     public void testLaunchHomeActivityOnDisplayWithDecorations() {
         createManagedHomeActivitySession(HOME_ACTIVITY);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
index 998f553..0b44b01 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
@@ -24,11 +24,11 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.pm.PackageManager.FEATURE_LEANBACK;
-import static android.server.wm.WindowManagerState.STATE_RESUMED;
-import static android.server.wm.WindowManagerState.STATE_STOPPED;
 import static android.server.wm.ComponentNameUtils.getActivityName;
 import static android.server.wm.ComponentNameUtils.getWindowName;
 import static android.server.wm.UiDeviceUtils.pressWindowButton;
+import static android.server.wm.WindowManagerState.STATE_RESUMED;
+import static android.server.wm.WindowManagerState.STATE_STOPPED;
 import static android.server.wm.app.Components.ALWAYS_FOCUSABLE_PIP_ACTIVITY;
 import static android.server.wm.app.Components.LAUNCHING_ACTIVITY;
 import static android.server.wm.app.Components.LAUNCH_ENTER_PIP_ACTIVITY;
@@ -88,10 +88,10 @@
 import android.os.Looper;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
-import android.server.wm.WindowManagerState.ActivityTask;
 import android.server.wm.CommandSession.ActivityCallback;
 import android.server.wm.CommandSession.SizeInfo;
 import android.server.wm.TestJournalProvider.TestJournalContainer;
+import android.server.wm.WindowManagerState.ActivityTask;
 import android.server.wm.settings.SettingsSession;
 import android.util.Log;
 import android.util.Size;
@@ -109,7 +109,6 @@
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
 
 /**
  * Build/Install/Run:
@@ -210,46 +209,6 @@
         mWmState.assertVisibility(PIP_ACTIVITY, true);
     }
 
-    private void waitForValidPinnedStackBounds(Function<WindowManagerState, Rect> boundsFunc) {
-        mWmState.waitForWithAmState(wmState -> {
-            final Rect bounds = boundsFunc.apply(wmState);
-            final Rect displayStableBounds = wmState.getStableBounds();
-            return bounds.width() > 0 && bounds.height() > 0
-                    && displayStableBounds.contains(bounds);
-        }, "valid pinned stack bounds");
-    }
-
-    @Test
-    public void testPinnedStackOutOfBoundsInsetsNonNegative() throws Exception {
-        final WindowManagerState wmState = mWmState;
-
-        // Launch an activity into the pinned stack
-        launchActivity(PIP_ACTIVITY, EXTRA_ENTER_PIP, "true",
-                EXTRA_TAP_TO_FINISH, "true");
-        // Wait for animation complete since we are comparing bounds
-        waitForEnterPipAnimationComplete(PIP_ACTIVITY);
-
-        // Get the display dimensions
-        WindowManagerState.WindowState windowState = getWindowState(PIP_ACTIVITY);
-        WindowManagerState.DisplayContent display =
-                wmState.getDisplay(windowState.getDisplayId());
-        Rect displayRect = display.getDisplayRect();
-
-        // Move the pinned stack offscreen
-        final int stackId = getPinnedStack().mRootTaskId;
-        final int top = 0;
-        final int left = displayRect.width() - 200;
-        resizePinnedStack(stackId, left, top, left + 500, top + 500);
-
-        // Ensure that the surface insets are not negative
-        windowState = getWindowState(PIP_ACTIVITY);
-        Rect contentInsets = windowState.getContentInsets();
-        if (contentInsets != null) {
-            assertTrue(contentInsets.left >= 0 && contentInsets.top >= 0
-                    && contentInsets.width() >= 0 && contentInsets.height() >= 0);
-        }
-    }
-
     @Test
     public void testPinnedStackInBoundsAfterRotation() {
         // Launch an activity into the pinned stack
@@ -299,6 +258,9 @@
     }
 
     private void testEnterPipAspectRatio(int num, int denom) throws Exception {
+        // Launch a test activity so that we're not over home
+        launchActivity(TEST_ACTIVITY);
+
         launchActivity(PIP_ACTIVITY,
                 EXTRA_ENTER_PIP, "true",
                 EXTRA_ENTER_PIP_ASPECT_RATIO_NUMERATOR, Integer.toString(num),
@@ -324,6 +286,9 @@
     }
 
     private void testResizePipAspectRatio(int num, int denom) throws Exception {
+        // Launch a test activity so that we're not over home
+        launchActivity(TEST_ACTIVITY);
+
         launchActivity(PIP_ACTIVITY,
                 EXTRA_ENTER_PIP, "true",
                 EXTRA_SET_ASPECT_RATIO_NUMERATOR, Integer.toString(num),
@@ -349,6 +314,9 @@
     }
 
     private void testEnterPipExtremeAspectRatio(int num, int denom) throws Exception {
+        // Launch a test activity so that we're not over home
+        launchActivity(TEST_ACTIVITY);
+
         // Assert that we could not create a pinned stack with an extreme aspect ratio
         launchActivity(PIP_ACTIVITY,
                 EXTRA_ENTER_PIP, "true",
@@ -370,6 +338,9 @@
     }
 
     private void testSetPipExtremeAspectRatio(int num, int denom) throws Exception {
+        // Launch a test activity so that we're not over home
+        launchActivity(TEST_ACTIVITY);
+
         // Try to resize the a normal pinned stack to an extreme aspect ratio and ensure that
         // fails (the aspect ratio remains the same)
         launchActivity(PIP_ACTIVITY,
@@ -882,6 +853,7 @@
         }
     }
 
+    @Ignore("b/149946388")
     @Test
     public void testEnterPipInterruptedCallbacks() {
         final TransitionAnimationScaleSession transitionAnimationScaleSession =
@@ -1018,18 +990,13 @@
         waitForEnterPip(PIP_ACTIVITY);
         assertPinnedStackExists();
         ActivityTask stack = mWmState.getStandardStackByWindowingMode(WINDOWING_MODE_PINNED);
-        int stackId = stack.mRootTaskId;
         int taskId = stack.getTopTask().mTaskId;
 
         // Launch task overlay activity into PiP activity task
         launchPinnedActivityAsTaskOverlay(TRANSLUCENT_TEST_ACTIVITY, taskId);
 
-        // Finish the task overlay activity while animating and ensure that the PiP activity never
-        // got resumed.
+        // Finish the task overlay activity and ensure that the PiP activity never got resumed.
         separateTestJournal();
-        SystemUtil.runWithShellPermissionIdentity(
-                () -> mAtm.resizePinnedStack(stackId, new Rect(20, 20, 500, 500),
-                        true /* animate */));
         mBroadcastActionTrigger.doAction(TEST_ACTIVITY_ACTION_FINISH_SELF);
         mWmState.waitFor((amState) ->
                         !amState.containsActivity(TRANSLUCENT_TEST_ACTIVITY),
@@ -1287,13 +1254,24 @@
 
     /**
      * Waits until the picture-in-picture animation has finished.
+     * TODO(b/149947030): use the transition completed signal from TaskOrganizer
      */
     private void waitForEnterPipAnimationComplete(ComponentName activityName) {
         waitForEnterPip(activityName);
-        mWmState.waitFor((amState) -> {
-                ActivityTask stack = amState.getStandardRootTaskByWindowingMode(WINDOWING_MODE_PINNED);
-                return stack != null && !stack.mAnimatingBounds;
-            }, "pinned stack bounds animation to finish");
+        final Rect pinnedStackBounds = new Rect();
+        mWmState.waitForWithAmState(wmState -> {
+            final Rect displayStableBounds = wmState.getStableBounds();
+            Rect newBounds = wmState.getStandardStackByWindowingMode(WINDOWING_MODE_PINNED)
+                    .getBounds();
+            if (pinnedStackBounds.equals(newBounds)
+                    && (displayStableBounds.width() / 2) > newBounds.width()
+                    && (displayStableBounds.height() / 2) > newBounds.height()) {
+                return true;
+            } else if (newBounds != null) {
+                pinnedStackBounds.set(newBounds);
+            }
+            return false;
+        }, "stack bounds stabilized, consider in pinned mode");
     }
 
     /**
@@ -1307,12 +1285,28 @@
 
     /**
      * Waits until the picture-in-picture animation to fullscreen has finished.
+     * TODO(b/149947030): use the transition completed signal from TaskOrganizer
      */
     private void waitForExitPipToFullscreen(ComponentName activityName) {
         mWmState.waitForValidState(new WaitForValidActivityState.Builder(activityName)
                 .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
                 .setActivityType(ACTIVITY_TYPE_STANDARD)
                 .build());
+        final Rect stackBounds = new Rect();
+        mWmState.waitForWithAmState(wmState -> {
+            final Rect displayStableBounds = wmState.getStableBounds();
+            final ActivityTask task = wmState.getTaskByActivity(activityName);
+            if (task == null) return false;
+            Rect newBounds = task.getBounds();
+            if (stackBounds.equals(newBounds)
+                    && (displayStableBounds.width() / 2) < newBounds.width()
+                    && (displayStableBounds.height() / 2) < newBounds.height()) {
+                return true;
+            } else if (newBounds != null) {
+                stackBounds.set(newBounds);
+            }
+            return false;
+        }, "stack bounds stabilized, consider in fullscreen mode");
     }
 
     /**
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
index f6646b4..c0bf81f 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
@@ -410,119 +410,6 @@
         }
     }
 
-    @Test
-    public void testMinimizedFromEachDockedSide() {
-        final RotationSession rotationSession = createManagedRotationSession();
-        for (int i = 0; i < 2; i++) {
-            rotationSession.set(i);
-            launchActivityInDockStackAndMinimize(TEST_ACTIVITY);
-            if (!mWmState.isScreenPortrait() && isTablet()) {
-                // Test minimize to the right only on tablets in landscape
-                removeStacksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME);
-                launchActivityInDockStackAndMinimize(TEST_ACTIVITY,
-                        SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT);
-            }
-            removeStacksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME);
-        }
-    }
-
-    @Test
-    public void testRotationWhileDockMinimized() {
-        launchActivityInDockStackAndMinimize(TEST_ACTIVITY);
-
-        // Rotate device single steps (90°) 0-1-2-3.
-        // Each time we compute the state we implicitly assert valid bounds in minimized mode.
-        final RotationSession rotationSession = createManagedRotationSession();
-        for (int i = 0; i < 4; i++) {
-            rotationSession.set(i);
-            mWmState.computeState(TEST_ACTIVITY);
-        }
-
-        // Double steps (180°) We ended the single step at 3. So, we jump directly to 1 for
-        // double step. So, we are testing 3-1-3 for one side and 0-2-0 for the other side in
-        // minimized mode.
-        rotationSession.set(ROTATION_90);
-        mWmState.computeState(TEST_ACTIVITY);
-        rotationSession.set(ROTATION_270);
-        mWmState.computeState(TEST_ACTIVITY);
-        rotationSession.set(ROTATION_0);
-        mWmState.computeState(TEST_ACTIVITY);
-        rotationSession.set(ROTATION_180);
-        mWmState.computeState(TEST_ACTIVITY);
-        rotationSession.set(ROTATION_0);
-        mWmState.computeState(TEST_ACTIVITY);
-    }
-
-    @Test
-    public void testMinimizeAndUnminimizeThenGoingHome() {
-        // Rotate the screen to check that minimize, unminimize, dismiss the docked stack and then
-        // going home has the correct app transition
-        final RotationSession rotationSession = createManagedRotationSession();
-        for (int rotation = ROTATION_0; rotation <= ROTATION_270; rotation++) {
-            launchActivityInDockStackAndMinimize(DOCKED_ACTIVITY);
-            // Set rotation after docked stack exists so the display can be rotated (home may
-            // be fixed-orientation if it is fullscreen).
-            rotationSession.set(rotation);
-
-            if (mIsHomeRecentsComponent) {
-                launchActivity(TEST_ACTIVITY, WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
-            } else {
-                // Unminimize the docked stack
-                pressAppSwitchButtonAndWaitForRecents();
-                waitForDockNotMinimized();
-                assertDockNotMinimized();
-            }
-
-            // Dismiss the dock stack
-            setActivityTaskWindowingMode(DOCKED_ACTIVITY,
-                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
-            mWmState.computeState(DOCKED_ACTIVITY);
-
-            // Go home and check the app transition
-            assertNotEquals(TRANSIT_WALLPAPER_OPEN,
-                    mWmState.getDefaultDisplayLastTransition());
-            launchHomeActivity();
-            mWmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY);
-
-            assertEquals(TRANSIT_WALLPAPER_OPEN,
-                    mWmState.getDefaultDisplayLastTransition());
-        }
-    }
-
-    @Test
-    public void testDockedStackToMinimizeWhenUnlocked() {
-        if (!mIsHomeRecentsComponent) {
-            launchActivityInDockStackAndMinimize(TEST_ACTIVITY);
-        } else {
-            launchActivityInSplitScreenWithRecents(TEST_ACTIVITY);
-        }
-        mWmState.computeState(TEST_ACTIVITY);
-        createManagedLockScreenSession().sleepDevice()
-                .wakeUpDevice()
-                .unlockDevice();
-        mWmState.computeState(TEST_ACTIVITY);
-        assertDockMinimized();
-    }
-
-    @Test
-    public void testMinimizedStateWhenUnlockedAndUnMinimized() {
-        launchActivityInDockStackAndMinimize(TEST_ACTIVITY);
-
-        createManagedLockScreenSession().sleepDevice()
-                .wakeUpDevice()
-                .unlockDevice();
-        mWmState.computeState(TEST_ACTIVITY);
-
-        // Unminimized back to splitscreen
-        if (mIsHomeRecentsComponent) {
-            launchActivity(RESIZEABLE_ACTIVITY,
-                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
-        } else {
-            pressAppSwitchButtonAndWaitForRecents();
-        }
-        mWmState.computeState(TEST_ACTIVITY);
-    }
-
     /**
      * Verify split screen mode visibility after stack resize occurs.
      */
@@ -651,42 +538,4 @@
         assertThat("Recents stack should be on top of home stack",
                 recentsStackIndex, lessThan(homeStackIndex));
     }
-
-    private void launchActivityInDockStackAndMinimize(ComponentName activityName) {
-        launchActivityInDockStackAndMinimize(activityName, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT);
-    }
-
-    private void launchActivityInDockStackAndMinimize(ComponentName activityName, int createMode) {
-        launchActivityInSplitScreenWithRecents(activityName, createMode);
-        launchHomeActivityNoWait();
-        waitForAndAssertDockMinimized(activityName);
-    }
-
-    private void assertDockMinimized() {
-        assertTrue(mWmState.isDockedStackMinimized());
-    }
-
-    private void waitForAndAssertDockMinimized(ComponentName activityName)  {
-        waitForDockMinimized();
-        assertDockMinimized();
-        mWmState.computeState(activityName);
-        mWmState.assertContainsStack("Must contain docked stack.",
-                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD);
-        mWmState.assertFocusedStack("Home activity should be focused in minimized mode",
-                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME);
-    }
-
-    private void assertDockNotMinimized() {
-        assertFalse(mWmState.isDockedStackMinimized());
-    }
-
-    private void waitForDockMinimized() {
-        mWmState.waitForWithAmState(state -> state.isDockedStackMinimized(),
-                "Dock stack to be minimized");
-    }
-
-    private void waitForDockNotMinimized() {
-        mWmState.waitForWithAmState(state -> !state.isDockedStackMinimized(),
-                "Dock stack to not be minimized");
-    }
 }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java b/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java
index e4cb869..9ba003c 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java
@@ -17,7 +17,6 @@
 package android.server.wm.intent;
 
 import android.app.Activity;
-import android.os.Bundle;
 
 /**
  * A collection of activities with various launch modes used in the intent tests.
@@ -28,68 +27,60 @@
  */
 public class Activities {
 
-    private static class BaseActivity extends Activity {
-        @Override
-        protected void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            setTitle(getClass().getSimpleName());
-        }
+    public static class TrackerActivity extends Activity {
     }
 
-    public static class TrackerActivity extends BaseActivity {
+    public static class RegularActivity extends Activity {
     }
 
-    public static class RegularActivity extends BaseActivity {
+    public static class SingleTopActivity extends Activity {
     }
 
-    public static class SingleTopActivity extends BaseActivity {
+    public static class SingleInstanceActivity extends Activity {
     }
 
-    public static class SingleInstanceActivity extends BaseActivity {
+    public static class SingleInstanceActivity2 extends Activity {
     }
 
-    public static class SingleInstanceActivity2 extends BaseActivity {
+    public static class SingleTaskActivity extends Activity {
     }
 
-    public static class SingleTaskActivity extends BaseActivity {
+    public static class SingleTaskActivity2 extends Activity {
     }
 
-    public static class SingleTaskActivity2 extends BaseActivity {
+    public static class TaskAffinity1Activity extends Activity {
     }
 
-    public static class TaskAffinity1Activity extends BaseActivity {
+    public static class TaskAffinity1Activity2 extends Activity {
     }
 
-    public static class TaskAffinity1Activity2 extends BaseActivity {
+    public static class TaskAffinity2Activity extends Activity {
     }
 
-    public static class TaskAffinity2Activity extends BaseActivity {
+    public static class TaskAffinity3Activity extends Activity {
     }
 
-    public static class TaskAffinity3Activity extends BaseActivity {
+    public static class ClearTaskOnLaunchActivity extends Activity {
     }
 
-    public static class ClearTaskOnLaunchActivity extends BaseActivity {
+    public static class DocumentLaunchIntoActivity extends Activity {
     }
 
-    public static class DocumentLaunchIntoActivity extends BaseActivity {
+    public static class DocumentLaunchAlwaysActivity extends Activity {
     }
 
-    public static class DocumentLaunchAlwaysActivity extends BaseActivity {
+    public static class DocumentLaunchNeverActivity extends Activity {
     }
 
-    public static class DocumentLaunchNeverActivity extends BaseActivity {
+    public static class NoHistoryActivity extends Activity {
     }
 
-    public static class NoHistoryActivity extends BaseActivity {
+    public static class LauncherActivity extends Activity {
     }
 
-    public static class LauncherActivity extends BaseActivity {
+    public static class RelinquishTaskIdentityActivity extends Activity {
     }
 
-    public static class RelinquishTaskIdentityActivity extends BaseActivity {
-    }
-
-    public static class TaskAffinity1RelinquishTaskIdentityActivity extends BaseActivity {
+    public static class TaskAffinity1RelinquishTaskIdentityActivity extends Activity {
     }
 }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java b/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
index 950047d..9e1d67a 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/intent/LaunchRunner.java
@@ -264,11 +264,6 @@
 
         if (activity == null) {
             return activityContext;
-        } else if (startForResult && activityContext == activity) {
-            // The result might have send back to caller activity and forced the caller activity
-            // to resumed again, before the started activity actually resumed. Just wait for idle
-            // for that case.
-            getInstrumentation().waitForIdleSync();
         } else {
             waitAndAssertActivityLaunched(activity, intent);
         }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java
index 93ecabc..8acde84 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java
@@ -352,7 +352,7 @@
         waitForActivityTransitions(ConfigChangeHandlingActivity.class,
                 Arrays.asList(ON_TOP_POSITION_LOST, ON_MULTI_WINDOW_MODE_CHANGED));
         LifecycleVerifier.assertOrder(getLifecycleLog(), ConfigChangeHandlingActivity.class,
-                Arrays.asList(ON_TOP_POSITION_LOST, ON_MULTI_WINDOW_MODE_CHANGED),
+                Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED, ON_TOP_POSITION_LOST),
                 "moveToSplitScreen");
 
         // Exit split-screen
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/LifecycleVerifier.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/LifecycleVerifier.java
index 2aecea9..f7b7e54 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/LifecycleVerifier.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/LifecycleVerifier.java
@@ -302,7 +302,7 @@
                 ? Arrays.asList(
                 ON_TOP_POSITION_LOST, ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE,
                 ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME, ON_TOP_POSITION_GAINED,
-                ON_TOP_POSITION_LOST, ON_PAUSE, ON_MULTI_WINDOW_MODE_CHANGED)
+                ON_MULTI_WINDOW_MODE_CHANGED, ON_TOP_POSITION_LOST, ON_PAUSE)
                 : Arrays.asList(
                         ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
                 ON_RESUME, ON_PAUSE);
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
index b7352fe..d49f11f 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
@@ -101,6 +101,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
 
 import static java.lang.Integer.toHexString;
 
@@ -529,9 +530,18 @@
     }
 
     protected ComponentName getDefaultSecondaryHomeComponent() {
+        assumeTrue(supportsMultiDisplay());
         int resId = Resources.getSystem().getIdentifier(
-                "config_secondaryHomeComponent", "string", "android");
-        return ComponentName.unflattenFromString(mContext.getResources().getString(resId));
+                "config_secondaryHomePackage", "string", "android");
+        final Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(Intent.CATEGORY_SECONDARY_HOME);
+        intent.setPackage(mContext.getResources().getString(resId));
+        final ResolveInfo resolveInfo =
+                mContext.getPackageManager().resolveActivity(intent, MATCH_DEFAULT_ONLY);
+        assertNotNull("Should have default secondary home activity", resolveInfo);
+
+        return new ComponentName(resolveInfo.activityInfo.packageName,
+                resolveInfo.activityInfo.name);
     }
 
     /**
@@ -750,15 +760,11 @@
      * {@code false}.
      */
     protected void launchActivityInSplitScreenWithRecents(ComponentName activityName) {
-        launchActivityInSplitScreenWithRecents(activityName, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT);
-    }
-
-    protected void launchActivityInSplitScreenWithRecents(ComponentName activityName,
-            int createMode) {
         SystemUtil.runWithShellPermissionIdentity(() -> {
             launchActivity(activityName);
             final int taskId = mWmState.getTaskByActivity(activityName).mTaskId;
-            mAtm.setTaskWindowingModeSplitScreenPrimary(taskId, createMode,
+            mAtm.setTaskWindowingModeSplitScreenPrimary(taskId,
+                    SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
                     true /* onTop */, false /* animate */,
                     null /* initialBounds */, true /* showRecents */);
 
@@ -902,12 +908,6 @@
                         new Rect(0, 0, taskWidth, taskHeight)));
     }
 
-    protected void resizePinnedStack(
-            int stackId, int stackLeft, int stackTop, int stackWidth, int stackHeight) {
-        SystemUtil.runWithShellPermissionIdentity(() -> mAtm.resizePinnedStack(stackId,
-                new Rect(stackLeft, stackTop, stackWidth, stackHeight), false /* animate */));
-    }
-
     protected void pressAppSwitchButtonAndWaitForRecents() {
         pressAppSwitchButton();
         mWmState.waitForRecentsActivityVisible();
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
index 61c3a380..d747155 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
@@ -135,7 +135,6 @@
     private String mTopResumedActivityRecord = null;
     final List<String> mResumedActivitiesInStacks = new ArrayList<>();
     final List<String> mResumedActivitiesInDisplays = new ArrayList<>();
-    private boolean mIsDockedStackMinimized;
     private Rect mDefaultPinnedStackBounds = new Rect();
     private Rect mPinnedStackMovementBounds = new Rect();
     private String mInputMethodWindowAppToken = null;
@@ -364,7 +363,6 @@
         mKeyguardControllerState = null;
         mIsHomeRecentsComponent = null;
         mPendingActivities.clear();
-        mIsDockedStackMinimized = false;
         mDefaultPinnedStackBounds.setEmpty();
         mPinnedStackMovementBounds.setEmpty();
         mInputMethodWindowAppToken = null;
@@ -876,10 +874,6 @@
         return mWindowStates.size() - mWindowStates.indexOf(w);
     }
 
-    public boolean isDockedStackMinimized() {
-        return mIsDockedStackMinimized;
-    }
-
     ActivityTask getStandardRootTaskByWindowingMode(int windowingMode) {
         for (ActivityTask task : mRootTasks) {
             if (task.getActivityType() != ACTIVITY_TYPE_STANDARD) {
@@ -985,9 +979,6 @@
             mAppTransitionState = appStateToString(appState);
             mLastTransition = appTransitionToString(lastTransition);
 
-            if (proto.dockedStackDividerController != null) {
-                amState.mIsDockedStackMinimized = proto.dockedStackDividerController.minimizedDock;
-            }
             PinnedStackControllerProto pinnedStackProto = proto.pinnedStackController;
             if (pinnedStackProto != null) {
                 amState.mDefaultPinnedStackBounds = extract(pinnedStackProto.defaultBounds);
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionInfoTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionInfoTest.java
index fc8e56c..b234bd4 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionInfoTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionInfoTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.testng.Assert.assertThrows;
+import static org.testng.Assert.assertTrue;
 
 import android.os.Parcel;
 import android.util.Size;
@@ -42,21 +43,32 @@
     public void testNullInlinePresentationSpecThrowsException() {
         assertThrows(NullPointerException.class,
                 () -> InlineSuggestionInfo.newInlineSuggestionInfo(/* presentationSpec */ null,
-                        InlineSuggestionInfo.SOURCE_AUTOFILL, new String[]{""}));
+                        InlineSuggestionInfo.SOURCE_AUTOFILL, new String[]{""},
+                        InlineSuggestionInfo.TYPE_SUGGESTION, /* isPinned */ false));
     }
 
     @Test
     public void testNullSourceThrowsException() {
         assertThrows(IllegalArgumentException.class,
                 () -> InlineSuggestionInfo.newInlineSuggestionInfo(
-                        mInlinePresentationSpec, /* source */null, new String[]{""}));
+                        mInlinePresentationSpec, /* source */null, new String[]{""},
+                        InlineSuggestionInfo.TYPE_SUGGESTION, /* isPinned */ false));
+    }
+
+    @Test
+    public void testNullTypeThrowsException() {
+        assertThrows(IllegalArgumentException.class,
+                () -> InlineSuggestionInfo.newInlineSuggestionInfo(
+                        mInlinePresentationSpec, InlineSuggestionInfo.SOURCE_AUTOFILL,
+                        new String[]{""}, /* type */ null, /* isPinned */ false));
     }
 
     @Test
     public void testInlineSuggestionInfoValues() {
         InlineSuggestionInfo info =
                 InlineSuggestionInfo.newInlineSuggestionInfo(mInlinePresentationSpec,
-                        InlineSuggestionInfo.SOURCE_AUTOFILL, new String[]{"password"});
+                        InlineSuggestionInfo.SOURCE_AUTOFILL, new String[]{"password"},
+                        InlineSuggestionInfo.TYPE_SUGGESTION, /* isPinned */ true);
 
         assertThat(info.getSource()).isEqualTo(InlineSuggestionInfo.SOURCE_AUTOFILL);
         assertThat(info.getPresentationSpec()).isNotNull();
@@ -64,12 +76,14 @@
         assertThat(info.getAutofillHints().length).isEqualTo(1);
         assertThat(info.getAutofillHints()[0]).isEqualTo("password");
         assertThat(info.getType()).isEqualTo(InlineSuggestionInfo.TYPE_SUGGESTION);
+        assertTrue(info.isPinned());
     }
 
     @Test
     public void testInlineSuggestionInfoParcelizeDeparcelize() {
         InlineSuggestionInfo info = InlineSuggestionInfo.newInlineSuggestionInfo(
-                mInlinePresentationSpec, InlineSuggestionInfo.SOURCE_AUTOFILL, new String[]{""});
+                mInlinePresentationSpec, InlineSuggestionInfo.SOURCE_AUTOFILL, new String[]{""},
+                InlineSuggestionInfo.TYPE_SUGGESTION, /* isPinned */ false);
         Parcel p = Parcel.obtain();
         info.writeToParcel(p, 0);
         p.setDataPosition(0);
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionTest.java
index a0cc196..90f9132 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionTest.java
@@ -114,7 +114,8 @@
 
     private InlineSuggestion createInlineSuggestion() {
         InlineSuggestionInfo info = InlineSuggestionInfo.newInlineSuggestionInfo(
-                mInlinePresentationSpec, InlineSuggestionInfo.SOURCE_AUTOFILL, new String[]{""});
+                mInlinePresentationSpec, InlineSuggestionInfo.SOURCE_AUTOFILL, new String[]{""},
+                InlineSuggestionInfo.TYPE_SUGGESTION, /* isPinned */ false);
         return InlineSuggestion.newInlineSuggestion(info);
     }
 }
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionsRequestTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionsRequestTest.java
index c5629fb..d8db007 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionsRequestTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/InlineSuggestionsRequestTest.java
@@ -32,6 +32,7 @@
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
+import android.os.LocaleList;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -60,16 +61,21 @@
     public void testInlineSuggestionsRequestValues() {
         final int suggestionCount = 3;
         ArrayList<InlinePresentationSpec> presentationSpecs = new ArrayList<>();
+        LocaleList localeList = LocaleList.forLanguageTags("fa-IR");
         InlineSuggestionsRequest request =
                 new InlineSuggestionsRequest.Builder(presentationSpecs)
                         .addPresentationSpecs(
                                 new InlinePresentationSpec.Builder(new Size(100, 100),
                                         new Size(400, 100)).build())
+                        .setSupportedLocales(LocaleList.forLanguageTags("fa-IR"))
+                        .setExtras(/* value */ null)
                         .setMaxSuggestionCount(suggestionCount).build();
 
         assertThat(request.getMaxSuggestionCount()).isEqualTo(suggestionCount);
         assertThat(request.getPresentationSpecs()).isNotNull();
         assertThat(request.getPresentationSpecs().size()).isEqualTo(1);
+        assertThat(request.getExtras()).isNull();
+        assertThat(request.getSupportedLocales()).isEqualTo(localeList);
     }
 
     @Test
diff --git a/tests/quickaccesswallet/AndroidManifest.xml b/tests/quickaccesswallet/AndroidManifest.xml
index 2765dd2..3d2ad69 100755
--- a/tests/quickaccesswallet/AndroidManifest.xml
+++ b/tests/quickaccesswallet/AndroidManifest.xml
@@ -20,8 +20,6 @@
           android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <!-- Required to update Secure Settings to set default payment app -->
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <!-- Required for HostApduService -->
     <uses-permission android:name="android.permission.NFC"/>
     <!-- Required to test QuickAccessWalletClient feature availability -->
diff --git a/tests/quickaccesswallet/src/android/quickaccesswallet/cts/QuickAccessWalletClientTest.java b/tests/quickaccesswallet/src/android/quickaccesswallet/cts/QuickAccessWalletClientTest.java
index 7130765..e7bf721 100755
--- a/tests/quickaccesswallet/src/android/quickaccesswallet/cts/QuickAccessWalletClientTest.java
+++ b/tests/quickaccesswallet/src/android/quickaccesswallet/cts/QuickAccessWalletClientTest.java
@@ -44,6 +44,8 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.platform.app.InstrumentationRegistry;
 
+import com.android.compatibility.common.util.SettingsUtils;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -66,22 +68,19 @@
     private static final GetWalletCardsRequest GET_WALLET_CARDS_REQUEST =
             new GetWalletCardsRequest(700, 440, 64, 5);
 
-    private static final int SETTING_DISABLED = 0;
-    private static final int SETTING_ENABLED = 1;
+    private static final String SETTING_DISABLED = "0";
+    private static final String SETTING_ENABLED = "1";
     private Context mContext;
     private String mDefaultPaymentApp;
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         // Save current default payment app
         mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
-        ContentResolver cr = mContext.getContentResolver();
-        mDefaultPaymentApp = Settings.Secure.getString(cr,
-                Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
-
+        mDefaultPaymentApp = SettingsUtils.get(Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
         ComponentName component =
                 ComponentName.createRelative(mContext, TestHostApduService.class.getName());
-        Settings.Secure.putString(cr, Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
+        SettingsUtils.syncSet(mContext, Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
                 component.flattenToString());
         TestQuickAccessWalletService.resetStaticFields();
     }
@@ -90,7 +89,7 @@
     public void tearDown() {
         // Restore saved default payment app
         ContentResolver cr = mContext.getContentResolver();
-        Settings.Secure.putString(cr, Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
+        SettingsUtils.syncSet(mContext, Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
                 mDefaultPaymentApp);
 
         // Return all services to default state
@@ -112,43 +111,44 @@
 
     @Test
     public void testIsWalletFeatureAvailableWhenDeviceLocked_checksSecureSettings() {
-        ContentResolver cr = mContext.getContentResolver();
         QuickAccessWalletClient client = QuickAccessWalletClient.create(mContext);
 
-        int showNotif = Settings.Secure.getInt(
-                cr, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, SETTING_DISABLED);
-        int allowPriv = Settings.Secure.getInt(
-                cr, Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, SETTING_DISABLED);
+
+        String showNotificationsSetting = SettingsUtils.getSecureSetting(
+                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
+        String allowPrivateNotificationsSetting = SettingsUtils.get(
+                Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
 
         try {
-            Settings.Secure.putInt(
-                    cr, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, SETTING_ENABLED);
-            Settings.Secure.putInt(
-                    cr, Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, SETTING_ENABLED);
+            SettingsUtils.syncSet(mContext, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                    SETTING_ENABLED);
+            SettingsUtils.syncSet(mContext, Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                    SETTING_ENABLED);
             assertThat(client.isWalletFeatureAvailableWhenDeviceLocked()).isTrue();
 
-            Settings.Secure.putInt(
-                    cr, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, SETTING_ENABLED);
-            Settings.Secure.putInt(
-                    cr, Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, SETTING_DISABLED);
+            SettingsUtils.syncSet(mContext, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                    SETTING_ENABLED);
+            SettingsUtils.syncSet(mContext, Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                    SETTING_DISABLED);
             assertThat(client.isWalletFeatureAvailableWhenDeviceLocked()).isFalse();
 
-            Settings.Secure.putInt(
-                    cr, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, SETTING_DISABLED);
-            Settings.Secure.putInt(
-                    cr, Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, SETTING_ENABLED);
+            SettingsUtils.syncSet(mContext, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                    SETTING_DISABLED);
+            SettingsUtils.syncSet(mContext, Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                    SETTING_ENABLED);
             assertThat(client.isWalletFeatureAvailableWhenDeviceLocked()).isFalse();
 
-            Settings.Secure.putInt(
-                    cr, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, SETTING_DISABLED);
-            Settings.Secure.putInt(
-                    cr, Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, SETTING_DISABLED);
+            SettingsUtils.syncSet(mContext, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                    SETTING_DISABLED);
+            SettingsUtils.syncSet(mContext, Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                    SETTING_DISABLED);
             assertThat(client.isWalletFeatureAvailableWhenDeviceLocked()).isFalse();
         } finally {
             // return settings to original values
-            Settings.Secure.putInt(cr, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, showNotif);
-            Settings.Secure.putInt(
-                    cr, Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, allowPriv);
+            SettingsUtils.syncSet(mContext, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                    showNotificationsSetting);
+            SettingsUtils.syncSet(mContext, Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                    allowPrivateNotificationsSetting);
         }
     }
 
diff --git a/tests/signature/TEST_MAPPING b/tests/signature/TEST_MAPPING
index c1c9d61..810f3f7 100644
--- a/tests/signature/TEST_MAPPING
+++ b/tests/signature/TEST_MAPPING
@@ -37,6 +37,9 @@
         "name": "CtsHiddenApiKillswitchWildcardTestCases"
     },
     {
+        "name": "CtsSystemApiAnnotationTestCases"
+    },
+    {
         "name": "CtsSystemApiSignatureTestCases"
     },
     {
diff --git a/tests/signature/lib/common/src/android/signature/cts/ReflectionHelper.java b/tests/signature/lib/common/src/android/signature/cts/ReflectionHelper.java
index 9c3741e..3bed2ac 100644
--- a/tests/signature/lib/common/src/android/signature/cts/ReflectionHelper.java
+++ b/tests/signature/lib/common/src/android/signature/cts/ReflectionHelper.java
@@ -34,6 +34,8 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Uses reflection to obtain runtime representations of elements in the API.
@@ -421,11 +423,25 @@
         }
     }
 
+    private final static Pattern REPEATING_ANNOTATION_PATTERN =
+            Pattern.compile("@.*\\(value=\\[(.*)\\]\\)");
+
     public static boolean hasMatchingAnnotation(AnnotatedElement elem, String annotationSpec) {
         for (Annotation a : elem.getAnnotations()) {
             if (a.toString().equals(annotationSpec)) {
                 return true;
             }
+            // It could be a repeating annotation. In that case, a.toString() returns
+            // "@MyAnnotation$Container(value=[@MyAnnotation(A), @MyAnnotation(B)])"
+            // Then, iterate over @MyAnnotation(A) and @MyAnnotation(B).
+            Matcher m = REPEATING_ANNOTATION_PATTERN.matcher(a.toString());
+            if (m.matches()) {
+                for (String token : m.group(1).split(", ")) {
+                    if (token.equals(annotationSpec)) {
+                        return true;
+                    }
+                }
+            }
         }
         return false;
     }
diff --git a/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverTest.java b/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverTest.java
index ab44335..afae17e 100644
--- a/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverTest.java
+++ b/tests/tests/batterysaving/src/android/os/cts/batterysaving/BatterySaverTest.java
@@ -22,12 +22,15 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import android.app.UiModeManager;
+import android.content.res.Configuration;
 import android.os.PowerManager;
 
 import androidx.test.filters.MediumTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.compatibility.common.util.BatteryUtils;
+import com.android.compatibility.common.util.SettingsUtils;
 import com.android.compatibility.common.util.SystemUtil;
 
 import org.junit.Test;
@@ -91,4 +94,57 @@
             assertFalse(manager.isPowerSaveMode());
         });
     }
+
+    /** Tests that Battery Saver exemptions activate when car mode is active. */
+    @Test
+    public void testCarModeExceptions() throws Exception {
+        UiModeManager uiModeManager = getContext().getSystemService(UiModeManager.class);
+        uiModeManager.disableCarMode(0);
+
+        final PowerManager powerManager = BatteryUtils.getPowerManager();
+
+        try {
+            runDumpsysBatteryUnplug();
+
+            SettingsUtils.set(SettingsUtils.NAMESPACE_GLOBAL, "battery_saver_constants",
+                    "gps_mode=" + PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF
+                    + ",enable_night_mode=true");
+
+            enableBatterySaver(true);
+
+            // Allow time for UI change.
+            Thread.sleep(1000);
+            assertTrue(powerManager.isPowerSaveMode());
+            assertEquals(PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF,
+                    powerManager.getLocationPowerSaveMode());
+            assertEquals(Configuration.UI_MODE_NIGHT_YES,
+                    getContext().getResources().getConfiguration().uiMode
+                        & Configuration.UI_MODE_NIGHT_MASK);
+
+            uiModeManager.enableCarMode(0);
+            // Allow time for UI change.
+            Thread.sleep(1000);
+
+            final int locationPowerSaveMode = powerManager.getLocationPowerSaveMode();
+            assertTrue("Location power save mode didn't change from " + locationPowerSaveMode,
+                    locationPowerSaveMode == PowerManager.LOCATION_MODE_FOREGROUND_ONLY
+                            || locationPowerSaveMode == PowerManager.LOCATION_MODE_NO_CHANGE);
+            assertEquals(Configuration.UI_MODE_NIGHT_NO,
+                getContext().getResources().getConfiguration().uiMode
+                    & Configuration.UI_MODE_NIGHT_MASK);
+
+            uiModeManager.disableCarMode(0);
+            // Allow time for UI change.
+            Thread.sleep(1000);
+
+            assertEquals(PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF,
+                powerManager.getLocationPowerSaveMode());
+            assertEquals(Configuration.UI_MODE_NIGHT_YES,
+                getContext().getResources().getConfiguration().uiMode
+                    & Configuration.UI_MODE_NIGHT_MASK);
+        } finally {
+            uiModeManager.disableCarMode(0);
+            SettingsUtils.delete(SettingsUtils.NAMESPACE_GLOBAL, "battery_saver_constants");
+        }
+    }
 }
diff --git a/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java b/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java
index 583ff7c..1a27bf0 100644
--- a/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java
@@ -26,7 +26,9 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
@@ -215,4 +217,62 @@
                 PARTIALLY_DIRECT_BOOT_AWARE_PACKAGE_NAME, 0);
         assertTrue(applicationInfo.isEncryptionAware());
     }
+
+    @Test
+    public void testWriteToParcelDontSquash() throws Exception {
+        // Make sure ApplicationInfo.writeToParcel() doesn't do the "squashing",
+        // because Parcel.allowSquashing() isn't called.
+
+        mApplicationInfo = getContext().getPackageManager().getApplicationInfo(mPackageName, 0);
+
+        final Parcel p = Parcel.obtain();
+        mApplicationInfo.writeToParcel(p, 0);
+        mApplicationInfo.writeToParcel(p, 0);
+
+        // Don't call Parcel.allowSquashing()
+
+        p.setDataPosition(0);
+        final ApplicationInfo copy1 = ApplicationInfo.CREATOR.createFromParcel(p);
+        final ApplicationInfo copy2 = ApplicationInfo.CREATOR.createFromParcel(p);
+
+        p.recycle();
+
+        assertNotSame(mApplicationInfo, copy1);
+
+        // writeToParcel() doesn't do the squashing, so copy1 and copy2 will be different.
+        assertNotSame(copy1, copy2);
+
+        // Check several fields to make sure they're properly copied.
+        assertEquals(mApplicationInfo.packageName, copy2.packageName);
+        assertEquals(copy1.packageName, copy2.packageName);
+
+        assertEquals(mApplicationInfo.flags, copy2.flags);
+        assertEquals(copy1.flags, copy2.flags);
+    }
+
+    @Test
+    public void testWriteToParcelSquash() throws Exception {
+        // Make sure ApplicationInfo.writeToParcel() does the "squashing", after
+        // Parcel.allowSquashing() is called.
+
+        mApplicationInfo = getContext().getPackageManager().getApplicationInfo(mPackageName, 0);
+
+        final Parcel p = Parcel.obtain();
+
+        final boolean prevSquashing = p.allowSquashing(); // Allow squashing.
+
+        mApplicationInfo.writeToParcel(p, 0);
+        mApplicationInfo.writeToParcel(p, 0);
+
+        p.setDataPosition(0);
+        final ApplicationInfo copy1 = ApplicationInfo.CREATOR.createFromParcel(p);
+        final ApplicationInfo copy2 = ApplicationInfo.CREATOR.createFromParcel(p);
+
+        p.recycle();
+
+        assertNotSame(mApplicationInfo, copy1);
+        assertSame(copy1, copy2); //
+
+        p.restoreAllowSquashing(prevSquashing);
+    }
 }
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageInfoTest.java b/tests/tests/content/src/android/content/pm/cts/PackageInfoTest.java
index b2aae0d..8cfab20 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageInfoTest.java
@@ -18,6 +18,7 @@
 
 
 import android.content.pm.ApplicationInfo;
+import android.content.pm.ComponentInfo;
 import android.content.pm.ConfigurationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageItemInfo;
@@ -63,6 +64,19 @@
         p.recycle();
     }
 
+    public void testApplicationInfoSame() {
+        ApplicationInfo ai = mPackageInfo.applicationInfo;
+
+        // Make sure all the components in it has the same ApplicationInfo.
+        for (ComponentInfo[] ar : new ComponentInfo[][]{
+                mPackageInfo.activities, mPackageInfo.services, mPackageInfo.providers,
+                mPackageInfo.receivers}) {
+            for (ComponentInfo ci : ar) {
+                assertSame("component=" + ci.getComponentName(), ai, ci.applicationInfo);
+            }
+        }
+    }
+
     private void checkPkgInfoSame(PackageInfo expected, PackageInfo actual) {
         assertEquals(expected.packageName, actual.packageName);
         assertEquals(expected.getLongVersionCode(), actual.getLongVersionCode());
diff --git a/tests/tests/content/src/android/content/pm/cts/ProviderInfoListTest.java b/tests/tests/content/src/android/content/pm/cts/ProviderInfoListTest.java
new file mode 100644
index 0000000..2578058
--- /dev/null
+++ b/tests/tests/content/src/android/content/pm/cts/ProviderInfoListTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm.cts;
+
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ProviderInfoList;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class ProviderInfoListTest extends AndroidTestCase {
+    private static final String PACKAGE_NAME = "android.content.cts";
+
+    public void testApplicationInfoSquashed() throws Exception {
+        final PackageManager pm = getContext().getPackageManager();
+        final PackageInfo pi = pm.getPackageInfo(PACKAGE_NAME,
+                PackageManager.GET_PROVIDERS | PackageManager.GET_UNINSTALLED_PACKAGES);
+
+        // Make sure the package contains more than 1 providers.
+        assertNotNull(pi);
+        assertNotNull(pi.providers);
+        assertTrue(pi.providers.length > 1);
+
+        final List<ProviderInfo> providers = new ArrayList<>();
+        Collections.addAll(providers, pi.providers);
+
+        // Create a target list.
+        final ProviderInfoList source = ProviderInfoList.fromList(providers);
+
+        // Parcel it and uparcel
+        final Parcel p = Parcel.obtain();
+        source.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        final ProviderInfoList dest = ProviderInfoList.CREATOR.createFromParcel(p);
+        p.recycle();
+
+        final List<ProviderInfo> destList = dest.getList();
+        assertEquals(source.getList().size(), destList.size());
+        for (int i = 0; i < destList.size(); i++) {
+            assertEquals(destList.get(0).applicationInfo, destList.get(i).applicationInfo);
+        }
+    }
+}
diff --git a/tests/tests/net/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/tests/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
index 44a9cc2..d5361d7 100644
--- a/tests/tests/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
+++ b/tests/tests/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
@@ -163,7 +163,7 @@
 
         // Analyze results
         assertTrue("Wi-Fi RTT failure rate exceeds threshold: FAIL=" + numFailures + ", ITERATIONS="
-                        + NUM_OF_RTT_ITERATIONS,
+                        + NUM_OF_RTT_ITERATIONS + ", AP RSSI=" + testAp.level,
                 numFailures <= NUM_OF_RTT_ITERATIONS * MAX_FAILURE_RATE_PERCENT / 100);
         if (numFailures != NUM_OF_RTT_ITERATIONS) {
             double distanceAvg = distanceSum / (NUM_OF_RTT_ITERATIONS - numFailures);
diff --git a/tests/tests/provider/OWNERS b/tests/tests/provider/OWNERS
index fea932d..ed13f6fa 100644
--- a/tests/tests/provider/OWNERS
+++ b/tests/tests/provider/OWNERS
@@ -5,3 +5,5 @@
 tgunn@google.com
 nicksauer@google.com
 nona@google.com
+nandana@google.com
+zezeozue@google.com
diff --git a/tests/tests/secure_element/access_control/AccessControlApp1/src/android/omapi/accesscontrol1/cts/AccessControlTest.java b/tests/tests/secure_element/access_control/AccessControlApp1/src/android/omapi/accesscontrol1/cts/AccessControlTest.java
index ad85ac2..da2145c 100755
--- a/tests/tests/secure_element/access_control/AccessControlApp1/src/android/omapi/accesscontrol1/cts/AccessControlTest.java
+++ b/tests/tests/secure_element/access_control/AccessControlApp1/src/android/omapi/accesscontrol1/cts/AccessControlTest.java
@@ -159,7 +159,17 @@
     private boolean supportsHardware() {
         final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
         boolean lowRamDevice = PropertyUtil.propertyEquals("ro.config.low_ram", "true");
-        return !lowRamDevice || (lowRamDevice && pm.hasSystemFeature("android.hardware.type.watch"));
+        return !lowRamDevice || pm.hasSystemFeature("android.hardware.type.watch")
+                || hasSecureElementPackage(pm);
+    }
+
+    private boolean hasSecureElementPackage(PackageManager pm) {
+        try {
+            pm.getPackageInfo("com.android.se", 0 /* flags*/);
+            return true;
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
     }
 
     private boolean supportOMAPIReaders() {
diff --git a/tests/tests/secure_element/access_control/AccessControlApp2/src/android/omapi/accesscontrol2/cts/AccessControlTest.java b/tests/tests/secure_element/access_control/AccessControlApp2/src/android/omapi/accesscontrol2/cts/AccessControlTest.java
index 8bce22b..0080446 100755
--- a/tests/tests/secure_element/access_control/AccessControlApp2/src/android/omapi/accesscontrol2/cts/AccessControlTest.java
+++ b/tests/tests/secure_element/access_control/AccessControlApp2/src/android/omapi/accesscontrol2/cts/AccessControlTest.java
@@ -158,7 +158,17 @@
     private boolean supportsHardware() {
         final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
         boolean lowRamDevice = PropertyUtil.propertyEquals("ro.config.low_ram", "true");
-        return !lowRamDevice || (lowRamDevice && pm.hasSystemFeature("android.hardware.type.watch"));
+        return !lowRamDevice || pm.hasSystemFeature("android.hardware.type.watch")
+                || hasSecureElementPackage(pm);
+    }
+
+    private boolean hasSecureElementPackage(PackageManager pm) {
+        try {
+            pm.getPackageInfo("com.android.se", 0 /* flags*/);
+            return true;
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
     }
 
     private boolean supportOMAPIReaders() {
diff --git a/tests/tests/secure_element/access_control/AccessControlApp3/src/android/omapi/accesscontrol3/cts/AccessControlTest.java b/tests/tests/secure_element/access_control/AccessControlApp3/src/android/omapi/accesscontrol3/cts/AccessControlTest.java
index e6dc5f0..24e0cac 100755
--- a/tests/tests/secure_element/access_control/AccessControlApp3/src/android/omapi/accesscontrol3/cts/AccessControlTest.java
+++ b/tests/tests/secure_element/access_control/AccessControlApp3/src/android/omapi/accesscontrol3/cts/AccessControlTest.java
@@ -168,7 +168,17 @@
     private boolean supportsHardware() {
         final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
         boolean lowRamDevice = PropertyUtil.propertyEquals("ro.config.low_ram", "true");
-        return !lowRamDevice || (lowRamDevice && pm.hasSystemFeature("android.hardware.type.watch"));
+        return !lowRamDevice || pm.hasSystemFeature("android.hardware.type.watch")
+                || hasSecureElementPackage(pm);
+    }
+
+    private boolean hasSecureElementPackage(PackageManager pm) {
+        try {
+            pm.getPackageInfo("com.android.se", 0 /* flags*/);
+            return true;
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
     }
 
     private boolean supportOMAPIReaders() {
diff --git a/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java b/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
index d634fee..9a862d7 100644
--- a/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
+++ b/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
@@ -155,7 +155,17 @@
     private boolean supportsHardware() {
         final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
         boolean lowRamDevice = PropertyUtil.propertyEquals("ro.config.low_ram", "true");
-        return !lowRamDevice || (lowRamDevice && pm.hasSystemFeature("android.hardware.type.watch"));
+        return !lowRamDevice || pm.hasSystemFeature("android.hardware.type.watch")
+                || hasSecureElementPackage(pm);
+    }
+
+    private boolean hasSecureElementPackage(PackageManager pm) {
+        try {
+            pm.getPackageInfo("com.android.se", 0 /* flags*/);
+            return true;
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
     }
 
     private boolean supportUICCReaders() {
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
index de40198..476166eb 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -2483,28 +2483,6 @@
     }
 
     @Test
-    public void testSetPolicyDataEnabled() {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
-            return;
-        }
-        // test without permission: verify SecurityException
-        try {
-            mTelephonyManager.setPolicyDataEnabled(true);
-            fail("testSetPolicyDataEnabled: SecurityException expected");
-        } catch (SecurityException se) {
-            // expected
-        }
-        // test with permission
-        try {
-            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
-                    mTelephonyManager,
-                    (tm) -> tm.setPolicyDataEnabled(true));
-        } catch (SecurityException se) {
-            fail("testSetPolicyDataEnabled: SecurityException not expected");
-        }
-    }
-
-    @Test
     public void testSetAllowedNetworkTypes() {
         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
             return;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 7419858..94b2c1e 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -245,9 +245,7 @@
             return;
         }
 
-        // TODO(b/148840827): Uncomment default value assertion when a new version of WebView
-        // where the change happened is dropped in master.
-        // assertFalse("File access should be off by default", mSettings.getAllowFileAccess());
+        assertFalse("File access should be off by default", mSettings.getAllowFileAccess());
 
         mSettings.setAllowFileAccess(true);
         assertTrue("Explicitly setting file access to true should work",