Merge stage-aosp-rvc-ts-dev into rvc-dev

Bug: 148878042
Exempt-From-Owner-Approval: All changes are already in master
Merged-In: Ie1f3e27e0c973e6410fcecfcee049d736481f0e6
Change-Id: I37b338f2cc04c30e49a6a29e89beb529f2e30824
diff --git a/apps/CameraITS/pymodules/its/caps.py b/apps/CameraITS/pymodules/its/caps.py
index ccbaa65..ddb3c95 100644
--- a/apps/CameraITS/pymodules/its/caps.py
+++ b/apps/CameraITS/pymodules/its/caps.py
@@ -555,12 +555,13 @@
               0 in props["android.request.availableCapabilities"]
 
 
-def sensor_fusion_capable(props):
+def sensor_fusion_test_capable(props, cam):
     """Determine if test_sensor_fusion is run."""
     return all([
             its.caps.sensor_fusion(props),
             its.caps.manual_sensor(props),
-            props["android.lens.facing"] != FACING_EXTERNAL])
+            props["android.lens.facing"] != FACING_EXTERNAL,
+            cam.get_sensors().get("gyro")])
 
 
 def multi_camera_frame_sync_capable(props):
diff --git a/apps/CameraITS/tests/scene1_1/test_dng_noise_model.py b/apps/CameraITS/tests/scene1_1/test_dng_noise_model.py
index 8afc41b..e257937 100644
--- a/apps/CameraITS/tests/scene1_1/test_dng_noise_model.py
+++ b/apps/CameraITS/tests/scene1_1/test_dng_noise_model.py
@@ -57,7 +57,7 @@
         sens_min, _ = props['android.sensor.info.sensitivityRange']
         sens_max_ana = props['android.sensor.maxAnalogSensitivity']
         sens_step = (sens_max_ana - sens_min) / NUM_STEPS
-        s_ae, e_ae, _, _, _ = cam.do_3a(get_results=True, do_af=False)
+        s_ae, e_ae, _, _, _ = cam.do_3a(get_results=True)
         s_e_prod = s_ae * e_ae
         # Focus at zero to intentionally blur the scene as much as possible.
         f_dist = 0.0
diff --git a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
index f1b1d36..0caf148 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
@@ -425,7 +425,7 @@
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
         props = cam.override_with_hidden_physical_camera_props(props)
