Merge "Merge "Changing Requirement#checkPerformanceClass to ignore if given devicePerfClass is not handled by a required meausrement" am: c8048b1933 am: 0a79c3ec4f" into tm-dev
diff --git a/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java b/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java
index 8deeb76..12fbb3c 100644
--- a/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java
+++ b/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java
@@ -73,6 +73,7 @@
         EXCEPTION_PATTERNS.add(":: 1002");          // used by remote control
         EXCEPTION_PATTERNS.add(":: 1020");          // used by remote control
         EXCEPTION_PATTERNS.add("0.0.0.0:7275");     // used by supl
+        EXCEPTION_PATTERNS.add("0.0.0.0:68");       // DHCP server for Tethering
         // b/150186547 ports
         EXCEPTION_PATTERNS.add("192.168.17.10:48881");
         EXCEPTION_PATTERNS.add("192.168.17.10:48896");
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 daccbb0..fc4c05e 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
@@ -426,6 +426,10 @@
                             return e;
                         }
                     }
+                    case "setEnableOnBackInvokedCallback":
+                        boolean isEnabled = command.getExtras().getBoolean("isEnabled");
+                        getApplicationInfo().setEnableOnBackInvokedCallback(isEnabled);
+                        return ImeEvent.RETURN_VALUE_UNAVAILABLE;
                     case "getDisplayId":
                         return getDisplay().getDisplayId();
                     case "verifyLayoutInflaterContext":
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 c5ef7d0..3654a15 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockImeSession.java
@@ -1405,6 +1405,13 @@
     }
 
     @NonNull
+    public ImeCommand callSetEnableOnBackInvokedCallback(Boolean isEnabled) {
+        final Bundle params = new Bundle();
+        params.putBoolean("isEnabled", isEnabled);
+        return callCommandInternal("setEnableOnBackInvokedCallback", params);
+    }
+
+    @NonNull
     public ImeCommand callGetDisplayId() {
         final Bundle params = new Bundle();
         return callCommandInternal("getDisplayId", params);
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
index 3591ffa..ac95dc8 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/KeyboardVisibilityControlTest.java
@@ -244,6 +244,76 @@
         }
     }
 
