Merge "Make STEM_PRIMARY gestures executable when they are intercepted at queueing stage." into main
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 775a361..25e4116 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4995,6 +4995,14 @@
                 }
                 break;
             }
+            case KeyEvent.KEYCODE_STEM_PRIMARY: {
+                if (down && event.getRepeatCount() == 0 && (result & ACTION_PASS_TO_USER) == 0) {
+                    // We've decided not to pass key to user at queueing stage. Make the gesture
+                    // executable.
+                    setDeferredKeyActionsExecutableAsync(keyCode, event.getDownTime());
+                }
+                break;
+            }
             case KeyEvent.KEYCODE_VIDEO_APP_1:
             case KeyEvent.KEYCODE_VIDEO_APP_2:
             case KeyEvent.KEYCODE_VIDEO_APP_3:
diff --git a/services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java b/services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java
index 50d37ec..77e7a0a 100644
--- a/services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/StemKeyGestureTests.java
@@ -34,6 +34,7 @@
 import android.content.ComponentName;
 import android.os.RemoteException;
 import android.provider.Settings;
+import android.view.Display;
 
 import org.junit.Test;
 
@@ -104,6 +105,27 @@
     }
 
     @Test
+    public void stemSingleKey_launchTargetActivity_whenScreenIsOff() {
+        overrideBehavior(
+                STEM_PRIMARY_BUTTON_SHORT_PRESS,
+                SHORT_PRESS_PRIMARY_LAUNCH_TARGET_ACTIVITY);
+        setUpPhoneWindowManager(/* supportSettingsUpdate= */ true);
+        mPhoneWindowManager.overrideShouldEarlyShortPressOnStemPrimary(false);
+        mPhoneWindowManager.overrideStartActivity();
+        mPhoneWindowManager.setKeyguardServiceDelegateIsShowing(false);
+        mPhoneWindowManager.overrideIsUserSetupComplete(true);
+        mPhoneWindowManager.assumeResolveActivityNotNull();
+        mPhoneWindowManager.overrideDisplayState(Display.STATE_OFF);
+        ComponentName targetComponent = ComponentName.unflattenFromString(TEST_TARGET_ACTIVITY);
+        mPhoneWindowManager.overrideStemPressTargetActivity(targetComponent);
+        mPhoneWindowManager.overrideKeyEventPolicyFlags(0);
+
+        sendKey(KEYCODE_STEM_PRIMARY);
+
+        mPhoneWindowManager.assertActivityTargetLaunched(targetComponent);
+    }
+
+    @Test
     public void stemSingleKey_appHasOverridePermission_consumedByApp_notOpenAllApp() {
         overrideBehavior(STEM_PRIMARY_BUTTON_SHORT_PRESS, SHORT_PRESS_PRIMARY_LAUNCH_ALL_APPS);
         setUpPhoneWindowManager(/* supportSettingsUpdate= */ true);
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index 2904c03..1a26c45 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -180,6 +180,8 @@
     private boolean mIsTalkBackEnabled;
     private boolean mIsTalkBackShortcutGestureEnabled;
 
+    private int mKeyEventPolicyFlags = FLAG_INTERACTIVE;
+
     private class TestTalkbackShortcutController extends TalkbackShortcutController {
         TestTalkbackShortcutController(Context context) {
             super(context);
@@ -379,12 +381,12 @@
     }
 
     int interceptKeyBeforeQueueing(KeyEvent event) {
-        return mPhoneWindowManager.interceptKeyBeforeQueueing(event, FLAG_INTERACTIVE);
+        return mPhoneWindowManager.interceptKeyBeforeQueueing(event, mKeyEventPolicyFlags);
     }
 
     long interceptKeyBeforeDispatching(KeyEvent event) {
         return mPhoneWindowManager.interceptKeyBeforeDispatching(mInputToken, event,
-                FLAG_INTERACTIVE);
+                mKeyEventPolicyFlags);
     }
 
     void dispatchUnhandledKey(KeyEvent event) {
@@ -588,6 +590,10 @@
                 .when(mButtonOverridePermissionChecker).canAppOverrideSystemKey(any(), anyInt());
     }
 
+    void overrideKeyEventPolicyFlags(int flags) {
+        mKeyEventPolicyFlags = flags;
+    }
+
     /**
      * Below functions will check the policy behavior could be invoked.
      */