summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Michał Brzeziński <brzezinski@google.com> 2024-08-19 18:41:14 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-08-19 18:41:14 +0000
commit94e64d081d5b4e636b0c7d4c996d06d8996b6f5f (patch)
treeef1624c9c41fa34170c85b38acda4ed6eca65c33
parent80462ae2d37e27fd17b58589dd3f8fa901cb0a48 (diff)
parent20c78a6c479a954de660cc8aae33742151dfb7f4 (diff)
Merge "Passing meta/action key related key events when private flag is set" into main
-rw-r--r--core/java/android/view/WindowManager.java9
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java15
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/MetaKeyEventsInterceptionTests.java96
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java5
4 files changed, 125 insertions, 0 deletions
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 017e004a7f13..67a207e34a1a 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -3462,6 +3462,15 @@ public interface WindowManager extends ViewManager {
public static final int PRIVATE_FLAG_NOT_MAGNIFIABLE = 1 << 22;
/**
+ * Indicates that the window should receive key events including Action/Meta key.
+ * They will not be intercepted as usual and instead will be passed to the window with other
+ * key events.
+ * TODO(b/358569822) Remove this once we have nicer API for listening to shortcuts
+ * @hide
+ */
+ public static final int PRIVATE_FLAG_ALLOW_ACTION_KEY_EVENTS = 1 << 23;
+
+ /**
* Flag to indicate that the window is color space agnostic, and the color can be
* interpreted to any color space.
* @hide
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index aa56e8d8eb55..ba3de33d865c 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3352,6 +3352,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mConsumedKeysForDevice.put(deviceId, consumedKeys);
}
+ // TODO(b/358569822) Remove below once we have nicer API for listening to shortcuts
+ if ((event.isMetaPressed() || KeyEvent.isMetaKey(keyCode))
+ && shouldInterceptShortcuts(focusedToken)) {
+ return keyNotConsumed;
+ }
+
if (interceptSystemKeysAndShortcuts(focusedToken, event)
&& event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
consumedKeys.add(keyCode);
@@ -3842,6 +3848,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return (metaState & KeyEvent.META_META_ON) != 0;
}
+ private boolean shouldInterceptShortcuts(IBinder focusedToken) {
+ KeyInterceptionInfo info =
+ mWindowManagerInternal.getKeyInterceptionInfoFromToken(focusedToken);
+ boolean hasInterceptWindowFlag = (info.layoutParamsPrivateFlags
+ & WindowManager.LayoutParams.PRIVATE_FLAG_ALLOW_ACTION_KEY_EVENTS) != 0;
+ return hasInterceptWindowFlag && mButtonOverridePermissionChecker.canAppOverrideSystemKey(
+ mContext, info.windowOwnerUid);
+ }
+
/**
* In this function, we check whether a system key should be sent to the application. We also
* detect the key gesture on this key, even if the key will be sent to the app. The gesture
diff --git a/services/tests/wmtests/src/com/android/server/policy/MetaKeyEventsInterceptionTests.java b/services/tests/wmtests/src/com/android/server/policy/MetaKeyEventsInterceptionTests.java
new file mode 100644
index 000000000000..b979335233e3
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/policy/MetaKeyEventsInterceptionTests.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2024 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.server.policy;
+
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_ALLOW_ACTION_KEY_EVENTS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.view.KeyEvent;
+import android.view.WindowManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.policy.KeyInterceptionInfo;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Testing {@link PhoneWindowManager} functionality of letting app intercepting key events
+ * containing META.
+ */
+@SmallTest
+public class MetaKeyEventsInterceptionTests extends ShortcutKeyTestBase {
+
+ private static final List<KeyEvent> META_KEY_EVENTS = Arrays.asList(
+ new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_META_LEFT),
+ new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_META_RIGHT),
+ new KeyEvent(/* downTime= */ 0, /* eventTime= */
+ 0, /* action= */ 0, /* code= */ 0, /* repeat= */ 0,
+ /* metaState= */ KeyEvent.META_META_ON));
+
+ @Before
+ public void setUp() {
+ setUpPhoneWindowManager();
+ }
+
+ @Test
+ public void doesntInterceptMetaKeyEvents_whenWindowAskedForIt() {
+ mPhoneWindowManager.overrideFocusedWindowButtonOverridePermission(/* granted= */ true);
+ setWindowKeyInterceptionWithPrivateFlags(PRIVATE_FLAG_ALLOW_ACTION_KEY_EVENTS);
+
+ META_KEY_EVENTS.forEach(keyEvent -> {
+ assertKeyInterceptionResult(keyEvent, /* intercepted= */ false);
+ });
+ }
+
+ @Test
+ public void interceptsMetaKeyEvents_whenWindowDoesntHaveFlagSet() {
+ mPhoneWindowManager.overrideFocusedWindowButtonOverridePermission(/* granted= */ true);
+ setWindowKeyInterceptionWithPrivateFlags(0);
+
+ META_KEY_EVENTS.forEach(keyEvent -> {
+ assertKeyInterceptionResult(keyEvent, /* intercepted= */ true);
+ });
+ }
+
+ @Test
+ public void interceptsMetaKeyEvents_whenWindowDoesntHavePermission() {
+ mPhoneWindowManager.overrideFocusedWindowButtonOverridePermission(/* granted= */ false);
+ setWindowKeyInterceptionWithPrivateFlags(PRIVATE_FLAG_ALLOW_ACTION_KEY_EVENTS);
+
+ META_KEY_EVENTS.forEach(keyEvent -> {
+ assertKeyInterceptionResult(keyEvent, /* intercepted= */ true);
+ });
+ }
+
+ private void setWindowKeyInterceptionWithPrivateFlags(int privateFlags) {
+ KeyInterceptionInfo info = new KeyInterceptionInfo(
+ WindowManager.LayoutParams.TYPE_APPLICATION, privateFlags, "title", 0);
+ mPhoneWindowManager.overrideWindowKeyInterceptionInfo(info);
+ }
+
+ private void assertKeyInterceptionResult(KeyEvent keyEvent, boolean intercepted) {
+ long result = mPhoneWindowManager.interceptKeyBeforeDispatching(keyEvent);
+ int expected = intercepted ? -1 : 0;
+ assertThat(result).isEqualTo(expected);
+ }
+}
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 43b065dbb6a5..79c7ac193b40 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -52,6 +52,7 @@ import static org.mockito.Mockito.after;
import static org.mockito.Mockito.description;
import static org.mockito.Mockito.mockingDetails;
import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
import android.app.ActivityManagerInternal;
@@ -613,6 +614,10 @@ class TestPhoneWindowManager {
.when(mButtonOverridePermissionChecker).canAppOverrideSystemKey(any(), anyInt());
}
+ void overrideWindowKeyInterceptionInfo(KeyInterceptionInfo info) {
+ when(mWindowManagerInternal.getKeyInterceptionInfoFromToken(any())).thenReturn(info);
+ }
+
void overrideKeyEventPolicyFlags(int flags) {
mKeyEventPolicyFlags = flags;
}