+    private void verifyHideImeBackPressed(
+            boolean appRequestsLegacy, boolean imeRequestsLegacy) throws Exception {
+        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        final InputMethodManager imm = InstrumentationRegistry.getInstrumentation()
+                .getTargetContext().getSystemService(InputMethodManager.class);
+
+        try (MockImeSession imeSession = MockImeSession.create(
+                instrumentation.getContext(),
+                instrumentation.getUiAutomation(),
+                new ImeSettings.Builder())) {
+            final ImeEventStream stream = imeSession.openEventStream();
+
+            final String marker = getTestMarker();
+            final EditText editText = launchTestActivity(marker);
+            final TestActivity testActivity = (TestActivity) editText.getContext();
+            if (appRequestsLegacy) {
+                testActivity.getApplicationInfo().setEnableOnBackInvokedCallback(true);
+                testActivity.setIgnoreBackKey(true);
+            }
+            if (imeRequestsLegacy) {
+                imeSession.callSetEnableOnBackInvokedCallback(true);
+            }
+
+            expectEvent(stream, editorMatcher("onStartInput", marker), TIMEOUT);
+            notExpectEvent(stream, editorMatcher("onStartInputView", marker), TIMEOUT);
+            expectImeInvisible(TIMEOUT);
+
+            assertTrue("isActive() must return true if the View has IME focus",
+                    getOnMainSync(() -> imm.isActive(editText)));
+
+            // Test showSoftInput() flow
+            assertTrue("showSoftInput must success if the View has IME focus",
+                    getOnMainSync(() -> imm.showSoftInput(editText, 0)));
+
+            expectEvent(stream, showSoftInputMatcher(InputMethod.SHOW_EXPLICIT), TIMEOUT);
+            expectEvent(stream, editorMatcher("onStartInputView", marker), TIMEOUT);
+            expectEventWithKeyValue(stream, "onWindowVisibilityChanged", "visible",
+                    View.VISIBLE, TIMEOUT);
+            expectImeVisible(TIMEOUT);
+
+            // Pressing back key, expect soft-keyboard will become invisible.
+            instrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
+            expectEvent(stream, hideSoftInputMatcher(), TIMEOUT);
+            expectEvent(stream, onFinishInputViewMatcher(false), TIMEOUT);
+            expectEventWithKeyValue(stream, "onWindowVisibilityChanged", "visible",
+                    View.GONE, TIMEOUT);
+            expectImeInvisible(TIMEOUT);
+        }
+    }
+
+    @Test
+    public void testHideImeAfterBackPressed_legacyAppLegacyIme() throws Exception {
+        verifyHideImeBackPressed(true /* appRequestsLegacy */, true /* imeRequestsLegacy */);
+    }
+
+    @Test
+    public void testHideImeAfterBackPressed_migratedAppLegacyIme() throws Exception {
+        verifyHideImeBackPressed(false /* appRequestsLegacy */, true /* imeRequestsLegacy */);
+    }
+
+    @Test
+    public void testHideImeAfterBackPressed_migratedAppMigratedIme() throws Exception {
+        verifyHideImeBackPressed(false /* appRequestsLegacy */, false /* imeRequestsLegacy */);
+    }
+
+    @Test
+    public void testHideImeAfterBackPressed_legacyAppMigratedIme() throws Exception {
+        verifyHideImeBackPressed(true /* appRequestsLegacy */, false /* imeRequestsLegacy */);
+    }
+
     @Test
     public void testShowHideSoftInputShouldBeIgnoredOnNonFocusedView() throws Exception {
         final InputMethodManager imm = InstrumentationRegistry.getInstrumentation()
diff --git a/tests/inputmethod/util/src/android/view/inputmethod/cts/util/TestActivity.java b/tests/inputmethod/util/src/android/view/inputmethod/cts/util/TestActivity.java
index 66ef1e2..2b12a3c 100644
--- a/tests/inputmethod/util/src/android/view/inputmethod/cts/util/TestActivity.java
+++ b/tests/inputmethod/util/src/android/view/inputmethod/cts/util/TestActivity.java
@@ -31,6 +31,8 @@
 import android.view.Window;
 import android.view.WindowManager;
 import android.widget.TextView;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
 
 import androidx.annotation.AnyThread;
 import androidx.annotation.NonNull;
@@ -56,6 +58,10 @@
     private long mOnBackPressedCallCount;
 
     private TextView mOverlayView;
+    private OnBackInvokedCallback mIgnoreBackKeyCallback = () -> {
+        // Ignore back.
+    };
+    private Boolean mIgnoreBackKeyCallbackRegistered = false;
 
     /**
      * Controls how {@link #onBackPressed()} behaves.
@@ -69,6 +75,19 @@
     @AnyThread
     public void setIgnoreBackKey(boolean ignore) {
         mIgnoreBackKey.set(ignore);
+        if (ignore) {
+            if (!mIgnoreBackKeyCallbackRegistered) {
+                getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
+                        OnBackInvokedDispatcher.PRIORITY_DEFAULT, mIgnoreBackKeyCallback);
+                mIgnoreBackKeyCallbackRegistered = true;
+            }
+        } else {
+            if (mIgnoreBackKeyCallbackRegistered) {
+                getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(
+                        mIgnoreBackKeyCallback);
+                mIgnoreBackKeyCallbackRegistered = false;
+            }
+        }
     }
 
     @UiThread
@@ -102,6 +121,10 @@
                     .getSystemService(WindowManager.class).removeView(mOverlayView);
             mOverlayView = null;
         }
+        if (mIgnoreBackKeyCallbackRegistered) {
+            getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mIgnoreBackKeyCallback);
+            mIgnoreBackKeyCallbackRegistered = false;
+        }
     }
 
     /**
diff --git a/tests/quickaccesswallet/src/android/quickaccesswallet/cts/QuickAccessWalletClientTest.java b/tests/quickaccesswallet/src/android/quickaccesswallet/cts/QuickAccessWalletClientTest.java
index 8a5d528..0e794d0 100755
--- a/tests/quickaccesswallet/src/android/quickaccesswallet/cts/QuickAccessWalletClientTest.java
+++ b/tests/quickaccesswallet/src/android/quickaccesswallet/cts/QuickAccessWalletClientTest.java
@@ -28,6 +28,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
+import android.platform.test.annotations.AppModeFull;
 import android.provider.Settings;
 import android.quickaccesswallet.NoPermissionQuickAccessWalletService;
 import android.quickaccesswallet.QuickAccessWalletActivity;
@@ -69,6 +70,7 @@
  * Tests parceling of the {@link WalletCard}
  */
 @RunWith(AndroidJUnit4.class)
+@AppModeFull
 public class QuickAccessWalletClientTest {
 
     private static final String SETTING_KEY = "lockscreen_show_wallet";
diff --git a/tests/translation/AndroidManifest.xml b/tests/translation/AndroidManifest.xml
index aab6515..80ac551 100644
--- a/tests/translation/AndroidManifest.xml
+++ b/tests/translation/AndroidManifest.xml
@@ -22,10 +22,16 @@
     <application android:label="Translation TestCase">
         <uses-library android:name="android.test.runner"/>
 
+        <!--
+        EmptyActivity uses a transparent theme so that SimpleActivity below it can have its views
+        translated. See UiTranslationManagerTest#testTranslationAfterStartActivityOnSameTask.
+        -->
         <activity android:name=".EmptyActivity"
                   android:label="EmptyActivity"
-                  android:exported="true">
+                  android:exported="true"
+                  android:theme="@style/TransparentTheme">
         </activity>
+
         <activity android:name=".SimpleActivity"
                   android:label="SimpleActivity"
                   android:exported="true">
diff --git a/tests/translation/res/values/styles.xml b/tests/translation/res/values/styles.xml
new file mode 100644
index 0000000..3dd2eb6
--- /dev/null
+++ b/tests/translation/res/values/styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources>
+    <style name="TransparentTheme">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:backgroundDimEnabled">false</item>
+    </style>
+</resources>
\ No newline at end of file