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

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

Merge "Handle custom key gestures added by the user" into main

parents cf1fff23 37fa9143
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -17,10 +17,13 @@
package com.android.server.input;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.hardware.input.InputGestureData;
import android.hardware.input.InputManager;
import android.util.IndentingPrintWriter;
import android.util.SparseArray;
import android.view.KeyEvent;

import com.android.internal.annotations.GuardedBy;

@@ -40,6 +43,10 @@ import java.util.Objects;
final class InputGestureManager {
    private static final String TAG = "InputGestureManager";

    private static final int KEY_GESTURE_META_MASK =
            KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON
                    | KeyEvent.META_META_ON;

    @GuardedBy("mCustomInputGestures")
    private final SparseArray<Map<InputGestureData.Trigger, InputGestureData>>
            mCustomInputGestures = new SparseArray<>();
@@ -96,6 +103,23 @@ final class InputGestureManager {
        }
    }

    @Nullable
    public InputGestureData getCustomGestureForKeyEvent(@UserIdInt int userId, KeyEvent event) {
        final int keyCode = event.getKeyCode();
        if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
            return null;
        }
        synchronized (mCustomInputGestures) {
            Map<InputGestureData.Trigger, InputGestureData> customGestures =
                    mCustomInputGestures.get(userId);
            if (customGestures == null) {
                return null;
            }
            int modifierState = event.getMetaState() & KEY_GESTURE_META_MASK;
            return customGestures.get(InputGestureData.createKeyTrigger(keyCode, modifierState));
        }
    }

    public void dump(IndentingPrintWriter ipw) {
        ipw.println("InputGestureManager:");
        ipw.increaseIndent();
+1 −0
Original line number Diff line number Diff line
@@ -3022,6 +3022,7 @@ public class InputManagerService extends IInputManager.Stub

    private void handleCurrentUserChanged(@UserIdInt int userId) {
        mCurrentUserId = userId;
        mKeyGestureController.setCurrentUserId(userId);
    }

    /**
+121 −78

File changed.

Preview size limit exceeded, changes collapsed.

+65 −1
Original line number Diff line number Diff line
@@ -22,8 +22,10 @@ import android.content.pm.PackageManager
import android.content.res.Resources
import android.hardware.input.IInputManager
import android.hardware.input.AidlKeyGestureEvent
import android.hardware.input.AppLaunchData
import android.hardware.input.IKeyGestureEventListener
import android.hardware.input.IKeyGestureHandler
import android.hardware.input.InputGestureData
import android.hardware.input.InputManager
import android.hardware.input.InputManagerGlobal
import android.hardware.input.KeyGestureEvent
@@ -232,7 +234,7 @@ class KeyGestureControllerTests {
        keyGestureController.handleKeyGesture(/* deviceId = */ 0, intArrayOf(KeyEvent.KEYCODE_HOME),
            /* modifierState = */ 0, KeyGestureEvent.KEY_GESTURE_TYPE_HOME,
            KeyGestureEvent.ACTION_GESTURE_COMPLETE, /* displayId */ 0,
            /* focusedToken = */ null, /* flags = */ 0
            /* focusedToken = */ null, /* flags = */ 0, /* appLaunchData = */null
        )

        assertEquals(
@@ -259,6 +261,7 @@ class KeyGestureControllerTests {
        val expectedKeys: IntArray,
        val expectedModifierState: Int,
        val expectedActions: IntArray,
        val expectedAppLaunchData: AppLaunchData? = null,
    ) {
        override fun toString(): String = name
    }
@@ -1055,6 +1058,62 @@ class KeyGestureControllerTests {
        testKeyGestureInternal(keyGestureController, test)
    }

    @Keep
    private fun customInputGesturesTestArguments(): Array<TestData> {
        return arrayOf(
            TestData(
                "META + ALT + Q -> Go Home",
                intArrayOf(
                    KeyEvent.KEYCODE_META_LEFT,
                    KeyEvent.KEYCODE_ALT_LEFT,
                    KeyEvent.KEYCODE_Q
                ),
                KeyGestureEvent.KEY_GESTURE_TYPE_HOME,
                intArrayOf(KeyEvent.KEYCODE_Q),
                KeyEvent.META_META_ON or KeyEvent.META_ALT_ON,
                intArrayOf(
                    KeyGestureEvent.ACTION_GESTURE_COMPLETE
                )
            ),
            TestData(
                "META + ALT + Q -> Launch app",
                intArrayOf(
                    KeyEvent.KEYCODE_CTRL_LEFT,
                    KeyEvent.KEYCODE_SHIFT_LEFT,
                    KeyEvent.KEYCODE_Q
                ),
                KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
                intArrayOf(KeyEvent.KEYCODE_Q),
                KeyEvent.META_CTRL_ON or KeyEvent.META_SHIFT_ON,
                intArrayOf(
                    KeyGestureEvent.ACTION_GESTURE_COMPLETE
                ),
                AppLaunchData.createLaunchDataForComponent("com.test", "com.test.BookmarkTest")
            ),
        )
    }

    @Test
    @Parameters(method = "customInputGesturesTestArguments")
    fun testCustomKeyGestures(test: TestData) {
        val keyGestureController = KeyGestureController(context, testLooper.looper)
        val builder = InputGestureData.Builder()
            .setKeyGestureType(test.expectedKeyGestureType)
            .setTrigger(
                InputGestureData.createKeyTrigger(
                    test.expectedKeys[0],
                    test.expectedModifierState
                )
            );
        if (test.expectedAppLaunchData != null) {
            builder.setAppLaunchData(test.expectedAppLaunchData)
        }
        val inputGestureData = builder.build();

        keyGestureController.addCustomInputGesture(0, inputGestureData.aidlData)
        testKeyGestureInternal(keyGestureController, test)
    }

    private fun testKeyGestureInternal(keyGestureController: KeyGestureController, test: TestData) {
        var handleEvents = mutableListOf<KeyGestureEvent>()
        val handler = KeyGestureHandler { event, _ ->
@@ -1093,6 +1152,11 @@ class KeyGestureControllerTests {
                test.expectedActions[i],
                event.action
            )
            assertEquals(
                "Test: $test doesn't produce correct app launch data",
                test.expectedAppLaunchData,
                event.appLaunchData
            )
        }

        keyGestureController.unregisterKeyGestureHandler(handler, 0)