Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 890300bf authored by Vaibhav Devmurari's avatar Vaibhav Devmurari Committed by Android (Google) Code Review
Browse files

Merge "Add long press escape to close current app if keyboard capture on" into main

parents 865dbadf bc24b511
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -132,6 +132,7 @@ public final class KeyGestureEvent {
    public static final int KEY_GESTURE_TYPE_SWITCH_TO_PREVIOUS_DESK = 77;
    public static final int KEY_GESTURE_TYPE_SWITCH_TO_NEXT_DESK = 78;
    public static final int KEY_GESTURE_TYPE_TOGGLE_QUICK_SETTINGS_PANEL = 79;
    public static final int KEY_GESTURE_TYPE_QUIT_FOCUSED_TASK = 80;

    public static final int FLAG_CANCELLED = 1 << 0;
    public static final int FLAG_LONG_PRESS = 1 << 1;
@@ -226,6 +227,7 @@ public final class KeyGestureEvent {
            KEY_GESTURE_TYPE_SWITCH_TO_PREVIOUS_DESK,
            KEY_GESTURE_TYPE_SWITCH_TO_NEXT_DESK,
            KEY_GESTURE_TYPE_TOGGLE_QUICK_SETTINGS_PANEL,
            KEY_GESTURE_TYPE_QUIT_FOCUSED_TASK,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface KeyGestureType {
@@ -824,6 +826,8 @@ public final class KeyGestureEvent {
                return "KEY_GESTURE_TYPE_SWITCH_TO_NEXT_DESK";
            case KEY_GESTURE_TYPE_TOGGLE_QUICK_SETTINGS_PANEL:
                return "KEY_GESTURE_TYPE_TOGGLE_QUICK_SETTINGS_PANEL";
            case KEY_GESTURE_TYPE_QUIT_FOCUSED_TASK:
                return "KEY_GESTURE_TYPE_QUIT_FOCUSED_TASK";
            default:
                return Integer.toHexString(value);
        }
+3 −0
Original line number Diff line number Diff line
@@ -2507,6 +2507,9 @@
    <!-- Description of policy access to disable keyguard features. [CHAR LIMIT=110]-->
    <string name="policydesc_disableKeyguardFeatures">Prevent use of some screen lock features.</string>
    <!-- Text for toast instructing user to long press escape to exit the current application. [CHAR LIMIT=TOAST]-->
    <string name="exit_toast_on_long_press_escape">Long press escape key to quit the application.</string>
    <!-- The order of these is important, don't reorder without changing Contacts.java --> <skip />
    <!-- Phone number types from android.provider.Contacts. This could be used when adding a new phone number for a contact, for example. -->
    <string-array name="phoneTypes">
+2 −0
Original line number Diff line number Diff line
@@ -6289,6 +6289,8 @@
  <java-symbol type="string" name="proximity_provider_service_package_name" />
  <java-symbol type="string" name="proximity_provider_service_class_name" />

  <java-symbol type="string" name="exit_toast_on_long_press_escape" />

  <!-- For App Functions -->
  <java-symbol type="array" name="config_appFunctionDeviceSettingsPackages" />
</resources>
+31 −1
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.widget.Toast;

import com.android.internal.R;
import com.android.internal.accessibility.AccessibilityShortcutController;
@@ -86,6 +87,7 @@ import com.android.internal.policy.KeyInterceptionInfo;
import com.android.internal.util.ScreenshotHelper;
import com.android.internal.util.ScreenshotRequest;
import com.android.server.LocalServices;
import com.android.server.UiThread;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.WindowManagerInternal;

@@ -127,6 +129,7 @@ final class KeyGestureController {
    private static final int MSG_LOAD_CUSTOM_GESTURES = 3;
    private static final int MSG_ACCESSIBILITY_SHORTCUT = 4;
    private static final int MSG_SCREENSHOT_SHORTCUT = 5;
    private static final int MSG_EXIT_FOCUSED_APP = 6;

    // must match: config_settingsKeyBehavior in config.xml
    private static final int SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY = 0;
@@ -148,6 +151,9 @@ final class KeyGestureController {
    // Increase the chord delay when taking a screenshot from the keyguard
    private static final float KEYGUARD_SCREENSHOT_CHORD_DELAY_MULTIPLIER = 2.5f;

    // Duration to long press escape to exit application when app is capturing keyboard keys
    private static final long LONG_PRESS_DURATION_FOR_EXIT_APP_MS = 1000;

    @LongDef(prefix = {"KEY_INTERCEPT_RESULT_"}, value = {
            KEY_INTERCEPT_RESULT_NOT_CONSUMED_GO_FALLBACK,
            KEY_INTERCEPT_RESULT_CONSUMED,
@@ -804,6 +810,28 @@ final class KeyGestureController {
                    }
                }
                return true;
            case KeyEvent.KEYCODE_ESCAPE:
                // TODO(b/358569822): Currently implemented long press using handler and delayed
                //  message here, instead of using SingleKeyGestureDetector because that detection
                //  logic doesn't have access to focused token. Refactor this so that we don't
                //  have this custom logic to detect long press.
                if (firstDown && canFocusedWindowCaptureKeys(focusedToken)) {
                    // Toast to quit application is shown on key down for ESCAPE key, when the
                    // focused window is capturing keys.
                    Toast.makeText(mContext, UiThread.get().getLooper(),
                            mContext.getString(R.string.exit_toast_on_long_press_escape),
                            Toast.LENGTH_SHORT).show();
                    AidlKeyGestureEvent eventToSend = createKeyGestureEvent(event.getDeviceId(),
                            new int[]{KeyEvent.KEYCODE_ESCAPE},
                            metaState, KeyGestureEvent.KEY_GESTURE_TYPE_QUIT_FOCUSED_TASK,
                            KeyGestureEvent.ACTION_GESTURE_COMPLETE,
                            displayId, /* flags= */0, /* appLaunchData= */ null);
                    Message msg = Message.obtain(mHandler, MSG_EXIT_FOCUSED_APP, eventToSend);
                    mHandler.sendMessageDelayed(msg, LONG_PRESS_DURATION_FOR_EXIT_APP_MS);
                } else if (!down) {
                    mHandler.removeMessages(MSG_EXIT_FOCUSED_APP);
                }
                break;
            case KeyEvent.KEYCODE_ASSIST:
                Slog.wtf(TAG, "KEYCODE_ASSIST should be handled in interceptKeyBeforeQueueing");
                return true;
@@ -1272,7 +1300,9 @@ final class KeyGestureController {
            case MSG_SCREENSHOT_SHORTCUT:
                takeScreenshot(msg.arg1, msg.arg2);
                break;

            case MSG_EXIT_FOCUSED_APP:
                handleKeyGesture((AidlKeyGestureEvent) msg.obj, /* focusedToken= */null);
                break;
        }
        return true;
    }
+21 −1
Original line number Diff line number Diff line
@@ -3467,7 +3467,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB,
                KeyGestureEvent.KEY_GESTURE_TYPE_RINGER_TOGGLE_CHORD,
                KeyGestureEvent.KEY_GESTURE_TYPE_GLOBAL_ACTIONS,
                KeyGestureEvent.KEY_GESTURE_TYPE_TV_TRIGGER_BUG_REPORT
                KeyGestureEvent.KEY_GESTURE_TYPE_TV_TRIGGER_BUG_REPORT,
                KeyGestureEvent.KEY_GESTURE_TYPE_QUIT_FOCUSED_TASK
        ));
        if (!com.android.window.flags.Flags.grantManageKeyGesturesToRecents()) {
            // When grantManageKeyGesturesToRecents is enabled, the event is handled in the
@@ -3671,6 +3672,25 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                            "Key gesture DND", true);
                }
                break;
            case KeyGestureEvent.KEY_GESTURE_TYPE_QUIT_FOCUSED_TASK:
                if (complete) {
                    try {
                        RootTaskInfo currentRootTask =
                                mActivityManagerService.getFocusedRootTaskInfo();
                        if (currentRootTask == null) {
                            Slog.e(TAG,
                                    "onKeyGesture: KEY_GESTURE_TYPE_QUIT_FOCUSED_TASK the current"
                                            + " root task is null" );
                            return;
                        }
                        mActivityManagerService.removeTask(currentRootTask.taskId);
                    } catch (RemoteException e) {
                        Slog.e(TAG,
                                "onKeyGesture: KEY_GESTURE_TYPE_QUIT_FOCUSED_TASK failed to close"
                                        + " the current root task",
                                e);
                    }
                }
            default:
                Log.w(TAG, "Received a key gesture " + event
                        + " that was not registered by this handler");
Loading