-        its.caps.skip_unless(its.caps.sensor_fusion_capable(props))
+        its.caps.skip_unless(its.caps.sensor_fusion_test_capable(props, cam))
 
         print "Starting sensor event collection"
         cam.start_sensor_events()
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index aa326a6..95eac99 100644
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -307,7 +307,7 @@
     with ItsSession(camera_id) as cam:
         props = cam.get_camera_properties()
         method = {'test_sensor_fusion': {
-                          'flag': its.caps.sensor_fusion_capable(props),
+                          'flag': its.caps.sensor_fusion_test_capable(props, cam),
                           'runs': 10},
                   'test_multi_camera_frame_sync': {
                           'flag': its.caps.multi_camera_frame_sync_capable(props),
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 1981e03..11e1a55 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -3664,6 +3664,17 @@
                        android:value="android.software.leanback" />
         </activity>
 
+        <activity android:name=".tv.audio.AudioCapabilitiesTestActivity"
+                  android:label="@string/tv_audio_capabilities_test"
+                  android:configChanges="orientation|screenSize|density|smallestScreenSize|screenLayout">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_tv" />
+            <meta-data android:name="test_required_features"
+                       android:value="android.software.leanback" />
+        </activity>
         <activity android:name=".tv.display.DisplayHdrCapabilitiesTestActivity"
                   android:label="@string/tv_hdr_capabilities_test"
                   android:configChanges="orientation|screenSize|density|smallestScreenSize|screenLayout">
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 2308863..4a0314c 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -4645,6 +4645,12 @@
     <!-- Common strings for the TV Display tests -->
     <string name="tv_start_test">Start Test</string>
 
+    <!-- Audio Capabilities test -->
+    <string name="tv_audio_capabilities_test">Audio Capabilities Test</string>
+    <string name="tv_audio_capabilities_test_info">This test checks if AudioDeviceInfo and
+    AudioTrack#isDirectPlaybackSupported APIs correctly report the Audio capabilities
+    of the connected audio devices.</string>
+
     <!-- HDR Capabilities test -->
     <string name="tv_hdr_capabilities_test">HDR Capabilities Test</string>
     <string name="tv_hdr_capabilities_test_step_hdr_display">HDR Display</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/RingerModeActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/RingerModeActivity.java
index 09d705f..d3fa699 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/RingerModeActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/RingerModeActivity.java
@@ -808,6 +808,11 @@
 
         @Override
         protected void test() {
+            if (mSkipRingerTests) {
+                status = PASS;
+                return;
+            }
+
             int volume, volumeDelta;
             int[] streams = {STREAM_MUSIC,
                     AudioManager.STREAM_VOICE_CALL,
@@ -1000,6 +1005,7 @@
         @Override
         protected void test() {
             if (mSkipRingerTests) {
+                status = PASS;
                 return;
             }
             int[] streams = { AudioManager.STREAM_RING };
@@ -1041,6 +1047,7 @@
         @Override
         protected void test() {
             if (mSkipRingerTests) {
+                status = PASS;
                 return;
             }
             int[] streams = { AudioManager.STREAM_RING };
@@ -1125,6 +1132,7 @@
         @Override
         protected void test() {
             if (mSkipRingerTests) {
+                status = PASS;
                 return;
             }
             int musicVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/TestSequence.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TestSequence.java
similarity index 97%
rename from apps/CtsVerifier/src/com/android/cts/verifier/tv/display/TestSequence.java
rename to apps/CtsVerifier/src/com/android/cts/verifier/tv/TestSequence.java
index 7815dcf..7b80155 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/TestSequence.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TestSequence.java
@@ -1,4 +1,4 @@
-package com.android.cts.verifier.tv.display;
+package com.android.cts.verifier.tv;
 
 
 import com.android.cts.verifier.tv.TvAppVerifierActivity;
@@ -63,4 +63,4 @@
         boolean allTestStepsPass = steps.stream().allMatch(step -> step.hasPassed());
         context.getPassButton().setEnabled(allTestStepsPass);
     }
-}
\ No newline at end of file
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/TestStepBase.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TestStepBase.java
similarity index 97%
rename from apps/CtsVerifier/src/com/android/cts/verifier/tv/display/TestStepBase.java
rename to apps/CtsVerifier/src/com/android/cts/verifier/tv/TestStepBase.java
index 050c549..6c9b5a1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/TestStepBase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TestStepBase.java
@@ -14,13 +14,12 @@
  * limitations under the License
  */
 
-package com.android.cts.verifier.tv.display;
+package com.android.cts.verifier.tv;
 
 import android.view.View;
 import android.widget.TextView;
 
 import com.android.cts.verifier.R;
-import com.android.cts.verifier.tv.TvAppVerifierActivity;
 
 import com.google.common.truth.FailureStrategy;
 import com.google.common.truth.StandardSubjectBuilder;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/AudioCapabilitiesTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/AudioCapabilitiesTestActivity.java
new file mode 100644
index 0000000..544b3c5
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/AudioCapabilitiesTestActivity.java
@@ -0,0 +1,95 @@
+/*
+ * 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.tv.audio;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.tv.TestSequence;
+import com.android.cts.verifier.tv.TestStepBase;
+import com.android.cts.verifier.tv.TvAppVerifierActivity;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Test to verify Audio Capabilities APIs are correctly implemented.
+ *
+ * <p>This test checks if the APIs return correct results when
+ *
+ * <ol>
+ *   <li>No receiver or soundbar is connected
+ *   <li>Receiver or soundbar is connected
+ * </ol>
+ *
+ * The test verifies the behavior of following APIs.
+ *
+ * <ul>
+ *   <li><a
+ *       href="https://developer.android.com/reference/android/media/AudioDeviceInfo#getEncodings()">
+ *       AudioDeviceInfo.getEncodings()</a>
+ *   <li><a
+ *       href="https://developer.android.com/reference/android/media/AudioDeviceInfo#getChannelCounts()">
+ *       AudioDeviceInfo.getChannelCounts()</a>
+ *   <li><a
+ *       href="https://developer.android.com/reference/android/media/AudioDeviceInfo#getSampleRates()">
+ *       AudioDeviceInfo.getSampleRates()</a>
+ *   <li><a
+ *       href="https://developer.android.com/reference/android/media/AudioTrack#isDirectPlaybackSupported(android.media.AudioFormat,%20android.media.AudioAttributes)">
+ *       AudioTrack.isDirectPlaybackSupported()</a>
+ * </ul>
+ */
+public class AudioCapabilitiesTestActivity extends TvAppVerifierActivity {
+    private TestSequence mTestSequence;
+
+    @Override
+    protected void setInfoResources() {
+        setInfoResources(
+                R.string.tv_audio_capabilities_test, R.string.tv_audio_capabilities_test_info, -1);
+    }
+
+    @Override
+    protected void createTestItems() {
+        List<TestStepBase> testSteps = new ArrayList<>();
+        testSteps.add(new TVTestStep(this));
+        testSteps.add(new ReceiverTestStep(this));
+        mTestSequence = new TestSequence(this, testSteps);
+        mTestSequence.init();
+    }
+
+    private static class TVTestStep extends TestStep {
+        public TVTestStep(TvAppVerifierActivity context) {
+            super(context, "", R.string.tv_start_test);
+        }
+
+        @Override
+        public boolean runTest() {
+            // TODO: Add test logic
+            return false;
+        }
+    }
+
+    private static class ReceiverTestStep extends TestStep {
+        public ReceiverTestStep(TvAppVerifierActivity context) {
+            super(context, "", R.string.tv_start_test);
+        }
+
+        @Override
+        public boolean runTest() {
+            // TODO: Add test logic
+            return false;
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/OWNERS
new file mode 100644
index 0000000..b19e6c1
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/OWNERS
@@ -0,0 +1,2 @@
+kritidang@google.com
+blindahl@google.com
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/TestStep.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/TestStep.java
new file mode 100644
index 0000000..cafc226
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/audio/TestStep.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.cts.verifier.tv.audio;
+
+import android.view.View;
+
+import androidx.annotation.StringRes;
+
+import com.android.cts.verifier.tv.TestStepBase;
+import com.android.cts.verifier.tv.TvAppVerifierActivity;
+
+/** Test step containing instruction to the user and a button. */
+public abstract class TestStep extends TestStepBase {
+    protected View mButtonView;
+
+    @StringRes private int mButtonStringId;
+
+    /**
+     * Constructs a test step containing instruction to the user and a button.
+     *
+     * @param context The test activity which this test step is part of.
+     * @param instructionText Text of the test instruction visible to the user.
+     * @param buttonTextId Id of a string resource containing the text of the button.
+     */
+    public TestStep(
+            TvAppVerifierActivity context, String instructionText, @StringRes int buttonStringId) {
+        super(context, instructionText);
+        mButtonStringId = buttonStringId;
+    }
+
+    /** Creates the View for this test step in the context {@link TvAppVerifierActivity}. */
+    public void createUiElements() {
+        super.createUiElements();
+        mButtonView =
+                mContext.createButtonItem(
+                        mButtonStringId,
+                        (View view) -> {
+                            onButtonClickRunTest();
+                        });
+    }
+
+    @Override
+    public void enableInteractivity() {
+        TvAppVerifierActivity.setButtonEnabled(mButtonView, true);
+    }
+
+    @Override
+    public void disableInteractivity() {
+        TvAppVerifierActivity.setButtonEnabled(mButtonView, false);
+    }
+
+    public abstract boolean runTest();
+
+    private void onButtonClickRunTest() {
+        disableInteractivity();
+        super.done();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java
index 1fd4bdd..7c6efbc 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayHdrCapabilitiesTestActivity.java
@@ -24,6 +24,8 @@
 import androidx.annotation.StringRes;
 
 import com.android.cts.verifier.R;
+import com.android.cts.verifier.tv.TestSequence;
+import com.android.cts.verifier.tv.TestStepBase;
 import com.android.cts.verifier.tv.TvAppVerifierActivity;
 import com.android.cts.verifier.tv.TvUtil;
 
@@ -102,8 +104,7 @@
 
         @Override
         public void runTest() {
-            DisplayManager displayManager =
-                    (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
+            DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
             Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
             getAsserter().withMessage("Display.isHdr()").that(display.isHdr()).isFalse();
             getAsserter()
@@ -134,8 +135,7 @@
 
         @Override
         public void runTest() {
-            DisplayManager displayManager =
-                    (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
+            DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
             Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
 
             getAsserter().withMessage("Display.isHdr()").that(display.isHdr()).isTrue();
@@ -206,8 +206,7 @@
         private void runTest() {
             try {
                 // Verify the display APIs do not crash when the display is disconnected
-                DisplayManager displayManager =
-                        (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
+                DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
                 Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
                 display.isHdr();
                 display.getHdrCapabilities();
@@ -224,8 +223,7 @@
         }
 
         private static String getInstructionText(Context context) {
-            DisplayManager displayManager =
-                    (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+            DisplayManager displayManager = context.getSystemService(DisplayManager.class);
             Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
 
             int[] hdrTypes = display.getHdrCapabilities().getSupportedHdrTypes();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java
index b663801..7c0f37f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/DisplayModesTestActivity.java
@@ -24,6 +24,8 @@
 import androidx.annotation.StringRes;
 
 import com.android.cts.verifier.R;
+import com.android.cts.verifier.tv.TestSequence;
+import com.android.cts.verifier.tv.TestStepBase;
 import com.android.cts.verifier.tv.TvAppVerifierActivity;
 import com.android.cts.verifier.tv.TvUtil;
 
@@ -130,8 +132,7 @@
         private void runTest() {
             try {
                 // Verify the display APIs do not crash when the display is disconnected
-                DisplayManager displayManager =
-                        (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
+                DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
                 Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
                 display.getMode();
                 display.getSupportedModes();
@@ -163,8 +164,7 @@
 
         @Override
         public void runTest() {
-            DisplayManager displayManager =
-                    (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
+            DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
             Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
             getAsserter()
                     .withMessage("Display.getMode()")
@@ -224,8 +224,7 @@
 
         @Override
         public void runTest() {
-            DisplayManager displayManager =
-                    (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
+            DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
             Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
 
             getAsserter()
@@ -265,8 +264,7 @@
         }
 
         private static String getInstructionText(Context context) {
-            DisplayManager displayManager =
-                    (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+            DisplayManager displayManager = context.getSystemService(DisplayManager.class);
             Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
             String supportedModes =
                     Arrays.stream(display.getSupportedModes())
@@ -289,7 +287,7 @@
     }
 
     // We use a custom Mode class since the constructors of Display.Mode are hidden. Additionally,
-    // we want to use fuzzy comparision for frame rates which is not used in Display.Mode.equals().
+    // we want to use fuzzy comparison for frame rates which is not used in Display.Mode.equals().
     private static class Mode {
         public int mWidth;
         public int mHeight;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/OneButtonTestStep.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/OneButtonTestStep.java
index c73fd53..6ee34f3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/OneButtonTestStep.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/OneButtonTestStep.java
@@ -20,6 +20,7 @@
 
 import androidx.annotation.StringRes;
 
+import com.android.cts.verifier.tv.TestStepBase;
 import com.android.cts.verifier.tv.TvAppVerifierActivity;
 
 /** Test step containing instruction to the user and a button. */
@@ -27,11 +28,9 @@
 
     protected View mButtonView;
 
-    @StringRes
-    private int mButtonStringId;
+    @StringRes private int mButtonStringId;
 
-    @StringRes
-    private int mStepNameStringId;
+    @StringRes private int mStepNameStringId;
 
     /**
      * Constructs a test step containing instruction to the user and a button.
@@ -39,11 +38,14 @@
      * @param context The test activity which this test step is part of.
      * @param instructionText The text of the test instruction visible to the user.
      * @param stepNameStringId Id of a string resource containing human readable name of this step
-     *                         to be used  in logs.
+     *     to be used in logs.
      * @param buttonStringId Id of a string resource containing the text of the button.
      */
-    public OneButtonTestStep(TvAppVerifierActivity context, @StringRes int stepNameStringId,
-            String instructionText, @StringRes int buttonStringId) {
+    public OneButtonTestStep(
+            TvAppVerifierActivity context,
+            @StringRes int stepNameStringId,
+            String instructionText,
+            @StringRes int buttonStringId) {
         super(context, instructionText);
         mStepNameStringId = stepNameStringId;
         mButtonStringId = buttonStringId;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java
index 0281252..4da4d18 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/display/YesNoTestStep.java
@@ -19,6 +19,7 @@
 import android.view.View;
 
 import com.android.cts.verifier.R;
+import com.android.cts.verifier.tv.TestStepBase;
 import com.android.cts.verifier.tv.TvAppVerifierActivity;
 
 /**
@@ -30,8 +31,8 @@
     private View noButton;
 
     /**
-     * Constructs a test step containing human instructions for a manual test and two buttons -
-     * Yes and No.
+     * Constructs a test step containing human instructions for a manual test and two buttons - Yes
+     * and No.
      *
      * @param context The test activity which this test step is part of.
      * @param instructionText The text of the test instruction visible to the user.
diff --git a/hostsidetests/adbmanager/Android.bp b/hostsidetests/adbmanager/Android.bp
new file mode 100644
index 0000000..54616e5
--- /dev/null
+++ b/hostsidetests/adbmanager/Android.bp
@@ -0,0 +1,25 @@
+// 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.
+
+java_test_host {
+    name: "CtsAdbManagerHostTestCases",
+    defaults: ["cts_defaults"],
+    srcs: ["src/**/*.java"],
+    test_suites: ["cts", "general-tests"],
+    libs: [
+        "compatibility-host-util",
+        "cts-tradefed",
+        "tradefed"
+    ],
+}
diff --git a/hostsidetests/adbmanager/AndroidTest.xml b/hostsidetests/adbmanager/AndroidTest.xml
new file mode 100644
index 0000000..2194a4c
--- /dev/null
+++ b/hostsidetests/adbmanager/AndroidTest.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<configuration description="Config for CTS AdbManager host test cases">
+    <option name="test-suite-tag" value="cts" />
+    <option name="config-descriptor:metadata" key="component" value="framework" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsAdbManagerHostTestCases.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/adbmanager/OWNERS b/hostsidetests/adbmanager/OWNERS
new file mode 100644
index 0000000..e102aca
--- /dev/null
+++ b/hostsidetests/adbmanager/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 1352
+joshuaduong@google.com
+mpgroover@google.com
+include platform/system/core:/janitors/OWNERS
diff --git a/hostsidetests/adbmanager/src/android/adbmanager/cts/AdbManagerHostDeviceTest.java b/hostsidetests/adbmanager/src/android/adbmanager/cts/AdbManagerHostDeviceTest.java
new file mode 100644
index 0000000..096f3fd
--- /dev/null
+++ b/hostsidetests/adbmanager/src/android/adbmanager/cts/AdbManagerHostDeviceTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.adbmanager.cts;
+
+import com.android.compatibility.common.util.CddTest;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.tradefed.util.CommandResult;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests the AdbManager System APIs via shell commands.
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class AdbManagerHostDeviceTest extends BaseHostJUnit4Test {
+    private static final String FEATURE_WIFI = "android.hardware.wifi";
+    private static final String FEATURE_CAMERA_ANY = "android.hardware.camera.any";
+
+    private boolean hasFeature(String feature) throws Exception {
+        CommandResult result = getDevice().executeShellV2Command("pm has-feature " + feature);
+        Assert.assertTrue(new Integer(0).equals(result.getExitCode()));
+        return Boolean.parseBoolean(result.getStdout().trim());
+    }
+
+    @Test
+    @CddTest(requirement="6.1/C-1-1")
+    public void test_isadbWifiSupported() throws Exception {
+        boolean expected = hasFeature(FEATURE_WIFI);
+
+        CommandResult result = getDevice().executeShellV2Command("cmd adb is-wifi-supported");
+
+        Assert.assertTrue(new Integer(0).equals(result.getExitCode()));
+        Assert.assertEquals(expected, Boolean.parseBoolean(result.getStdout().trim()));
+    }
+
+    @Test
+    @CddTest(requirement="6.1/C-1-2")
+    public void test_isadbWifiQrSupported() throws Exception {
+        boolean expected = hasFeature(FEATURE_WIFI) && hasFeature(FEATURE_CAMERA_ANY);
+
+        CommandResult result = getDevice().executeShellV2Command("cmd adb is-wifi-qr-supported");
+
+        Assert.assertTrue(new Integer(0).equals(result.getExitCode()));
+        Assert.assertEquals(expected, Boolean.parseBoolean(result.getStdout().trim()));
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
index a08a515..2a087dc 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
@@ -488,6 +488,8 @@
     private void doMediaSandboxed(Config config, boolean sandboxed) throws Exception {
         installPackage(config.apk);
         installPackage(MEDIA_29.apk);
+        // Make sure user initialization is complete before updating permission
+        waitForBroadcastIdle();
         for (int user : mUsers) {
             updatePermissions(config.pkg, user, new String[] {
                     PERM_READ_EXTERNAL_STORAGE,
@@ -749,6 +751,11 @@
         }
     }
 
+    /** Wait until all broadcast queues are idle. */
+    private void waitForBroadcastIdle() throws Exception{
+        getDevice().executeShellCommand("am wait-for-broadcast-idle");
+    }
+
     private void updateAppOp(String packageName, int userId, String appOp, boolean allow)
             throws Exception {
         updateAppOp(packageName, false, userId, appOp, allow);
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileCalendarTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileCalendarTest.java
index 5ced0e6..b565e32 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileCalendarTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileCalendarTest.java
@@ -238,6 +238,12 @@
         requireRunningOnPrimaryProfile();
 
         // Test the return cursor is correct when the all checks are met.
+        final String selection = "(" + CalendarContract.Calendars.ACCOUNT_TYPE  + "=? AND "
+                + CalendarContract.Events.TITLE  + " =? )";
+        final String[] selectionArgs = new String[] {
+                TEST_ACCOUNT_TYPE,
+                WORK_EVENT_TITLE
+        };
         final String[] projection = new String[]{
                 CalendarContract.Instances.TITLE,
                 CalendarContract.Instances.DTSTART,
@@ -247,7 +253,7 @@
                 buildQueryInstancesUri(CalendarContract.Instances.ENTERPRISE_CONTENT_URI,
                         WORK_EVENT_DTSTART - DateUtils.YEAR_IN_MILLIS,
                         WORK_EVENT_DTEND + DateUtils.YEAR_IN_MILLIS, null),
-                projection, null, null, null);
+                projection, selection, selectionArgs, null);
 
         assertThat(cursor).isNotNull();
         assertThat(cursor.getCount()).isEqualTo(1);
@@ -263,6 +269,12 @@
         requireRunningOnPrimaryProfile();
 
         // Test the return cursor is correct when the all checks are met.
+        final String selection = "(" + CalendarContract.Calendars.ACCOUNT_TYPE  + "=? AND "
+                + CalendarContract.Events.TITLE  + " =? )";
+        final String[] selectionArgs = new String[] {
+                TEST_ACCOUNT_TYPE,
+                WORK_EVENT_TITLE
+        };
         final String[] projection = new String[]{
                 CalendarContract.Instances.TITLE,
                 CalendarContract.Instances.DTSTART,
@@ -272,7 +284,7 @@
                 buildQueryInstancesUri(CalendarContract.Instances.ENTERPRISE_CONTENT_BY_DAY_URI,
                         WORK_EVENT_DTSTART_JULIAN_DAY - 1,
                         WORK_EVENT_DTEND_JULIAN_DAY + 1, null),
-                projection, null, null, null);
+                projection, selection, selectionArgs, null);
 
         assertThat(cursor).isNotNull();
         assertThat(cursor.getCount()).isEqualTo(1);
diff --git a/hostsidetests/packagemanager/dynamicmime/app/manifests/AndroidManifest_preferred.xml b/hostsidetests/packagemanager/dynamicmime/app/manifests/AndroidManifest_preferred.xml
index 83cdf0e..a2b7c08 100644
--- a/hostsidetests/packagemanager/dynamicmime/app/manifests/AndroidManifest_preferred.xml
+++ b/hostsidetests/packagemanager/dynamicmime/app/manifests/AndroidManifest_preferred.xml
@@ -23,7 +23,7 @@
         <uses-library android:name="android.test.runner" />
         <activity android:name="android.dynamicmime.common.activity.FirstActivity">
             <intent-filter android:label="TestApp.FirstActivity">
-                <action android:name="android.intent.action.SEND"/>
+                <action android:name="android.dynamicmime.preferred.TEST_ACTION"/>
                 <action android:name="android.dynamicmime.preferred.FILTER_INFO_HOOK_group_first"/>
                 <category android:name="android.intent.category.DEFAULT"/>
                 <data android:mimeGroup="group_first"/>
@@ -32,14 +32,34 @@
 
         <activity android:name="android.dynamicmime.common.activity.TwoGroupsActivity">
             <intent-filter android:label="TestApp.TwoGroupsActivity">
-                <action android:name="android.intent.action.SEND"/>
-                <category android:name="android.intent.category.DEFAULT"/>
+                <action android:name="android.dynamicmime.preferred.TEST_ACTION"/>
                 <action android:name="android.dynamicmime.preferred.FILTER_INFO_HOOK_group_both"/>
+                <category android:name="android.intent.category.DEFAULT"/>
                 <data android:mimeGroup="group_third"/>
                 <data android:mimeGroup="group_second"/>
             </intent-filter>
         </activity>
 
+        <activity android:name="android.dynamicmime.common.activity.StaticActivity1"
+            android:exported="true">
+            <intent-filter android:label="StaticActivity1">
+                <action android:name="android.dynamicmime.preferred.TEST_ACTION"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <data android:mimeType="text/plain"/>
+                <data android:mimeType="image/png"/>
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.dynamicmime.common.activity.StaticActivity2"
+            android:exported="true">
+            <intent-filter android:label="StaticActivity2">
+                <action android:name="android.dynamicmime.preferred.TEST_ACTION"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <data android:mimeType="text/plain"/>
+                <data android:mimeType="image/png"/>
+            </intent-filter>
+        </activity>
+
         <receiver android:name="android.dynamicmime.app.AppMimeGroupsReceiver"
                   android:exported="true">
             <intent-filter>
diff --git a/hostsidetests/packagemanager/dynamicmime/common/src/android/dynamicmime/common/activity/StaticActivity1.java b/hostsidetests/packagemanager/dynamicmime/common/src/android/dynamicmime/common/activity/StaticActivity1.java
new file mode 100644
index 0000000..a76f09e
--- /dev/null
+++ b/hostsidetests/packagemanager/dynamicmime/common/src/android/dynamicmime/common/activity/StaticActivity1.java
@@ -0,0 +1,27 @@
+/*
+ * 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.dynamicmime.common.activity;
+
+import android.app.Activity;
+
+/**
+ * Activity that has intent-filter to handle "text/plain" and "image/png" MIME types.
+ *
+ * Needed for {@link android.dynamicmime.testapp.preferred.PreferredActivitiesTest} to ensure that
+ * there is more than one activity, capable of handling certain MIME types.
+ */
+public class StaticActivity1 extends Activity {
+}
\ No newline at end of file
diff --git a/hostsidetests/packagemanager/dynamicmime/common/src/android/dynamicmime/common/activity/StaticActivity2.java b/hostsidetests/packagemanager/dynamicmime/common/src/android/dynamicmime/common/activity/StaticActivity2.java
new file mode 100644
index 0000000..ad536db
--- /dev/null
+++ b/hostsidetests/packagemanager/dynamicmime/common/src/android/dynamicmime/common/activity/StaticActivity2.java
@@ -0,0 +1,27 @@
+/*
+ * 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.dynamicmime.common.activity;
+
+import android.app.Activity;
+
+/**
+ * Activity that has intent-filter to handle "text/plain" and "image/png" MIME types.
+ *
+ * Needed for {@link android.dynamicmime.testapp.preferred.PreferredActivitiesTest} to ensure that
+ * there is more than one activity, capable of handling certain MIME types.
+ */
+public class StaticActivity2 extends Activity {
+}
\ No newline at end of file
diff --git a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
index c9e25b0..d37b0f5 100644
--- a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
+++ b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
@@ -54,11 +54,9 @@
 
 @RunWith(AndroidJUnit4.class)
 public class PreferredActivitiesTest extends BaseDynamicMimeTest {
-    private static final String NAV_BAR_INTERACTION_MODE_RES_NAME = "config_navBarInteractionMode";
-    private static final int NAV_BAR_INTERACTION_MODE_GESTURAL = 2;
+    private static final String ACTION = "android.dynamicmime.preferred.TEST_ACTION";
 
     private static final BySelector BUTTON_ALWAYS = By.res("android:id/button_always");
-    private static final BySelector RESOLVER_DIALOG = By.res("android:id/contentPanel");
 
     private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(30L);
 
@@ -71,17 +69,6 @@
     @Before
     public void setUp() {
         Utils.installApk(APK_PREFERRED_APP);
-        assumeNavigationMode();
-    }
-
-    private void assumeNavigationMode() {
-        Resources res = context().getResources();
-        int navModeResId = res.getIdentifier(NAV_BAR_INTERACTION_MODE_RES_NAME, "integer",
-                "android");
-        int navMode = res.getInteger(navModeResId);
-
-        assumeTrue("Non-gesture navigation mode required",
-                navMode != NAV_BAR_INTERACTION_MODE_GESTURAL);
     }
 
     @After
@@ -288,10 +275,6 @@
     }
 
     private UiObject2 findActivityInDialog(String label) {
-        getUiDevice()
-                .wait(Until.findObject(RESOLVER_DIALOG), TIMEOUT)
-                .swipe(Direction.UP, 1f);
-
         return getUiDevice().findObject(By.text(label));
     }
 
@@ -331,7 +314,7 @@
 
     private static void sendIntent(String mimeType) {
         Intent sendIntent = new Intent();
-        sendIntent.setAction(Intent.ACTION_SEND);
+        sendIntent.setAction(ACTION);
         sendIntent.setType(mimeType);
         sendIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         targetContext().startActivity(sendIntent, null);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedDisplayTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedDisplayTest.java
index 0fd37c2..ece2fbf 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedDisplayTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedDisplayTest.java
@@ -19,6 +19,7 @@
 import static android.accessibilityservice.cts.utils.AccessibilityEventFilterUtils.filterWindowsChangeTypesAndWindowTitle;
 import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.findWindowByTitle;
 import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchActivityAndWaitForItToBeOnscreen;
+import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.supportsMultiDisplay;
 import static android.accessibilityservice.cts.utils.AsyncUtils.DEFAULT_TIMEOUT_MS;
 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
 import static android.view.accessibility.AccessibilityEvent.WINDOWS_CHANGE_ADDED;
@@ -101,7 +102,7 @@
     @Before
     public void setUp() throws Exception {
         mContext = sInstrumentation.getContext();
-        assumeTrue(supportsMultiDisplay());
+        assumeTrue(supportsMultiDisplay(mContext));
 
         mParentActivityTitle = mContext.getString(
                 R.string.accessibility_embedded_display_test_parent_activity);
@@ -246,11 +247,6 @@
         assertNotNull(mEmbeddedDisplayActivity);
     }
 
-    private boolean supportsMultiDisplay() {
-        return mContext.getPackageManager().hasSystemFeature(
-                FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
-    }
-
     public static class EmbeddedDisplayParentActivity extends Activity {
         private ActivityView mActivityView;
 
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
index 252fbcb..b32d5b8 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
@@ -21,6 +21,7 @@
 import static android.accessibilityservice.cts.utils.AccessibilityEventFilterUtils.filterWindowsChangedWithChangeTypes;
 import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchActivityAndWaitForItToBeOnscreen;
 import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchActivityOnSpecifiedDisplayAndWaitForItToBeOnscreen;
+import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.supportsMultiDisplay;
 import static android.accessibilityservice.cts.utils.AsyncUtils.DEFAULT_TIMEOUT_MS;
 import static android.accessibilityservice.cts.utils.DisplayUtils.getStatusBarHeight;
 import static android.accessibilityservice.cts.utils.DisplayUtils.VirtualDisplaySession;
@@ -50,6 +51,7 @@
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
 
 import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.AccessibilityService;
@@ -637,6 +639,8 @@
 
     @Test
     public void testGetWindowsOnAllDisplays_resultIsSortedByLayerDescending() throws Exception {
+        assumeTrue(supportsMultiDisplay(sInstrumentation.getContext()));
+
         addTwoAppPanelWindows(mActivity);
         // Creates a virtual display.
         try (final VirtualDisplaySession displaySession = new VirtualDisplaySession()) {
@@ -655,9 +659,9 @@
             SparseArray<List<AccessibilityWindowInfo>> allWindows =
                     sUiAutomation.getWindowsOnAllDisplays();
             assertNotNull(allWindows);
-            assertTrue(allWindows.size() == 2);
 
             // Gets windows on default display.
+            assertTrue(allWindows.contains(Display.DEFAULT_DISPLAY));
             List<AccessibilityWindowInfo> windowsOnDefaultDisplay =
                     allWindows.get(Display.DEFAULT_DISPLAY);
             assertNotNull(windowsOnDefaultDisplay);
@@ -672,6 +676,7 @@
                     new IsSortedBy<>(w -> w.getLayer(), /* ascending */ false));
 
             // Gets windows on virtual display.
+            assertTrue(allWindows.contains(virtualDisplayId));
             List<AccessibilityWindowInfo> windowsOnVirtualDisplay =
                     allWindows.get(virtualDisplayId);
             assertNotNull(windowsOnVirtualDisplay);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
index 3e253a7..2638c91 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
@@ -23,6 +23,7 @@
 import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.getActivityTitle;
 import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchActivityAndWaitForItToBeOnscreen;
 import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchActivityOnSpecifiedDisplayAndWaitForItToBeOnscreen;
+import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.supportsMultiDisplay;
 import static android.accessibilityservice.cts.utils.DisplayUtils.VirtualDisplaySession;
 import static android.accessibilityservice.cts.utils.DisplayUtils.getStatusBarHeight;
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
@@ -41,6 +42,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeTrue;
 
 import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.AccessibilityServiceInfo;
@@ -242,6 +244,8 @@
 
     @Test
     public void moveFocusToAnotherDisplay_movesActiveAndFocusWindow() throws Exception {
+        assumeTrue(supportsMultiDisplay(sInstrumentation.getContext()));
+
         // Makes sure activityWindow on default display is focused
         AccessibilityWindowInfo activityWindow = findWindowByTitle(sUiAutomation, mActivityTitle);
         assertTrue(activityWindow.isActive());
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
index 83ac347..6885b71 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
@@ -16,6 +16,7 @@
 
 import static android.accessibility.cts.common.ShellCommandBuilder.execShellCommand;
 import static android.accessibilityservice.cts.utils.AsyncUtils.DEFAULT_TIMEOUT_MS;
+import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
@@ -154,6 +155,11 @@
         }
     }
 
+    public static boolean supportsMultiDisplay(Context context) {
+        return context.getPackageManager().hasSystemFeature(
+                FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
+    }
+
     private static boolean isHomeScreenShowing(Context context, UiAutomation uiAutomation) {
         final List<AccessibilityWindowInfo> windows = uiAutomation.getWindows();
         final PackageManager packageManager = context.getPackageManager();
diff --git a/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java b/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
index 980800c..e7d7394 100644
--- a/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
+++ b/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
@@ -16,6 +16,8 @@
 
 package android.app.cts;
 
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningAppProcessInfo;
 import android.app.ApplicationExitInfo;
@@ -734,6 +736,60 @@
                 info.getRss() * 1024, new StringBuilder()));
     }
 
+    // A clone of testPermissionChange using a different revoke api
+    public void testPermissionChangeWithReason() throws Exception {
+        String revokeReason = "test reason";
+        // Remove old records to avoid interference with the test.
+        clearHistoricalExitInfo();
+
+        // Grant the read calendar permission
+        mInstrumentation.getUiAutomation().grantRuntimePermission(
+                STUB_PACKAGE_NAME, android.Manifest.permission.READ_CALENDAR);
+        long now = System.currentTimeMillis();
+
+        // Start a process and do nothing
+        startService(ACTION_FINISH, STUB_SERVICE_NAME, false, false);
+
+        // Enable high frequency memory sampling
+        executeShellCmd("dumpsys procstats --start-testing");
+        // Sleep for a while to wait for the sampling of memory info
+        sleep(10000);
+        // Stop the high frequency memory sampling
+        executeShellCmd("dumpsys procstats --stop-testing");
+        // Get the memory info from it.
+        String dump = executeShellCmd("dumpsys activity processes " + STUB_PACKAGE_NAME);
+        assertNotNull(dump);
+        final String lastPss = extractMemString(dump, " lastPss=", ' ');
+        final String lastRss = extractMemString(dump, " lastRss=", '\n');
+
+        // Revoke the read calendar permission
+        runWithShellPermissionIdentity(() -> {
+            mContext.getPackageManager().revokeRuntimePermission(STUB_PACKAGE_NAME,
+                    android.Manifest.permission.READ_CALENDAR, Process.myUserHandle(),
+                    revokeReason);
+        });
+        waitForGone(mWatcher);
+        long now2 = System.currentTimeMillis();
+
+        List<ApplicationExitInfo> list = ShellIdentityUtils.invokeMethodWithShellPermissions(
+                STUB_PACKAGE_NAME, mStubPackagePid, 1,
+                mActivityManager::getHistoricalProcessExitReasons,
+                android.Manifest.permission.DUMP);
+
+        assertTrue(list != null && list.size() == 1);
+
+        ApplicationExitInfo info = list.get(0);
+        verify(info, mStubPackagePid, mStubPackageUid, STUB_PACKAGE_NAME,
+                ApplicationExitInfo.REASON_PERMISSION_CHANGE, null, null, now, now2);
+        assertEquals(revokeReason, info.getDescription());
+
+        // Also verify that we get the expected meminfo
+        assertEquals(lastPss, DebugUtils.sizeValueToString(
+                info.getPss() * 1024, new StringBuilder()));
+        assertEquals(lastRss, DebugUtils.sizeValueToString(
+                info.getRss() * 1024, new StringBuilder()));
+    }
+
     public void testCrash() throws Exception {
         // Remove old records to avoid interference with the test.
         clearHistoricalExitInfo();
diff --git a/tests/autofillservice/AndroidManifest.xml b/tests/autofillservice/AndroidManifest.xml
index d4d5459..f690678 100644
--- a/tests/autofillservice/AndroidManifest.xml
+++ b/tests/autofillservice/AndroidManifest.xml
@@ -134,6 +134,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity android:name=".augmented.AugmentedAuthActivity" />
         <activity android:name=".SimpleAfterLoginActivity" />
         <activity android:name=".SimpleBeforeLoginActivity" />
         <activity android:name=".NonAutofillableActivity" />
diff --git a/tests/autofillservice/res/layout/authentication_activity.xml b/tests/autofillservice/res/layout/authentication_activity.xml
new file mode 100644
index 0000000..23e58e7
--- /dev/null
+++ b/tests/autofillservice/res/layout/authentication_activity.xml
@@ -0,0 +1,44 @@
+<?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"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:focusable="true"
+              android:focusableInTouchMode="true"
+              android:orientation="vertical" >
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Authenticate?" />
+
+    <EditText
+        android:id="@+id/password"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:inputType="textPassword"
+        android:autofillHints="password" />
+
+    <Button
+        android:id="@+id/yes"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Yes" />
+
+</LinearLayout>
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AuthenticationActivity.java b/tests/autofillservice/src/android/autofillservice/cts/AuthenticationActivity.java
index b247ec2..7ddfccc 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AuthenticationActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AuthenticationActivity.java
@@ -34,6 +34,8 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.autofill.AutofillManager;
+import android.widget.Button;
+import android.widget.EditText;
 
 import com.google.common.base.Preconditions;
 
@@ -58,6 +60,7 @@
 
 
     private static final int MSG_WAIT_FOR_LATCH = 1;
+    private static final int MSG_REQUEST_AUTOFILL = 2;
 
     private static Bundle sData;
     private static final SparseArray<CannedDataset> sDatasets = new SparseArray<>();
@@ -73,10 +76,18 @@
     // Used to block response until it's counted down.
     private static CountDownLatch sResponseLatch;
 
+    // Guarded by sLock
+    // Used to request autofill for a autofillable view in AuthenticationActivity
+    private static boolean sRequestAutofill;
+
     private Handler mHandler;
 
+    private EditText mPasswordEditText;
+    private Button mYesButton;
+
     static void resetStaticState() {
-        setResultCode(RESULT_OK);
+        setResultCode(null, RESULT_OK);
+        setRequestAutofillForAuthenticationActivity(/* requestAutofill */ false);
         sDatasets.clear();
         sResponses.clear();
         for (int i = 0; i < sPendingIntents.size(); i++) {
@@ -168,15 +179,30 @@
         }
     }
 
+    public static void setRequestAutofillForAuthenticationActivity(boolean requestAutofill) {
+        synchronized (sLock) {
+            sRequestAutofill = requestAutofill;
+        }
+    }
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        setContentView(R.layout.authentication_activity);
+
+        mPasswordEditText = findViewById(R.id.password);
+        mYesButton = findViewById(R.id.yes);
+        mYesButton.setOnClickListener(view -> doIt());
+
         mHandler = new Handler(Looper.getMainLooper(), (m) -> {
             switch (m.what) {
                 case MSG_WAIT_FOR_LATCH:
                     waitForLatchAndDoIt();
                     break;
+                case MSG_REQUEST_AUTOFILL:
+                    requestFocusOnPassword();
+                    break;
                 default:
                     throw new IllegalArgumentException("invalid message: " + m);
             }
@@ -186,11 +212,17 @@
         if (sResponseLatch != null) {
             Log.d(TAG, "Delaying message until latch is counted down");
             mHandler.dispatchMessage(mHandler.obtainMessage(MSG_WAIT_FOR_LATCH));
+        } else if (sRequestAutofill) {
+            mHandler.dispatchMessage(mHandler.obtainMessage(MSG_REQUEST_AUTOFILL));
         } else {
             doIt();
         }
     }
 
+    private void requestFocusOnPassword() {
+        syncRunOnUiThread(() -> mPasswordEditText.requestFocus());
+    }
+
     private void waitForLatchAndDoIt() {
         try {
             final boolean called = sResponseLatch.await(5, TimeUnit.SECONDS);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
index 6c229e0..f0e1179 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
@@ -26,6 +26,7 @@
 
 import android.app.PendingIntent;
 import android.autofillservice.cts.InstrumentedAutoFillService.Replier;
+import android.autofillservice.cts.augmented.AugmentedAuthActivity;
 import android.autofillservice.cts.inline.InlineUiBot;
 import android.content.ClipboardManager;
 import android.content.Context;
@@ -100,6 +101,10 @@
             return sDefaultUiBot2;
         }
 
+        protected static UiBot getDropdownUiBot() {
+            return sDefaultUiBot;
+        }
+
         @ClassRule
         public static final SettingsStateKeeperRule sPublicServiceSettingsKeeper =
                 sTheRealServiceSettingsKeeper;
@@ -388,6 +393,7 @@
 
             InstrumentedAutoFillService.resetStaticState();
             AuthenticationActivity.resetStaticState();
+            AugmentedAuthActivity.resetStaticState();
             sReplier.reset();
         }
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAuthActivity.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAuthActivity.java
new file mode 100644
index 0000000..8de9eb7
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAuthActivity.java
@@ -0,0 +1,90 @@
+/*
+ * 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.augmented;
+
+import android.app.PendingIntent;
+import android.autofillservice.cts.AbstractAutoFillActivity;
+import android.autofillservice.cts.R;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.os.Bundle;
+import android.service.autofill.Dataset;
+import android.util.Log;
+import android.view.autofill.AutofillManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Activity for testing Augmented Autofill authentication flow. This activity shows a simple UI;
+ * when the UI is tapped, it returns whatever data was configured via the auth intent.
+ */
+public class AugmentedAuthActivity extends AbstractAutoFillActivity {
+    private static final String TAG = "AugmentedAuthActivity";
+
+    public static final String ID_AUTH_ACTIVITY_BUTTON = "button";
+
+    private static final String EXTRA_DATASET_TO_RETURN = "dataset_to_return";
+    private static final String EXTRA_CLIENT_STATE_TO_RETURN = "client_state_to_return";
+    private static final String EXTRA_RESULT_CODE_TO_RETURN = "result_code_to_return";
+
+    private static final List<PendingIntent> sPendingIntents = new ArrayList<>(1);
+
+    public static void resetStaticState() {
+        for (PendingIntent pendingIntent : sPendingIntents) {
+            pendingIntent.cancel();
+        }
+        sPendingIntents.clear();
+    }
+
+    public static IntentSender createSender(Context context, int requestCode,
+            Dataset datasetToReturn, Bundle clientStateToReturn, int resultCodeToReturn) {
+        Intent intent = new Intent(context, AugmentedAuthActivity.class);
+        intent.putExtra(EXTRA_DATASET_TO_RETURN, datasetToReturn);
+        intent.putExtra(EXTRA_CLIENT_STATE_TO_RETURN, clientStateToReturn);
+        intent.putExtra(EXTRA_RESULT_CODE_TO_RETURN, resultCodeToReturn);
+        PendingIntent pendingIntent = PendingIntent.getActivity(context, requestCode, intent, 0);
+        sPendingIntents.add(pendingIntent);
+        return pendingIntent.getIntentSender();
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Log.d(TAG, "Auth activity invoked, showing auth UI");
+        setContentView(R.layout.single_button_activity);
+        findViewById(R.id.button).setOnClickListener((v) -> {
+            Log.d(TAG, "Auth UI tapped, returning result");
+
+            Intent intent = getIntent();
+            Dataset dataset = intent.getParcelableExtra(EXTRA_DATASET_TO_RETURN);
+            Bundle clientState = intent.getParcelableExtra(EXTRA_CLIENT_STATE_TO_RETURN);
+            int resultCode = intent.getIntExtra(EXTRA_RESULT_CODE_TO_RETURN, RESULT_OK);
+            Log.d(TAG, "Output: dataset=" + dataset + ", clientState=" + clientState
+                    + ", resultCode=" + resultCode);
+
+            Intent result = new Intent();
+            result.putExtra(AutofillManager.EXTRA_AUTHENTICATION_RESULT, dataset);
+            result.putExtra(AutofillManager.EXTRA_CLIENT_STATE, clientState);
+            setResult(resultCode, result);
+
+            finish();
+        });
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java
index a8a26a3..af1229b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java
@@ -19,6 +19,7 @@
 
 import android.autofillservice.cts.R;
 import android.content.Context;
+import android.content.IntentSender;
 import android.os.Bundle;
 import android.service.autofill.InlinePresentation;
 import android.service.autofill.augmented.FillCallback;
@@ -189,6 +190,7 @@
                     final AutofillId id = pair.first;
                     datasetBuilder.setFieldInlinePresentation(id, pair.second, null,
                             dataset.mFieldPresentationById.get(id));
+                    datasetBuilder.setAuthentication(dataset.mAuthentication);
                 }
                 list.add(datasetBuilder.build());
             }
@@ -279,12 +281,14 @@
         private final Map<AutofillId, InlinePresentation> mFieldPresentationById;
         private final String mPresentation;
         private final AutofillValue mOnlyFieldValue;
+        private final IntentSender mAuthentication;
 
         private Dataset(@NonNull Builder builder) {
             mFieldValuesById = builder.mFieldValuesById;
             mPresentation = builder.mPresentation;
             mOnlyFieldValue = builder.mOnlyFieldValue;
             mFieldPresentationById = builder.mFieldPresentationById;
+            this.mAuthentication = builder.mAuthentication;
         }
 
         @NonNull
@@ -304,6 +308,7 @@
             return "Dataset: [presentation=" + mPresentation
                     + ", onlyField=" + mOnlyFieldValue
                     + ", fields=" + mFieldValuesById
+                    + ", auth=" + mAuthentication
                     + "]";
         }
 
@@ -314,6 +319,7 @@
 
             private final String mPresentation;
             private AutofillValue mOnlyFieldValue;
+            private IntentSender mAuthentication;
 
             public Builder(@NonNull String presentation) {
                 mPresentation = Objects.requireNonNull(presentation);
@@ -356,6 +362,13 @@
                 return this;
             }
 
+            /**
+             * Sets the authentication intent for this dataset.
+             */
+            public Builder setAuthentication(IntentSender authentication) {
+                mAuthentication = authentication;
+                return this;
+            }
 
             public Dataset build() {
                 return new Dataset(this);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedAuthTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedAuthTest.java
new file mode 100644
index 0000000..bb81399
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedAuthTest.java
@@ -0,0 +1,208 @@
+/*
+ * 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.CannedFillResponse.NO_RESPONSE;
+import static android.autofillservice.cts.Helper.ID_USERNAME;
+import static android.autofillservice.cts.augmented.AugmentedHelper.assertBasicRequestInfo;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.autofillservice.cts.AutofillActivityTestRule;
+import android.autofillservice.cts.augmented.AugmentedAuthActivity;
+import android.autofillservice.cts.augmented.AugmentedAutofillAutoActivityLaunchTestCase;
+import android.autofillservice.cts.augmented.AugmentedLoginActivity;
+import android.autofillservice.cts.augmented.CannedAugmentedFillResponse;
+import android.autofillservice.cts.augmented.CtsAugmentedAutofillService;
+import android.content.IntentSender;
+import android.service.autofill.Dataset;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+import android.widget.EditText;
+
+import org.junit.Test;
+
+public class InlineAugmentedAuthTest
+        extends AugmentedAutofillAutoActivityLaunchTestCase<AugmentedLoginActivity> {
+
+    protected AugmentedLoginActivity mActivity;
+
+    public InlineAugmentedAuthTest() {
+        super(getInlineUiBot());
+    }
+
+    @Override
+    protected AutofillActivityTestRule<AugmentedLoginActivity> getActivityRule() {
+        return new AutofillActivityTestRule<AugmentedLoginActivity>(AugmentedLoginActivity.class) {
+            @Override
+            protected void afterActivityLaunched() {
+                mActivity = getActivity();
+            }
+        };
+    }
+
+    @Test
+    public void testDatasetAuth_resultOk_validDataset() throws Exception {
+        // Set services
+        enableService();
+        enableAugmentedService();
+
+        // Set expectations
+        final EditText unField = mActivity.getUsername();
+        final AutofillId unFieldId = unField.getAutofillId();
+        final AutofillValue unValue = unField.getAutofillValue();
+        sReplier.addResponse(NO_RESPONSE);
+        Dataset authResult = new Dataset.Builder(createInlinePresentation("auth"))
+                .setId("dummyId")
+                .setValue(unFieldId, AutofillValue.forText("Auth Result"))
+                .build();
+        IntentSender authAction = AugmentedAuthActivity.createSender(mContext, 1,
+                authResult, null, RESULT_OK);
+        sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
+                .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("bla").build(),
+                        unFieldId)
+                .addInlineSuggestion(new CannedAugmentedFillResponse.Dataset.Builder("inline")
+                        .setField(unFieldId, "John Smith", createInlinePresentation("John"))
+                        .setAuthentication(authAction)
+                        .build())
+                .build());
+
+        // Trigger autofill request
+        mUiBot.selectByRelativeId(ID_USERNAME);
+        mUiBot.waitForIdle();
+        sReplier.getNextFillRequest();
+        CtsAugmentedAutofillService.AugmentedFillRequest request1 =
+                sAugmentedReplier.getNextFillRequest();
+
+        // Assert request
+        assertBasicRequestInfo(request1, mActivity, unFieldId, unValue);
+
+        // Confirm suggestions
+        mUiBot.assertDatasets("John");
+
+        // Tap on suggestion
+        mUiBot.selectDataset("John");
+        mUiBot.waitForIdle();
+
+        // Tap on the auth activity button and assert that the dataset from the auth activity is
+        // filled into the field.
+        mActivity.expectAutoFill("Auth Result");
+        mUiBot.selectByRelativeId(AugmentedAuthActivity.ID_AUTH_ACTIVITY_BUTTON);
+        mUiBot.waitForIdle();
+        mActivity.assertAutoFilled();
+        assertThat(unField.getText().toString()).isEqualTo("Auth Result");
+        mUiBot.assertNoDatasets();
+    }
+
+    @Test
+    public void testDatasetAuth_resultOk_nullDataset() throws Exception {
+        // Set services
+        enableService();
+        enableAugmentedService();
+
+        // Set expectations
+        final EditText unField = mActivity.getUsername();
+        final AutofillId unFieldId = unField.getAutofillId();
+        final AutofillValue unValue = unField.getAutofillValue();
+        sReplier.addResponse(NO_RESPONSE);
+        IntentSender authAction = AugmentedAuthActivity.createSender(mContext, 1,
+                null, null, RESULT_OK);
+        sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
+                .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("bla").build(),
+                        unFieldId)
+                .addInlineSuggestion(new CannedAugmentedFillResponse.Dataset.Builder("inline")
+                        .setField(unFieldId, "John Smith", createInlinePresentation("John"))
+                        .setAuthentication(authAction)
+                        .build())
+                .build());
+
+        // Trigger autofill request
+        mUiBot.selectByRelativeId(ID_USERNAME);
+        mUiBot.waitForIdle();
+        sReplier.getNextFillRequest();
+        CtsAugmentedAutofillService.AugmentedFillRequest request1 =
+                sAugmentedReplier.getNextFillRequest();
+
+        // Assert request
+        assertBasicRequestInfo(request1, mActivity, unFieldId, unValue);
+
+        // Confirm suggestions
+        mUiBot.assertDatasets("John");
+
+        // Tap on suggestion
+        mUiBot.selectDataset("John");
+        mUiBot.waitForIdle();
+
+        // Tap on the auth activity button and assert that the field is left unchanged (since the
+        // dataset returned from the auth activity is null).
+        mUiBot.selectByRelativeId(AugmentedAuthActivity.ID_AUTH_ACTIVITY_BUTTON);
+        mUiBot.waitForIdle();
+        assertThat(unField.getText().toString()).isEqualTo("");
+    }
+
+    @Test
+    public void testDatasetAuth_resultCancel() throws Exception {
+        // Set services
+        enableService();
+        enableAugmentedService();
+
+        // Set expectations
+        final EditText unField = mActivity.getUsername();
+        final AutofillId unFieldId = unField.getAutofillId();
+        final AutofillValue unValue = unField.getAutofillValue();
+        sReplier.addResponse(NO_RESPONSE);
+        Dataset authResult = new Dataset.Builder(createInlinePresentation("auth"))
+                .setId("dummyId")
+                .setValue(unFieldId, AutofillValue.forText("Auth Result"))
+                .build();
+        IntentSender authAction = AugmentedAuthActivity.createSender(mContext, 1,
+                authResult, null, RESULT_CANCELED);
+        sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
+                .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("bla").build(),
+                        unFieldId)
+                .addInlineSuggestion(new CannedAugmentedFillResponse.Dataset.Builder("inline")
+                        .setField(unFieldId, "John Smith", createInlinePresentation("John"))
+                        .setAuthentication(authAction)
+                        .build())
+                .build());
+
+        // Trigger autofill request
+        mUiBot.selectByRelativeId(ID_USERNAME);
+        mUiBot.waitForIdle();
+        sReplier.getNextFillRequest();
+        CtsAugmentedAutofillService.AugmentedFillRequest request1 =
+                sAugmentedReplier.getNextFillRequest();
+
+        // Assert request
+        assertBasicRequestInfo(request1, mActivity, unFieldId, unValue);
+
+        // Confirm suggestions
+        mUiBot.assertDatasets("John");
+
+        // Tap on suggestion
+        mUiBot.selectDataset("John");
+        mUiBot.waitForIdle();
+
+        // Tap on the auth activity button and assert that the field is left unchanged (since the
+        // result code returned by the auth activity is RESULT_CANCELED).
+        mUiBot.selectByRelativeId(AugmentedAuthActivity.ID_AUTH_ACTIVITY_BUTTON);
+        mUiBot.waitForIdle();
+        assertThat(unField.getText().toString()).isEqualTo("");
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedWebViewActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedWebViewActivityTest.java
new file mode 100644
index 0000000..7ebe26d
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedWebViewActivityTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.NO_RESPONSE;
+import static android.autofillservice.cts.WebViewActivity.HTML_NAME_PASSWORD;
+import static android.autofillservice.cts.WebViewActivity.HTML_NAME_USERNAME;
+import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.NO_AUGMENTED_RESPONSE;
+
+import android.app.assist.AssistStructure.ViewNode;
+import android.autofillservice.cts.AutofillActivityTestRule;
+import android.autofillservice.cts.CannedFillResponse;
+import android.autofillservice.cts.Helper;
+import android.autofillservice.cts.InstrumentedAutoFillService.FillRequest;
+import android.autofillservice.cts.MyWebView;
+import android.autofillservice.cts.WebViewActivity;
+import android.autofillservice.cts.augmented.AugmentedAutofillAutoActivityLaunchTestCase;
+import android.autofillservice.cts.augmented.CannedAugmentedFillResponse;
+import android.support.test.uiautomator.UiObject2;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.autofill.AutofillId;
+
+import org.junit.Test;
+
+public class InlineAugmentedWebViewActivityTest extends
+        AugmentedAutofillAutoActivityLaunchTestCase<WebViewActivity> {
+
+    private static final String TAG = "InlineAugmentedWebViewActivityTest";
+    private WebViewActivity mActivity;
+
+    public InlineAugmentedWebViewActivityTest() {
+        super(getInlineUiBot());
+    }
+
+    @Override
+    protected AutofillActivityTestRule<WebViewActivity> getActivityRule() {
+        return new AutofillActivityTestRule<WebViewActivity>(WebViewActivity.class) {
+            @Override
+            protected void beforeActivityLaunched() {
+                super.beforeActivityLaunched();
+                Log.i(TAG, "Setting service before launching the activity");
+                enableService();
+            }
+
+            @Override
+            protected void afterActivityLaunched() {
+                mActivity = getActivity();
+            }
+        };
+    }
+
+    @Test
+    public void testAugmentedAutoFillNoDatasets() throws Exception {
+        // Set service.
+        enableAutofillServices();
+
+        // Load WebView
+        mActivity.loadWebView(mUiBot);
+        mUiBot.waitForIdleSync();
+
+        // Set expectations.
+        sReplier.addResponse(CannedFillResponse.NO_RESPONSE);
+        sAugmentedReplier.addResponse(NO_AUGMENTED_RESPONSE);
+
+        // Trigger autofill.
+        mActivity.getUsernameInput().click();
+        sReplier.getNextFillRequest();
+        sAugmentedReplier.getNextFillRequest();
+
+        // Assert not shown.
+        mUiBot.assertNoDatasetsEver();
+    }
+
+    @Test
+    public void testAugmentedAutoFillOneDataset() throws Exception {
+        // Set service.
+        enableAutofillServices();
+
+        testBasicAugmentedAutofill();
+    }
+
+    @Test
+    public void testAugmentedAutoFill_startTypingHideInline() throws Exception {
+        // Set service.
+        enableAutofillServices();
+
+        testBasicAugmentedAutofill();
+
+        // Now pretend user typing something by updating the value in the input field.
+        mActivity.getUsernameInput().click();
+        mActivity.dispatchKeyPress(KeyEvent.KEYCODE_U);
+
+        // Expect the inline suggestion to disappear.
+        mUiBot.assertNoDatasets();
+    }
+
+    private void enableAutofillServices() throws Exception {
+        enableService();
+        enableAugmentedService();
+    }
+
+    private void testBasicAugmentedAutofill() throws Exception {
+        // Load WebView
+        MyWebView myWebView = mActivity.loadWebView(mUiBot);
+        mUiBot.waitForIdleSync();
+
+        // Set expectations
+        sReplier.addResponse(NO_RESPONSE);
+
+        // Trigger autofill.
+        mActivity.getUsernameInput().click();
+        mUiBot.waitForIdleSync();
+
+        // We cannot get webview field's AutofillId from AugmentedService FillRequest, we only can
+        // get these AutofillIds from AutofillService's AssistStructure by using html tag.
+        FillRequest autofillRequest = sReplier.getNextFillRequest();
+
+        // Set expectations for AugmentedService
+        AutofillId usernameId = getAutofillIdByWebViewTag(autofillRequest, HTML_NAME_USERNAME);
+        AutofillId passwordId = getAutofillIdByWebViewTag(autofillRequest, HTML_NAME_PASSWORD);
+        sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
+                .addInlineSuggestion(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
+                        .setField(usernameId, "dude", createInlinePresentation("dude"))
+                        .setField(passwordId, "sweet", createInlinePresentation("sweet"))
+                        .build())
+                .setOnlyDataset(new CannedAugmentedFillResponse.Dataset.Builder("req1")
+                        .setOnlyField("dude")
+                        .build())
+                .build());
+
+        sAugmentedReplier.getNextFillRequest();
+        final UiObject2 datasetPicker = mUiBot.assertDatasets("dude");
+
+        // Now Autofill it.
+        myWebView.expectAutofill("dude", "sweet");
+        mUiBot.selectDataset(datasetPicker, "dude");
+        myWebView.assertAutofilled();
+        mUiBot.assertNoDatasets();
+    }
+
+    private AutofillId getAutofillIdByWebViewTag(FillRequest autofillRequest, String tag) {
+        ViewNode viewNode = Helper.findNodeByHtmlName(autofillRequest.structure, tag);
+        return AutofillId.withoutSession(viewNode.getAutofillId());
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAuthenticationTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAuthenticationTest.java
index 5c63891..fcd18e4 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAuthenticationTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAuthenticationTest.java
@@ -133,6 +133,79 @@
     }
 
     @Test
+    public void testDatasetAuthPinnedPresentationSelectedAndAutofilled() throws Exception {
+        // Set service.
+        enableService();
+
+        // Prepare the authenticated dataset
+        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, null,
+                                Helper.createPinnedInlinePresentation("auth-pinned"))
+                        .setField(ID_PASSWORD, UNUSED_AUTOFILL_VALUE, null,
+                                Helper.createInlinePresentation("auth-unpinned"))
+                        .setPresentation(createPresentation("auth"))
+                        .setAuthentication(authentication)
+                        .build());
+        sReplier.addResponse(builder.build());
+
+        // Trigger auto-fill, verify seeing dataset.
+        assertSuggestionShownBySelectViewId(ID_USERNAME, "auth-pinned");
+        sReplier.getNextFillRequest();
+
+        // ...and select the dataset, then check the authentication result is autofilled.
+        mActivity.expectAutoFill("dude", "sweet");
+        AuthenticationActivity.setResultCode(RESULT_OK);
+        mUiBot.selectDataset("auth-pinned");
+        mUiBot.waitForIdle();
+        mActivity.assertAutoFilled();
+
+        // Clear the username field, and expect to see the pinned suggestion again, rather than
+        // the one returned from auth intent.
+        mActivity.onUsername((v) -> v.setText(""));
+        assertSuggestionShownBySelectViewId(ID_USERNAME, "auth-pinned");
+
+        // Now select the dataset again and verify that the same authentication flow happens.
+        mActivity.expectAutoFill("dude", "sweet");
+        AuthenticationActivity.setResultCode(RESULT_OK);
+        mUiBot.selectDataset("auth-pinned");
+        mUiBot.waitForIdle();
+        mActivity.assertAutoFilled();
+
+        // Clear the username field, put focus on password field, and then clear the password field,
+        // Expect to see unpinned suggestion.
+        mActivity.onUsername((v) -> v.setText(""));
+        mUiBot.selectByRelativeId(ID_PASSWORD);
+        mActivity.onPassword((v) -> v.setText(""));
+        assertSuggestionShownBySelectViewId(ID_PASSWORD, "auth-unpinned");
+
+        // Now select the dataset again and verify that the same authentication flow happens.
+        mActivity.expectAutoFill("dude", "sweet");
+        AuthenticationActivity.setResultCode(RESULT_OK);
+        mUiBot.selectDataset("auth-unpinned");
+        mUiBot.waitForIdle();
+        mActivity.assertAutoFilled();
+
+        // Clear the password field, and expect to see the unpinned suggestion again, rather than
+        // the one returned from auth intent.
+        mActivity.onPassword((v) -> v.setText(""));
+        assertSuggestionShownBySelectViewId(ID_PASSWORD, "auth-unpinned");
+
+        // Now select the dataset again and verify that the same authentication flow happens.
+        mActivity.expectAutoFill("dude", "sweet");
+        AuthenticationActivity.setResultCode(RESULT_OK);
+        mUiBot.selectDataset("auth-unpinned");
+        mUiBot.waitForIdle();
+        mActivity.assertAutoFilled();
+    }
+
+    @Test
     public void testDatasetAuthFilteringUsingRegex() throws Exception {
         // Set service.
         enableService();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
index 6aff0d5..eb18e96 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineLoginActivityTest.java
@@ -23,8 +23,11 @@
 import static android.autofillservice.cts.Helper.findAutofillIdByResourceId;
 import static android.autofillservice.cts.Helper.findNodeByResourceId;
 import static android.autofillservice.cts.Helper.getContext;
+import static android.autofillservice.cts.Timeouts.MOCK_IME_TIMEOUT_MS;
 import static android.autofillservice.cts.inline.InstrumentedAutoFillServiceInlineEnabled.SERVICE_NAME;
 
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent;
+
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
@@ -45,6 +48,7 @@
 import android.service.autofill.FillContext;
 import android.support.test.uiautomator.Direction;
 
+import com.android.cts.mockime.ImeEventStream;
 import com.android.cts.mockime.MockImeSession;
 
 import org.junit.Test;
@@ -396,4 +400,61 @@
         sReplier.getNextFillRequest();
         mUiBot.waitForIdleSync();
     }
+
+    @Test
+    public void testClickEventPassToIme() throws Exception {
+        testTouchEventPassToIme(/* longPress */ false);
+    }
+
+    @Test
+    public void testLongClickEventPassToIme() throws Exception {
+        testTouchEventPassToIme(/* longPress */ true);
+    }
+
+    private void testTouchEventPassToIme(boolean longPress) throws Exception {
+        final MockImeSession mockImeSession = sMockImeSessionRule.getMockImeSession();
+        assumeTrue("MockIME not available", mockImeSession != null);
+
+        // Set service.
+        enableService();
+
+        Intent intent = new Intent(mContext, DummyActivity.class);
+        PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
+
+        final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
+                .addDataset(new CannedFillResponse.CannedDataset.Builder()
+                        .setField(ID_USERNAME, "dude")
+                        .setPresentation(createPresentation("The Username"))
+                        .setInlinePresentation(longPress
+                                ? createInlinePresentation("The Username", pendingIntent)
+                                : createInlinePresentation("The Username"))
+                        .build());
+
+        sReplier.addResponse(builder.build());
+
+        final ImeEventStream stream = mockImeSession.openEventStream();
+
+        // Trigger auto-fill.
+        mUiBot.selectByRelativeId(ID_USERNAME);
+        mUiBot.waitForIdleSync();
+        sReplier.getNextFillRequest();
+
+        mUiBot.assertDatasets("The Username");
+
+        if (longPress) {
+            // Long click on suggestion
+            mUiBot.longPressSuggestion("The Username");
+
+            expectEvent(stream,
+                    event -> "onInlineSuggestionLongClickedEvent".equals(event.getEventName()),
+                    MOCK_IME_TIMEOUT_MS);
+        } else {
+            // Click on suggestion
+            mUiBot.selectDataset("The Username");
+
+            expectEvent(stream,
+                    event -> "onInlineSuggestionClickedEvent".equals(event.getEventName()),
+                    MOCK_IME_TIMEOUT_MS);
+        }
+    }
 }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java
index 915a9dc..0824c46 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/ActivityVisibilityTests.java
@@ -332,7 +332,7 @@
         mWmState.assertVisibility(MOVE_TASK_TO_BACK_ACTIVITY, true);
 
         // Launch a different activity on top.
-        launchActivity(BROADCAST_RECEIVER_ACTIVITY);
+        launchActivity(BROADCAST_RECEIVER_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
         mWmState.waitForActivityState(BROADCAST_RECEIVER_ACTIVITY, STATE_RESUMED);
         mWmState.waitForActivityState(MOVE_TASK_TO_BACK_ACTIVITY,STATE_STOPPED);
         final boolean shouldBeVisible =
@@ -478,6 +478,7 @@
                 .setIntentExtra(
                         extra -> extra.putBoolean(Components.TestActivity.EXTRA_NO_IDLE, true))
                 .setTargetActivity(TEST_ACTIVITY)
+                .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
                 .execute();
     }
 
@@ -552,7 +553,7 @@
         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
         lockScreenSession.sleepDevice();
         separateTestJournal();
-        launchActivity(TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY);
+        launchActivity(TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
         mWmState.assertVisibility(TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY, true);
         assertTrue("Display turns on", isDisplayOn(DEFAULT_DISPLAY));
         assertSingleLaunch(TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY);
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 7ddc020..3a71828 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
@@ -2201,8 +2201,15 @@
                         // Include stopped packages
                         .append(" -f 0x00000020");
             } else {
+                // If new task flag isn't set the windowing mode of launcher activity will be the
+                // windowing mode of the target activity, so we need to launch launcher activity in
+                // it.
+                String amStartCmd =
+                        (mWindowingMode == -1 || mNewTask)
+                                ? getAmStartCmd(mLaunchingActivity)
+                                : getAmStartCmd(mLaunchingActivity, mWindowingMode);
                 // Use launching activity to launch the target.
-                commandBuilder.append(getAmStartCmd(mLaunchingActivity))
+                commandBuilder.append(amStartCmd)
                         .append(" -f 0x20000020");
             }
 
diff --git a/tests/inputmethod/Android.bp b/tests/inputmethod/Android.bp
index 95d5fa1..6f07ac6 100644
--- a/tests/inputmethod/Android.bp
+++ b/tests/inputmethod/Android.bp
@@ -25,6 +25,7 @@
     libs: ["android.test.runner"],
     static_libs: [
         "androidx.test.rules",
+        "androidx.test.uiautomator_uiautomator",
         "compatibility-device-util-axt",
         "ctstestrunner-axt",
         "CtsMockInputMethodLib",
diff --git a/tests/inputmethod/AndroidTest.xml b/tests/inputmethod/AndroidTest.xml
index f1ec1e0..fd2ea5d 100644
--- a/tests/inputmethod/AndroidTest.xml
+++ b/tests/inputmethod/AndroidTest.xml
@@ -48,6 +48,24 @@
         <option name="run-command" value="wm dismiss-keyguard" />
     </target_preparer>
 
+    <!--
+        A (separate) standalone test app APK is needed to test implicit app-visibility from the IME
+        process to the IME target process, because if the IME target process is directly interacting
+        with MockIme process via MockImeSession, then the system would already give the MockIme an
+        implicit app-visibility back to the test app.  To fully test app-visibility scenario,
+        MockImeSession cannot be used in the process where the focused Activity is hosted.
+    -->
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <!--
+            In order to simulate the scenario where the IME client process is normally
+            installed, explicitly set false here.  Otherwise, the test APP will be installed under
+            force-queryable mode, which makes the test useless.
+        -->
+        <option name="force-queryable" value="false" />
+        <option name="test-file-name" value="CtsInputMethodStandaloneTestApp.apk" />
+    </target_preparer>
+
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsInputMethodTestCases.apk" />
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/ImeEvent.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/ImeEvent.java
index 808a972..abfae95 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/ImeEvent.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/ImeEvent.java
@@ -38,6 +38,7 @@
         Integer,
         String,
         CharSequence,
+        Exception,
         Parcelable,
     }
 
@@ -74,6 +75,9 @@
         if (object instanceof CharSequence) {
             return ReturnType.CharSequence;
         }
+        if (object instanceof Exception) {
+            return ReturnType.Exception;
+        }
         if (object instanceof Parcelable) {
             return ReturnType.Parcelable;
         }
@@ -143,6 +147,9 @@
             case CharSequence:
                 bundle.putCharSequence("mReturnValue", getReturnCharSequenceValue());
                 break;
+            case Exception:
+                bundle.putSerializable("mReturnValue", getReturnExceptionValue());
+                break;
             case Parcelable:
                 bundle.putParcelable("mReturnValue", getReturnParcelableValue());
                 break;
@@ -186,6 +193,9 @@
             case CharSequence:
                 result = bundle.getCharSequence("mReturnValue");
                 break;
+            case Exception:
+                result = bundle.getSerializable("mReturnValue");
+                break;
             case Parcelable:
                 result = bundle.getParcelable("mReturnValue");
                 break;
@@ -364,6 +374,25 @@
         return (String) mReturnValue;
     }
 
+     /**
+      * Retrieves a result that is known to be {@link Exception} or its subclasses.
+      *
+      * @param <T> {@link Exception} or its subclass.
+      * @return {@link Exception} object returned as a result of the command.
+      * @throws NullPointerException if the return value is {@code null}
+      * @throws ClassCastException if the return value is non-{@code null} object that is different
+      *                            from {@link Exception}
+     */
+    public <T extends Exception> T getReturnExceptionValue() {
+        if (mReturnType == ReturnType.Null) {
+            throw new NullPointerException();
+        }
+        if (mReturnType != ReturnType.Exception) {
+            throw new ClassCastException();
+        }
+        return (T) mReturnValue;
+    }
+
     /**
      * @return result value of this event.
      * @throws NullPointerException if the return value is {@code null}
@@ -380,6 +409,12 @@
         return (T) mReturnValue;
     }
 
+    /**
+     * @return {@code true} when the result value is an {@link Exception}.
+     */
+    public boolean isExceptionReturnValue() {
+        return mReturnType == ReturnType.Exception;
+    }
 
     /**
      * @return {@code true} when the result value is {@code null}.
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
index ba7262e..779bba8 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
@@ -25,6 +25,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.inputmethodservice.InputMethodService;
@@ -289,6 +290,15 @@
                         sendDownUpKeyEvents(keyEventCode);
                         return ImeEvent.RETURN_VALUE_UNAVAILABLE;
                     }
+                    case "getApplicationInfo": {
+                        final String packageName = command.getExtras().getString("packageName");
+                        final int flags = command.getExtras().getInt("flags");
+                        try {
+                            return getPackageManager().getApplicationInfo(packageName, flags);
+                        } catch (PackageManager.NameNotFoundException e) {
+                            return e;
+                        }
+                    }
                     case "getDisplayId":
                         return getDisplay().getDisplayId();
                     case "verifyLayoutInflaterContext":
@@ -809,6 +819,13 @@
                         suggestionView -> {
                             Log.d(TAG, "new inline suggestion view ready");
                             if (suggestionView != null) {
+                                suggestionView.setOnClickListener((v) -> {
+                                    getTracer().onInlineSuggestionClickedEvent(() -> { });
+                                });
+                                suggestionView.setOnLongClickListener((v) -> {
+                                    getTracer().onInlineSuggestionLongClickedEvent(() -> { });
+                                    return true;
+                                });
                                 pendingInlineSuggestions.mViews[index] = suggestionView;
                             }
                             if (pendingInlineSuggestions.mInflatedViewCount.incrementAndGet()
@@ -1068,5 +1085,15 @@
             return recordEventInternal("onInlineSuggestionsResponse", supplier::getAsBoolean,
                     arguments);
         }
+
+        void onInlineSuggestionClickedEvent(@NonNull Runnable runnable) {
+            final Bundle arguments = new Bundle();
+            recordEventInternal("onInlineSuggestionClickedEvent", runnable, arguments);
+        }
+
+        void onInlineSuggestionLongClickedEvent(@NonNull Runnable runnable) {
+            final Bundle arguments = new Bundle();
+            recordEventInternal("onInlineSuggestionLongClickedEvent", runnable, arguments);
+        }
     }
 }
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java
index b495e36..9a5eba8 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java
@@ -977,6 +977,27 @@
         return callCommandInternal("sendDownUpKeyEvents", params);
     }
 
+    /**
+     * Lets {@link MockIme} call
+     * {@link android.content.pm.PackageManager#getApplicationInfo(String, int)} with the given
+     * {@code packageName} and {@code flags}.
+     *
+     * @param packageName the package name to be passed to
+     *                    {@link android.content.pm.PackageManager#getApplicationInfo(String, int)}.
+     * @param flags the flags to be passed to
+     *                    {@link android.content.pm.PackageManager#getApplicationInfo(String, int)}.
+     * @return {@link ImeCommand} object that can be passed to
+     *         {@link ImeEventStreamTestUtils#expectCommand(ImeEventStream, ImeCommand, long)} to
+     *         wait until this event is handled by {@link MockIme}.
+     */
+    @NonNull
+    public ImeCommand callGetApplicationInfo(@NonNull String packageName, int flags) {
+        final Bundle params = new Bundle();
+        params.putString("packageName", packageName);
+        params.putInt("flags", flags);
+        return callCommandInternal("getApplicationInfo", params);
+    }
+
     @NonNull
     public ImeCommand callGetDisplayId() {
         final Bundle params = new Bundle();
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodStartInputLifecycleTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodStartInputLifecycleTest.java
index 23f32ce..fc724f8 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodStartInputLifecycleTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/InputMethodStartInputLifecycleTest.java
@@ -21,8 +21,10 @@
 import static android.view.View.VISIBLE;
 
 import static com.android.cts.mockime.ImeEventStreamTestUtils.editorMatcher;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectBindInput;
 import static com.android.cts.mockime.ImeEventStreamTestUtils.expectCommand;
 import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.notExpectEvent;
 
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
@@ -30,14 +32,19 @@
 import android.app.Instrumentation;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.inputmethodservice.InputMethodService;
+import android.os.IBinder;
+import android.os.Process;
 import android.os.SystemClock;
 import android.text.TextUtils;
+import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.cts.util.DisableScreenDozeRule;
 import android.view.inputmethod.cts.util.EndToEndImeTestBase;
 import android.view.inputmethod.cts.util.TestActivity;
 import android.view.inputmethod.cts.util.TestUtils;
 import android.view.inputmethod.cts.util.UnlockScreenRule;
+import android.view.inputmethod.cts.util.WindowFocusStealer;
 import android.widget.EditText;
 import android.widget.LinearLayout;
 
@@ -140,6 +147,79 @@
         }
     }
 
+    /**
+     * Test case for Bug 158624922 and Bug 152373385.
+     *
+     * Test {@link android.inputmethodservice.InputMethodService#onStartInput(EditorInfo, boolean)}
+     * and {@link InputMethodService#onFinishInput()} won't be called and the input connection
+     * remains active, even when a non-IME focusable window hosted by a different process
+     * temporarily becomes the focused window.
+     */
+    @Test
+    public void testNoStartNewInputWhileOtherProcessHasWindowFocus() throws Exception {
+        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        try (MockImeSession imeSession = MockImeSession.create(
+                instrumentation.getContext(),
+                instrumentation.getUiAutomation(),
+                new ImeSettings.Builder())) {
+            final ImeEventStream stream = imeSession.openEventStream();
+
+            final String marker = InputMethodStartInputLifecycleTest.class.getName() + "/"
+                    + SystemClock.elapsedRealtimeNanos();
+            final EditText editText = launchTestActivity(marker);
+            TestUtils.runOnMainSync(() -> editText.requestFocus());
+
+            // Wait until the MockIme gets bound to the TestActivity.
+            expectBindInput(stream, Process.myPid(), TIMEOUT);
+
+            expectEvent(stream, editorMatcher("onStartInput", marker), TIMEOUT);
+
+            // Get app window token
+            final IBinder appWindowToken = TestUtils.getOnMainSync(
+                    () -> editText.getApplicationWindowToken());
+
+            try (WindowFocusStealer focusStealer =
+                         WindowFocusStealer.connect(instrumentation.getTargetContext(), TIMEOUT)) {
+
+                focusStealer.stealWindowFocus(appWindowToken, TIMEOUT);
+
+                // Wait until the edit text loses window focus.
+                TestUtils.waitOnMainUntil(() -> !editText.hasWindowFocus(), TIMEOUT);
+            }
+            // Wait until the edit text gains window focus again.
+            TestUtils.waitOnMainUntil(() -> editText.hasWindowFocus(), TIMEOUT);
+
+            // Not expect the input connection will be started or finished even gaining non-IME
+            // focusable window focus.
+            notExpectEvent(stream, event -> "onFinishInput".equals(event.getEventName())
+                    || "onStartInput".equals(event.getEventName()), TIMEOUT);
+
+            // Verify the input connection of the EditText is still active and can accept text.
+            final InputMethodManager imm = editText.getContext().getSystemService(
+                    InputMethodManager.class);
+            assertTrue(TestUtils.getOnMainSync(() -> imm.isActive(editText)));
+            assertTrue(TestUtils.getOnMainSync(() -> imm.isAcceptingText()));
+        }
+    }
+
+    private EditText launchTestActivity(String marker) {
+        final AtomicReference<EditText> editTextRef = new AtomicReference<>();
+        TestActivity.startSync(activity-> {
+            final LinearLayout layout = new LinearLayout(activity);
+            layout.setOrientation(LinearLayout.VERTICAL);
+
+            final EditText editText = new EditText(activity);
+            editText.setPrivateImeOptions(marker);
+            editText.setHint("editText");
+            editText.requestFocus();
+            editTextRef.set(editText);
+
+            layout.addView(editText);
+            return layout;
+        });
+        return editTextRef.get();
+    }
+
     private static Predicate<ImeEvent> onFinishInputMatcher() {
         return event -> TextUtils.equals("onFinishInput", event.getEventName());
     }
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/PackageVisibilityTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/PackageVisibilityTest.java
new file mode 100644
index 0000000..7705c63
--- /dev/null
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/PackageVisibilityTest.java
@@ -0,0 +1,183 @@
+/*
+ * 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.view.inputmethod.cts;
+
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.editorMatcher;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectCommand;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AppModeInstant;
+import android.view.inputmethod.cts.util.EndToEndImeTestBase;
+import android.view.inputmethod.cts.util.UnlockScreenRule;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.test.filters.MediumTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import com.android.cts.mockime.ImeCommand;
+import com.android.cts.mockime.ImeEvent;
+import com.android.cts.mockime.ImeEventStream;
+import com.android.cts.mockime.ImeSettings;
+import com.android.cts.mockime.MockImeSession;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.security.InvalidParameterException;
+import java.util.concurrent.TimeUnit;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public final class PackageVisibilityTest extends EndToEndImeTestBase {
+    static final long TIMEOUT = TimeUnit.SECONDS.toMillis(5);
+
+    @Rule
+    public final UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
+
+    private static final ComponentName TEST_ACTIVITY = new ComponentName(
+            "android.view.inputmethod.ctstestapp",
+            "android.view.inputmethod.ctstestapp.MainActivity");
+
+    private static final Uri TEST_ACTIVITY_URI =
+            Uri.parse("https://example.com/android/view/inputmethod/ctstestapp");
+
+    private static final String EXTRA_KEY_PRIVATE_IME_OPTIONS =
+            "android.view.inputmethod.ctstestapp.EXTRA_KEY_PRIVATE_IME_OPTIONS";
+
+    private static final String TEST_MARKER_PREFIX =
+            "android.view.inputmethod.cts.PackageVisibilityTest";
+
+    private static String getTestMarker() {
+        return TEST_MARKER_PREFIX + "/"  + SystemClock.elapsedRealtimeNanos();
+    }
+
+    @NonNull
+    private static Uri formatStringIntentParam(@NonNull Uri uri, @NonNull String key,
+            @Nullable String value) {
+        if (value == null) {
+            return uri;
+        }
+        return uri.buildUpon().appendQueryParameter(key, value).build();
+    }
+
+    @NonNull
+    private static String formatStringIntentParam(@NonNull String key, @Nullable String value) {
+        if (key.matches("[ \"']")) {
+            throw new InvalidParameterException("Unsupported character(s) in key=" + key);
+        }
+        if (value.matches("[ \"']")) {
+            throw new InvalidParameterException("Unsupported character(s) in value=" + value);
+        }
+        return value != null ? String.format(" --es %s %s", key, value) : "";
+    }
+
+    /**
+     * Launch the standalone version of the test {@link android.app.Activity} then wait for
+     * completions of launch.
+     *
+     * <p>Note: this method does not use
+     * {@link android.app.Instrumentation#startActivitySync(Intent)} because it does not work when
+     * both the calling process and the target process run under the instant app mode. Instead this
+     * method relies on adb command {@code adb shell am start} to work around that limitation.</p>
+     *
+     * @param instant {@code true} if the caller and the target is installed as instant apps.
+     * @param privateImeOptions If not {@code null},
+     *                          {@link android.view.inputmethod.EditorInfo#privateImeOptions} will
+     *                          in the test {@link android.app.Activity} will be set to this value.
+     * @param timeout timeout in milliseconds.
+     */
+    private void launchTestActivity(boolean instant, @Nullable String privateImeOptions,
+            long timeout) {
+        final String command;
+        if (instant) {
+            final Uri uri = formatStringIntentParam(
+                    TEST_ACTIVITY_URI, EXTRA_KEY_PRIVATE_IME_OPTIONS, privateImeOptions);
+            command = String.format("am start -a %s -c %s %s",
+                    Intent.ACTION_VIEW, Intent.CATEGORY_BROWSABLE, uri.toString());
+        } else {
+            command = String.format("am start -n %s",
+                    TEST_ACTIVITY.flattenToShortString())
+                    + formatStringIntentParam(EXTRA_KEY_PRIVATE_IME_OPTIONS, privateImeOptions);
+        }
+        runShellCommand(command);
+        UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+                .wait(Until.hasObject(By.pkg(TEST_ACTIVITY.getPackageName()).depth(0)), timeout);
+    }
+
+    @AppModeFull
+    @Test
+    public void testTargetPackageIsVisibleFromImeFull() throws Exception {
+        testTargetPackageIsVisibleFromIme(false /* instant */);
+    }
+
+    @AppModeInstant
+    @Test
+    public void testTargetPackageIsVisibleFromImeInstant() throws Exception {
+        // We need to explicitly check this condition in case tests are executed with atest command.
+        // See Bug 158617529 for details.
+        assumeTrue("This test should run when and only under the instant app mode.",
+                InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager()
+                        .isInstantApp());
+        testTargetPackageIsVisibleFromIme(true /* instant */);
+    }
+
+    private void testTargetPackageIsVisibleFromIme(boolean instant) throws Exception {
+        try (MockImeSession imeSession = MockImeSession.create(
+                InstrumentationRegistry.getInstrumentation().getContext(),
+                InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+                new ImeSettings.Builder())) {
+            final ImeEventStream stream = imeSession.openEventStream();
+
+            final String marker = getTestMarker();
+            launchTestActivity(instant, marker, TIMEOUT);
+
+            expectEvent(stream, editorMatcher("onStartInput", marker), TIMEOUT);
+
+            final ImeCommand command = imeSession.callGetApplicationInfo(
+                    TEST_ACTIVITY.getPackageName(), PackageManager.GET_META_DATA);
+            final ImeEvent event = expectCommand(stream, command, TIMEOUT);
+
+            if (event.isNullReturnValue()) {
+                fail("getApplicationInfo() returned null.");
+            }
+            if (event.isExceptionReturnValue()) {
+                final Exception exception = event.getReturnExceptionValue();
+                fail(exception.toString());
+            }
+            final ApplicationInfo applicationInfoFromIme = event.getReturnParcelableValue();
+            assertEquals(TEST_ACTIVITY.getPackageName(), applicationInfoFromIme.packageName);
+        }
+    }
+}
diff --git a/tests/inputmethod/testapp/Android.bp b/tests/inputmethod/testapp/Android.bp
new file mode 100644
index 0000000..1d55077
--- /dev/null
+++ b/tests/inputmethod/testapp/Android.bp
@@ -0,0 +1,33 @@
+// 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: "CtsInputMethodStandaloneTestApp",
+    defaults: ["cts_defaults"],
+    sdk_version: "current",
+    // tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts10",
+        "general-tests",
+    ],
+    compile_multilib: "both",
+    static_libs: [
+        "androidx.annotation_annotation",
+    ],
+    srcs: [
+        "src/**/*.java",
+        "src/**/I*.aidl",
+    ],
+}
diff --git a/tests/inputmethod/testapp/AndroidManifest.xml b/tests/inputmethod/testapp/AndroidManifest.xml
new file mode 100644
index 0000000..0f474205
--- /dev/null
+++ b/tests/inputmethod/testapp/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?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="android.view.inputmethod.ctstestapp"
+    android:targetSandboxVersion="2">
+
+    <application
+        android:label="CtsInputMethodStandaloneTestApp"
+        android:multiArch="true"
+        android:supportsRtl="true">
+        <activity
+            android:name=".MainActivity"
+            android:exported="true"
+            android:label="CtsInputMethodStandaloneTestActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="https" />
+                <data android:host="example.com" />
+                <data android:path="/android/view/inputmethod/ctstestapp" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/tests/inputmethod/testapp/src/android/view/inputmethod/ctstestapp/MainActivity.java b/tests/inputmethod/testapp/src/android/view/inputmethod/ctstestapp/MainActivity.java
new file mode 100644
index 0000000..58d5c42
--- /dev/null
+++ b/tests/inputmethod/testapp/src/android/view/inputmethod/ctstestapp/MainActivity.java
@@ -0,0 +1,65 @@
+/*
+ * 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.view.inputmethod.ctstestapp;
+
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
+
+import android.app.Activity;
+import android.net.Uri;
+import android.os.Bundle;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+import androidx.annotation.Nullable;
+
+/**
+ * A test {@link Activity} that automatically shows the input method.
+ */
+public final class MainActivity extends Activity {
+
+    private static final String EXTRA_KEY_PRIVATE_IME_OPTIONS =
+            "android.view.inputmethod.ctstestapp.EXTRA_KEY_PRIVATE_IME_OPTIONS";
+
+    @Nullable
+    private String getPrivateImeOptions() {
+        if (getPackageManager().isInstantApp()) {
+            final Uri uri = getIntent().getData();
+            if (uri == null || !uri.isHierarchical()) {
+                return null;
+            }
+            return uri.getQueryParameter(EXTRA_KEY_PRIVATE_IME_OPTIONS);
+        }
+        return getIntent().getStringExtra(EXTRA_KEY_PRIVATE_IME_OPTIONS);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final LinearLayout layout = new LinearLayout(this);
+        layout.setOrientation(LinearLayout.VERTICAL);
+        final EditText editText = new EditText(this);
+        editText.setHint("editText");
+        final String privateImeOptions = getPrivateImeOptions();
+        if (privateImeOptions != null) {
+            editText.setPrivateImeOptions(privateImeOptions);
+        }
+        editText.requestFocus();
+        layout.addView(editText);
+        getWindow().setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+        setContentView(layout);
+    }
+}
diff --git a/tests/tests/graphics/jni/VulkanTestHelpers.cpp b/tests/tests/graphics/jni/VulkanTestHelpers.cpp
index 7092b86..b549b97 100644
--- a/tests/tests/graphics/jni/VulkanTestHelpers.cpp
+++ b/tests/tests/graphics/jni/VulkanTestHelpers.cpp
@@ -69,6 +69,29 @@
 
 } // namespace
 
+static bool enumerateDeviceExtensions(VkPhysicalDevice device,
+                                      std::vector<VkExtensionProperties>* extensions) {
+    VkResult result;
+
+    uint32_t count = 0;
+    result = vkEnumerateDeviceExtensionProperties(device, nullptr, &count, nullptr);
+    if (result != VK_SUCCESS) return false;
+
+    extensions->resize(count);
+    result = vkEnumerateDeviceExtensionProperties(device, nullptr, &count, extensions->data());
+    if (result != VK_SUCCESS) return false;
+
+    return true;
+}
+
+static bool hasExtension(const char* extension_name,
+                         const std::vector<VkExtensionProperties>& extensions) {
+    return std::find_if(extensions.cbegin(), extensions.cend(),
+                        [extension_name](const VkExtensionProperties& extension) {
+                            return strcmp(extension.extensionName, extension_name) == 0;
+                        }) != extensions.cend();
+}
+
 bool VkInit::init() {
   VkApplicationInfo appInfo = {
       .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
@@ -108,6 +131,12 @@
   ASSERT(status == VK_SUCCESS || status == VK_INCOMPLETE);
   ASSERT(gpuCount > 0);
 
+  std::vector<VkExtensionProperties> supportedDeviceExtensions;
+  ASSERT(enumerateDeviceExtensions(mGpu, &supportedDeviceExtensions));
+  for (const auto extension : deviceExt) {
+      ASSERT(hasExtension(extension, supportedDeviceExtensions));
+  }
+
   uint32_t queueFamilyCount = 0;
   vkGetPhysicalDeviceQueueFamilyProperties(mGpu, &queueFamilyCount, nullptr);
   ASSERT(queueFamilyCount != 0);
diff --git a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
index 167619c..d4df722 100644
--- a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
@@ -453,7 +453,7 @@
             }
         }
 
-        // Not all devices support AC4
+        // Not all devices support AC4.
         if (ac4TrackIndex == -1) {
             List<AudioPresentation> presentations =
                     mExtractor.getAudioPresentations(0 /*trackIndex*/);
diff --git a/tests/tests/os/Android.mk b/tests/tests/os/Android.mk
index 632acf5..af8767f 100644
--- a/tests/tests/os/Android.mk
+++ b/tests/tests/os/Android.mk
@@ -14,6 +14,8 @@
 
 # platform version check (b/32056228)
 # ============================================================
+LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := cts-platform-version-check
diff --git a/tests/tests/os/AutoRevokePreRApp/Android.bp b/tests/tests/os/AutoRevokePreRApp/Android.bp
new file mode 100644
index 0000000..254f9eb
--- /dev/null
+++ b/tests/tests/os/AutoRevokePreRApp/Android.bp
@@ -0,0 +1,30 @@
+//
+// 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: "CtsAutoRevokePreRApp",
+    defaults: ["cts_defaults"],
+    sdk_version: "test_current",
+    // Tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "vts",
+        "vts10",
+        "mts",
+        "general-tests",
+    ],
+    srcs: ["src/**/*.java", "src/**/*.kt"],
+}
diff --git a/tests/tests/os/AutoRevokePreRApp/AndroidManifest.xml b/tests/tests/os/AutoRevokePreRApp/AndroidManifest.xml
new file mode 100644
index 0000000..972a19f
--- /dev/null
+++ b/tests/tests/os/AutoRevokePreRApp/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="android.os.cts.autorevokeprerapp">
+
+    <uses-permission android:name="android.permission.READ_CALENDAR" />
+
+    <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" />
+    <application>
+        <activity android:name="android.os.cts.autorevokeprerapp.MainActivity"
+                  android:exported="true"
+                  android:visibleToInstantApps="true" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
+
diff --git a/tests/tests/os/AutoRevokePreRApp/src/android/os/cts/autorevokeprerapp/MainActivity.kt b/tests/tests/os/AutoRevokePreRApp/src/android/os/cts/autorevokeprerapp/MainActivity.kt
new file mode 100644
index 0000000..ad4066b
--- /dev/null
+++ b/tests/tests/os/AutoRevokePreRApp/src/android/os/cts/autorevokeprerapp/MainActivity.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.os.cts.autorevokeprerapp
+
+import android.app.Activity
+import android.os.Bundle
+
+class MainActivity : Activity() {
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        requestPermissions(arrayOf("android.permission.READ_CALENDAR"), 0)
+    }
+}
diff --git a/tests/tests/os/CtsOsTestCases.xml b/tests/tests/os/CtsOsTestCases.xml
index 193eb0f..72902e68 100644
--- a/tests/tests/os/CtsOsTestCases.xml
+++ b/tests/tests/os/CtsOsTestCases.xml
@@ -46,5 +46,6 @@
     <!-- Load additional APKs onto device -->
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
         <option name="push" value="CtsAutoRevokeDummyApp.apk->/data/local/tmp/cts/os/CtsAutoRevokeDummyApp.apk" />
+        <option name="push" value="CtsAutoRevokePreRApp.apk->/data/local/tmp/cts/os/CtsAutoRevokePreRApp.apk" />
     </target_preparer>
 </configuration>
diff --git a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
index 357e9c7..eb25347 100644
--- a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
+++ b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
@@ -31,10 +31,17 @@
 import android.test.InstrumentationTestCase
 import android.view.accessibility.AccessibilityNodeInfo
 import android.widget.Switch
-import com.android.compatibility.common.util.*
 import com.android.compatibility.common.util.textAsString
 import com.android.compatibility.common.util.MatcherUtils.hasTextThat
-import com.android.compatibility.common.util.SystemUtil.*
+import com.android.compatibility.common.util.SystemUtil
+import com.android.compatibility.common.util.SystemUtil.runShellCommand
+import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
+import com.android.compatibility.common.util.ThrowingSupplier
+import com.android.compatibility.common.util.UiAutomatorUtils
+import com.android.compatibility.common.util.click
+import com.android.compatibility.common.util.depthFirstSearch
+import com.android.compatibility.common.util.lowestCommonAncestor
+import com.android.compatibility.common.util.uiDump
 import org.hamcrest.CoreMatchers.containsString
 import org.hamcrest.CoreMatchers.containsStringIgnoringCase
 import org.hamcrest.Matcher
@@ -46,6 +53,8 @@
 
 private const val APK_PATH = "/data/local/tmp/cts/os/CtsAutoRevokeDummyApp.apk"
 private const val APK_PACKAGE_NAME = "android.os.cts.autorevokedummyapp"
+private const val APK_PATH_2 = "/data/local/tmp/cts/os/CtsAutoRevokePreRApp.apk"
+private const val APK_PACKAGE_NAME_2 = "android.os.cts.autorevokeprerapp"
 private const val READ_CALENDAR = "android.permission.READ_CALENDAR"
 
 /**
@@ -105,7 +114,7 @@
 
                 // Run
                 runAutoRevoke()
-                Thread.sleep(500)
+                Thread.sleep(1000)
 
                 // Verify
                 assertPermission(PERMISSION_GRANTED)
@@ -114,6 +123,47 @@
     }
 
     @AppModeFull(reason = "Uses separate apps for testing")
+    fun testPreRUnusedApp_doesntGetPermissionRevoked() {
+        wakeUpScreen()
+        withUnusedThresholdMs(3L) {
+            withDummyApp(APK_PATH_2, APK_PACKAGE_NAME_2) {
+                withDummyApp {
+                    startApp(APK_PACKAGE_NAME_2)
+                    clickPermissionAllow()
+                    eventually {
+                        assertPermission(PERMISSION_GRANTED, APK_PACKAGE_NAME_2)
+                    }
+
+                    goBack()
+                    goHome()
+                    goBack()
+
+                    startApp()
+                    clickPermissionAllow()
+                    eventually {
+                        assertPermission(PERMISSION_GRANTED)
+                    }
+
+                    goBack()
+                    goHome()
+                    goBack()
+                    Thread.sleep(20)
+
+                    // Run
+                    runAutoRevoke()
+                    Thread.sleep(500)
+
+                    // Verify
+                    eventually {
+                        assertPermission(PERMISSION_DENIED)
+                        assertPermission(PERMISSION_GRANTED, APK_PACKAGE_NAME_2)
+                    }
+                }
+            }
+        }
+    }
+
+    @AppModeFull(reason = "Uses separate apps for testing")
     fun testAutoRevoke_userWhitelisting() {
         wakeUpScreen()
         withUnusedThresholdMs(4L) {
@@ -284,7 +334,8 @@
         runWithShellPermissionIdentity {
             assertEquals(
                 permissionStateToString(state),
-                permissionStateToString(context.packageManager.checkPermission(READ_CALENDAR, APK_PACKAGE_NAME)))
+                permissionStateToString(
+                        context.packageManager.checkPermission(READ_CALENDAR, packageName)))
         }
     }
 
diff --git a/tests/tests/permission/src/android/permission/cts/NoActivityRelatedPermissionTest.java b/tests/tests/permission/src/android/permission/cts/NoActivityRelatedPermissionTest.java
index 4ae88c8..835ba12 100644
--- a/tests/tests/permission/src/android/permission/cts/NoActivityRelatedPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/NoActivityRelatedPermissionTest.java
@@ -53,21 +53,23 @@
         ActivityManager manager = (ActivityManager) getActivity()
                 .getSystemService(Context.ACTIVITY_SERVICE);
         List<ActivityManager.RunningTaskInfo> runningTasks =  manager.getRunningTasks(10);
-        // Current implementation should only return tasks for home and the caller.
-        // We'll be done and task this to mean it shouldn't return more than 2.
+        // Current implementation should only return tasks for home and the caller. Since there can
+        // be multiple home tasks, we remove them from the list and then check that there is one or
+        // less task left in the list.
+        removeHomeRunningTasks(runningTasks);
         assertTrue("Found tasks: " + runningTasks,
-                runningTasks == null || runningTasks.size() <= 2);
+                runningTasks == null || runningTasks.size() <= 1);
 
         List<ActivityManager.RecentTaskInfo> recentTasks = manager.getRecentTasks(10,
                 ActivityManager.RECENT_WITH_EXCLUDED);
         // Current implementation should only return tasks for home and the caller. Since there can
         // be multiple home tasks, we remove them from the list and then check that there is one or
         // less task left in the list.
-        removeHomeTasks(recentTasks);
+        removeHomeRecentsTasks(recentTasks);
         assertTrue("Found tasks: " + recentTasks, recentTasks == null || recentTasks.size() <= 1);
     }
 
-    private void removeHomeTasks(List<ActivityManager.RecentTaskInfo> tasks) {
+    private void removeHomeRecentsTasks(List<ActivityManager.RecentTaskInfo> tasks) {
         for (int i = tasks.size() -1; i >= 0; i--) {
             ActivityManager.RecentTaskInfo task = tasks.get(i);
             if (task.baseIntent != null && isHomeIntent(task.baseIntent)) {
@@ -76,9 +78,19 @@
         }
     }
 
+    private void removeHomeRunningTasks(List<ActivityManager.RunningTaskInfo> tasks) {
+        for (int i = tasks.size() -1; i >= 0; i--) {
+            ActivityManager.RunningTaskInfo task = tasks.get(i);
+            if (task.baseIntent != null && isHomeIntent(task.baseIntent)) {
+                tasks.remove(i);
+            }
+        }
+    }
+
     private boolean isHomeIntent(Intent intent) {
         return Intent.ACTION_MAIN.equals(intent.getAction())
-                && intent.hasCategory(Intent.CATEGORY_HOME)
+                && (intent.hasCategory(Intent.CATEGORY_HOME)
+                || intent.hasCategory(Intent.CATEGORY_SECONDARY_HOME))
                 && intent.getCategories().size() == 1
                 && intent.getData() == null
                 && intent.getType() == null;
diff --git a/tests/tests/permission/src/android/permission/cts/RevokePermissionTest.kt b/tests/tests/permission/src/android/permission/cts/RevokePermissionTest.kt
new file mode 100644
index 0000000..1d7e719
--- /dev/null
+++ b/tests/tests/permission/src/android/permission/cts/RevokePermissionTest.kt
@@ -0,0 +1,177 @@
+/*
+ * 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.permission.cts
+
+import android.Manifest.permission.CAMERA
+import android.Manifest.permission.READ_CALENDAR
+import android.content.pm.PackageManager
+import android.content.pm.PackageManager.PERMISSION_GRANTED
+import android.os.Process
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.compatibility.common.util.SystemUtil.runShellCommand
+import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+
+class RevokePermissionTest {
+
+    private val APP_PKG_NAME = "android.permission.cts.appthatrequestcustompermission"
+    private val APK = "/data/local/tmp/cts/permissions/" +
+            "CtsAppThatRequestsCalendarContactsBodySensorCustomPermission.apk"
+
+    @Before
+    fun installApp() {
+        runShellCommand("pm install -r -g $APK")
+    }
+
+    @Test
+    fun testRevokePermission() {
+        testRevoke(
+                packageName = APP_PKG_NAME,
+                permission = READ_CALENDAR,
+                isGranted = true)
+    }
+
+    @Test
+    fun testRevokePermissionNotRequested() {
+        testRevoke(
+                packageName = APP_PKG_NAME,
+                permission = CAMERA,
+                throwableType = SecurityException::class.java,
+                throwableMessage = "has not requested permission")
+    }
+
+    @Test
+    fun testRevokeFakePermission() {
+        val fakePermissionName = "FAKE_PERMISSION"
+        testRevoke(
+                packageName = APP_PKG_NAME,
+                permission = fakePermissionName,
+                throwableType = java.lang.IllegalArgumentException::class.java,
+                throwableMessage = "Unknown permission: $fakePermissionName")
+    }
+
+    @Test
+    fun testRevokeFakePackage() {
+        val fakePackageName = "fake.package.name.which.should.not.exist"
+        assertPackageNotInstalled(fakePackageName)
+        testRevoke(
+                packageName = fakePackageName,
+                permission = READ_CALENDAR)
+    }
+
+    @Test
+    fun testRevokePermissionWithReason() {
+        testRevoke(
+                packageName = APP_PKG_NAME,
+                permission = READ_CALENDAR,
+                reason = "test reason",
+                isGranted = true)
+    }
+
+    @Test
+    fun testRevokePermissionNotRequestedWithReason() {
+        testRevoke(
+                packageName = APP_PKG_NAME,
+                permission = CAMERA,
+                reason = "test reason",
+                throwableType = SecurityException::class.java,
+                throwableMessage = "has not requested permission")
+    }
+
+    @Test
+    fun testRevokeFakePermissionWithReason() {
+        val fakePermissionName = "FAKE_PERMISSION"
+        testRevoke(
+                packageName = APP_PKG_NAME,
+                permission = fakePermissionName,
+                reason = "test reason",
+                throwableType = java.lang.IllegalArgumentException::class.java,
+                throwableMessage = "Unknown permission: $fakePermissionName")
+    }
+
+    @Test
+    fun testRevokeFakePackageWithReason() {
+        val fakePackageName = "fake.package.name.which.should.not.exist"
+        assertPackageNotInstalled(fakePackageName)
+        testRevoke(
+                packageName = fakePackageName,
+                permission = READ_CALENDAR,
+                reason = "test reason")
+    }
+
+    @After
+    fun uninstallApp() {
+        runShellCommand("pm uninstall $APP_PKG_NAME")
+    }
+
+    private fun testRevoke(
+        packageName: String,
+        permission: String,
+        reason: String? = null,
+        isGranted: Boolean = false,
+        throwableType: Class<*>? = null,
+        throwableMessage: String = ""
+    ) {
+        val context = InstrumentationRegistry.getInstrumentation().targetContext
+        val pm = context.packageManager
+
+        if (isGranted) {
+            assertEquals(PERMISSION_GRANTED, pm.checkPermission(READ_CALENDAR, APP_PKG_NAME))
+        }
+
+        runWithShellPermissionIdentity {
+            if (throwableType == null) {
+                if (reason == null) {
+                    pm.revokeRuntimePermission(packageName, permission, Process.myUserHandle())
+                } else {
+                    pm.revokeRuntimePermission(packageName, permission, Process.myUserHandle(),
+                            reason)
+                }
+            } else {
+                try {
+                    if (reason == null) {
+                        pm.revokeRuntimePermission(packageName, permission, Process.myUserHandle())
+                    } else {
+                        pm.revokeRuntimePermission(packageName, permission, Process.myUserHandle(),
+                                reason)
+                    }
+                } catch (t: Throwable) {
+                    if (t::class.java.name == throwableType.name &&
+                            t.message!!.contains(throwableMessage)) {
+                        return@runWithShellPermissionIdentity
+                    }
+                    throw RuntimeException("Unexpected throwable", t)
+                }
+                throw RuntimeException("revokeRuntimePermission expected to throw.")
+            }
+        }
+    }
+
+    private fun assertPackageNotInstalled(packageName: String) {
+        val context = InstrumentationRegistry.getInstrumentation().targetContext
+        val pm = context.packageManager
+        try {
+            pm.getPackageInfo(packageName, 0)
+            throw RuntimeException("$packageName exists on this device")
+        } catch (e: PackageManager.NameNotFoundException) {
+            // Expected
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/view/res/layout/focus_finder_layout.xml b/tests/tests/view/res/layout/focus_finder_layout.xml
index 1dea684..4e2726c 100644
--- a/tests/tests/view/res/layout/focus_finder_layout.xml
+++ b/tests/tests/view/res/layout/focus_finder_layout.xml
@@ -46,7 +46,11 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_below="@id/layout">
-
+        <android.view.cts.TestButton
+            android:id="@+id/bottom_button"
+            android:layout_width="60dp"
+            android:layout_height="match_parent"
+            android:text="B" />
     </LinearLayout>
 </RelativeLayout>
 
diff --git a/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java b/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java
index ae0b4bf..300d3a5 100644
--- a/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/FocusFinderCtsActivity.java
@@ -25,6 +25,8 @@
 
     public ViewGroup layout;
 
+    public ViewGroup inflateLayout;
+
     public Button topLeftButton;
 
     public Button topRightButton;
@@ -33,15 +35,19 @@
 
     public Button bottomRightButton;
 
+    public Button bottomButton;
+
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         setContentView(R.layout.focus_finder_layout);
         layout = (ViewGroup) findViewById(R.id.layout);
+        inflateLayout = (ViewGroup) findViewById(R.id.inflate_layout);
         topLeftButton = (Button) findViewById(R.id.top_left_button);
         topRightButton = (Button) findViewById(R.id.top_right_button);
         bottomLeftButton = (Button) findViewById(R.id.bottom_left_button);
         bottomRightButton = (Button) findViewById(R.id.bottom_right_button);
+        bottomButton = (Button) findViewById(R.id.bottom_button);
     }
 }
 
diff --git a/tests/tests/view/src/android/view/cts/FocusFinderTest.java b/tests/tests/view/src/android/view/cts/FocusFinderTest.java
index 11e921a..53992ce 100644
--- a/tests/tests/view/src/android/view/cts/FocusFinderTest.java
+++ b/tests/tests/view/src/android/view/cts/FocusFinderTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
@@ -44,10 +45,12 @@
 public class FocusFinderTest {
     private FocusFinder mFocusFinder;
     private ViewGroup mLayout;
+    private ViewGroup mInflateLayout;
     private Button mTopLeft;
     private Button mTopRight;
     private Button mBottomLeft;
     private Button mBottomRight;
+    private Button mBottom;
 
     @Rule
     public ActivityTestRule<FocusFinderCtsActivity> mActivityRule =
@@ -59,14 +62,17 @@
 
         mFocusFinder = FocusFinder.getInstance();
         mLayout = activity.layout;
+        mInflateLayout = activity.inflateLayout;
         mTopLeft = activity.topLeftButton;
         mTopRight = activity.topRightButton;
         mBottomLeft = activity.bottomLeftButton;
         mBottomRight = activity.bottomRightButton;
+        mBottom = activity.bottomButton;
         mTopLeft.setNextFocusLeftId(View.NO_ID);
         mTopRight.setNextFocusLeftId(View.NO_ID);
         mBottomLeft.setNextFocusLeftId(View.NO_ID);
         mBottomRight.setNextFocusLeftId(View.NO_ID);
+        mBottom.setNextFocusLeftId(View.NO_ID);
     }
 
     @Test
@@ -456,4 +462,17 @@
         view.setRight(right);
         view.setBottom(bottom);
     }
+
+    @Test
+    public void testFindNextFocusDoesNotReturnItself() {
+        View nextFocus = mFocusFinder.findNextFocus(mInflateLayout, mBottom, View.FOCUS_FORWARD);
+        assertNull(nextFocus);
+    }
+
+    @Test
+    public void testFindPreviousFocusDoesNotReturnItself() {
+        View previousFocus =
+                mFocusFinder.findNextFocus(mInflateLayout, mBottom, View.FOCUS_BACKWARD);
+        assertNull(previousFocus);
+    }
 }
diff --git a/tests/tests/view/src/android/view/cts/TextureViewTest.java b/tests/tests/view/src/android/view/cts/TextureViewTest.java
index 9cab157..8736f36 100644
--- a/tests/tests/view/src/android/view/cts/TextureViewTest.java
+++ b/tests/tests/view/src/android/view/cts/TextureViewTest.java
@@ -81,7 +81,7 @@
         mActivityRule.runOnUiThread(() -> {
             View content = activity.findViewById(android.R.id.content);
             int[] outLocation = new int[2];
-            content.getLocationOnScreen(outLocation);
+            content.getLocationInWindow(outLocation);
             center.x = outLocation[0] + (content.getWidth() / 2);
             center.y = outLocation[1] + (content.getHeight() / 2);
             windowRet[0] = activity.getWindow();
@@ -145,7 +145,7 @@
         final Rect viewPos = new Rect();
         mActivityRule.runOnUiThread(() -> {
             int[] outLocation = new int[2];
-            textureView.getLocationOnScreen(outLocation);
+            textureView.getLocationInWindow(outLocation);
             viewPos.left = outLocation[0];
             viewPos.top = outLocation[1];
             viewPos.right = viewPos.left + textureView.getWidth();
@@ -187,7 +187,7 @@
         final Rect viewPos = new Rect();
         mActivityRule.runOnUiThread(() -> {
             int[] outLocation = new int[2];
-            textureView.getLocationOnScreen(outLocation);
+            textureView.getLocationInWindow(outLocation);
             viewPos.left = outLocation[0];
             viewPos.top = outLocation[1];
             viewPos.right = viewPos.left + textureView.getWidth();
@@ -343,7 +343,7 @@
             final Rect viewPos = new Rect();
             mActivityRule.runOnUiThread(() -> {
                 int[] outLocation = new int[2];
-                textureView.getLocationOnScreen(outLocation);
+                textureView.getLocationInWindow(outLocation);
                 viewPos.left = outLocation[0];
                 viewPos.top = outLocation[1];
                 viewPos.right = viewPos.left + textureView.getWidth();