summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt2
-rw-r--r--core/api/test-current.txt2
-rw-r--r--core/java/android/hardware/input/input_framework.aconfig7
-rw-r--r--core/java/android/view/KeyEvent.java26
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java23
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java9
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java5
8 files changed, 81 insertions, 5 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 89c772826822..e5bc2a3579bc 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -50640,6 +50640,7 @@ package android.view {
field public static final int KEYCODE_DVR = 173; // 0xad
field public static final int KEYCODE_E = 33; // 0x21
field public static final int KEYCODE_EISU = 212; // 0xd4
+ field @FlaggedApi("com.android.hardware.input.emoji_and_screenshot_keycodes_available") public static final int KEYCODE_EMOJI_PICKER = 317; // 0x13d
field public static final int KEYCODE_ENDCALL = 6; // 0x6
field public static final int KEYCODE_ENTER = 66; // 0x42
field public static final int KEYCODE_ENVELOPE = 65; // 0x41
@@ -50772,6 +50773,7 @@ package android.view {
field public static final int KEYCODE_RIGHT_BRACKET = 72; // 0x48
field public static final int KEYCODE_RO = 217; // 0xd9
field public static final int KEYCODE_S = 47; // 0x2f
+ field @FlaggedApi("com.android.hardware.input.emoji_and_screenshot_keycodes_available") public static final int KEYCODE_SCREENSHOT = 318; // 0x13e
field public static final int KEYCODE_SCROLL_LOCK = 116; // 0x74
field public static final int KEYCODE_SEARCH = 84; // 0x54
field public static final int KEYCODE_SEMICOLON = 74; // 0x4a
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 42cf08ff9a66..cea6547f8f83 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -3606,7 +3606,7 @@ package android.view {
method public final int getDisplayId();
method public final void setDisplayId(int);
field public static final int FLAG_IS_ACCESSIBILITY_EVENT = 2048; // 0x800
- field public static final int LAST_KEYCODE = 316; // 0x13c
+ field public static final int LAST_KEYCODE = 318; // 0x13e
}
public final class KeyboardShortcutGroup implements android.os.Parcelable {
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index 0ed6569afd2a..2041f6a5a845 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -33,6 +33,13 @@ flag {
flag {
namespace: "input_native"
+ name: "emoji_and_screenshot_keycodes_available"
+ description: "Add new KeyEvent keycodes for opening Emoji Picker and Taking Screenshots"
+ bug: "315307777"
+}
+
+flag {
+ namespace: "input_native"
name: "keyboard_a11y_slow_keys_flag"
description: "Controls if the slow keys accessibility feature for physical keyboard is available to the user"
bug: "294546335"
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index c6601e8d3085..1ee9509b116a 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -19,6 +19,7 @@ package android.view;
import static android.os.IInputConstants.INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
import static android.view.Display.INVALID_DISPLAY;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
@@ -31,6 +32,8 @@ import android.util.Log;
import android.util.SparseIntArray;
import android.view.KeyCharacterMap.KeyData;
+import com.android.hardware.input.Flags;
+
import java.util.concurrent.TimeUnit;
/**
@@ -384,7 +387,13 @@ public class KeyEvent extends InputEvent implements Parcelable {
public static final int KEYCODE_META_RIGHT = 118;
/** Key code constant: Function modifier key. */
public static final int KEYCODE_FUNCTION = 119;
- /** Key code constant: System Request / Print Screen key. */
+ /**
+ * Key code constant: System Request / Print Screen key.
+ *
+ * This key is sent to the app first and only if the app doesn't handle it, the framework
+ * handles it (to take a screenshot), unlike {@code KEYCODE_TAKE_SCREENSHOT} which is
+ * fully handled by the framework.
+ */
public static final int KEYCODE_SYSRQ = 120;
/** Key code constant: Break / Pause key. */
public static final int KEYCODE_BREAK = 121;
@@ -921,14 +930,25 @@ public class KeyEvent extends InputEvent implements Parcelable {
* User customizable key #4.
*/
public static final int KEYCODE_MACRO_4 = 316;
-
+ /** Key code constant: To open emoji picker */
+ @FlaggedApi(Flags.FLAG_EMOJI_AND_SCREENSHOT_KEYCODES_AVAILABLE)
+ public static final int KEYCODE_EMOJI_PICKER = 317;
+ /**
+ * Key code constant: To take a screenshot
+ *
+ * This key is fully handled by the framework and will not be sent to the foreground app,
+ * unlike {@code KEYCODE_SYSRQ} which is sent to the app first and only if the app
+ * doesn't handle it, the framework handles it (to take a screenshot).
+ */
+ @FlaggedApi(Flags.FLAG_EMOJI_AND_SCREENSHOT_KEYCODES_AVAILABLE)
+ public static final int KEYCODE_SCREENSHOT = 318;
/**
* Integer value of the last KEYCODE. Increases as new keycodes are added to KeyEvent.
* @hide
*/
@TestApi
- public static final int LAST_KEYCODE = KEYCODE_MACRO_4;
+ public static final int LAST_KEYCODE = KEYCODE_SCREENSHOT;
// NOTE: If you add a new keycode here you must also add it to:
// isSystem()
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 1fdcc64a90c8..51790b875465 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -75,6 +75,7 @@ import static android.view.WindowManagerGlobal.ADD_OKAY;
import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED;
import static android.view.contentprotection.flags.Flags.createAccessibilityOverlayAppOpEnabled;
+import static com.android.hardware.input.Flags.emojiAndScreenshotKeycodesAvailable;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_KEYCHORD_DELAY;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT;
@@ -3779,6 +3780,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
sendSystemKeyToStatusBarAsync(event);
return true;
}
+ case KeyEvent.KEYCODE_SCREENSHOT:
+ if (emojiAndScreenshotKeycodesAvailable() && down && repeatCount == 0) {
+ interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
+ }
+ return true;
}
if (isValidGlobalKey(keyCode)
&& mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
@@ -5022,6 +5028,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case KeyEvent.KEYCODE_MACRO_4:
result &= ~ACTION_PASS_TO_USER;
break;
+ case KeyEvent.KEYCODE_EMOJI_PICKER:
+ if (!emojiAndScreenshotKeycodesAvailable()) {
+ // Don't allow EMOJI_PICKER key to be dispatched until flag is released.
+ result &= ~ACTION_PASS_TO_USER;
+ }
+ break;
}
if (useHapticFeedback) {
diff --git a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
index 0382ca0d9fec..e21388e57a9e 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
@@ -34,6 +34,7 @@ import static android.view.KeyEvent.KEYCODE_SHIFT_LEFT;
import static android.view.KeyEvent.KEYCODE_SLASH;
import static android.view.KeyEvent.KEYCODE_SPACE;
import static android.view.KeyEvent.KEYCODE_TAB;
+import static android.view.KeyEvent.KEYCODE_SCREENSHOT;
import static android.view.KeyEvent.KEYCODE_U;
import static android.view.KeyEvent.KEYCODE_Z;
@@ -193,4 +194,26 @@ public class ModifierShortcutTests extends ShortcutKeyTestBase {
mPhoneWindowManager.verifyNewBrightness(newBrightness[i]);
}
}
+
+ /**
+ * Sends a KEYCODE_SCREENSHOT and validates screenshot is taken if flag is enabled
+ */
+ @Test
+ public void testTakeScreenshot_flagEnabled() {
+ mSetFlagsRule.enableFlags(com.android.hardware.input.Flags
+ .FLAG_EMOJI_AND_SCREENSHOT_KEYCODES_AVAILABLE);
+ sendKeyCombination(new int[]{KEYCODE_SCREENSHOT}, 0);
+ mPhoneWindowManager.assertTakeScreenshotCalled();
+ }
+
+ /**
+ * Sends a KEYCODE_SCREENSHOT and validates screenshot is not taken if flag is disabled
+ */
+ @Test
+ public void testTakeScreenshot_flagDisabled() {
+ mSetFlagsRule.disableFlags(com.android.hardware.input.Flags
+ .FLAG_EMOJI_AND_SCREENSHOT_KEYCODES_AVAILABLE);
+ sendKeyCombination(new int[]{KEYCODE_SCREENSHOT}, 0);
+ mPhoneWindowManager.assertTakeScreenshotNotCalled();
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
index 157d1627d993..fee6582c1ba4 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
@@ -46,6 +46,7 @@ import static com.android.server.policy.WindowManagerPolicy.ACTION_PASS_TO_USER;
import static java.util.Collections.unmodifiableMap;
import android.content.Context;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.util.ArrayMap;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
@@ -57,11 +58,17 @@ import com.android.internal.util.test.FakeSettingsProviderRule;
import org.junit.After;
import org.junit.Rule;
+import org.junit.rules.RuleChain;
import java.util.Map;
class ShortcutKeyTestBase {
- @Rule public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
+
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ public final FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
+
+ @Rule
+ public RuleChain rules = RuleChain.outerRule(mSettingsProviderRule).around(mSetFlagsRule);
TestPhoneWindowManager mPhoneWindowManager;
DispatchedKeyHandler mDispatchedKeyHandler = event -> false;
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 c8abd8d7297e..2904c0325d40 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -596,6 +596,11 @@ class TestPhoneWindowManager {
verify(mDisplayPolicy).takeScreenshot(anyInt(), anyInt());
}
+ void assertTakeScreenshotNotCalled() {
+ mTestLooper.dispatchAll();
+ verify(mDisplayPolicy, never()).takeScreenshot(anyInt(), anyInt());
+ }
+
void assertShowGlobalActionsCalled() {
mTestLooper.dispatchAll();
verify(mPhoneWindowManager).showGlobalActions();