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

Commit 1f245100 authored by Jeff Brown's avatar Jeff Brown
Browse files

Ensure the ShortcutManager uses the correct key character map.

The ShortcutManager used to only receive the key code of the key event
that triggered the shortcut.  This change now provides the shortcut
manager with the whole key event so it can look up the associated
character using the correct key character map.

To make this more efficient, added a mechanism for recycling
key events.  At the moment it is only used by key events owned by the
system process, since clients of the existing API (such as Views)
might continue to hold on to key events after dispatch has finished so
they would break if the key event were recycled by the framework.

Deprecated KeyCharacterMap.BUILT_IN_KEYBOARD.

Change-Id: I4313725dd63f2be01c350c005a41c7fde9bc67e8
parent 47e6b1b5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -196675,7 +196675,7 @@
 value="0"
 static="true"
 final="true"
 deprecated="not deprecated"
 deprecated="deprecated"
 visibility="public"
>
</field>
+12 −0
Original line number Diff line number Diff line
@@ -31,7 +31,19 @@ import java.lang.Character;
public class KeyCharacterMap {
    /**
     * The id of the device's primary built in keyboard is always 0.
     *
     * @deprecated This constant should no longer be used because there is no
     * guarantee that a device has a built-in keyboard that can be used for
     * typing text.  There might not be a built-in keyboard, the built-in keyboard
     * might be a {@link #NUMERIC} or {@link #SPECIAL_FUNCTION} keyboard, or there
     * might be multiple keyboards installed including external keyboards.
     * When interpreting key presses received from the framework, applications should
     * use the device id specified in the {@link #KeyEvent} received.
     * When synthesizing key presses for delivery elsewhere or when translating key presses
     * from unknown keyboards, applications should use the special {@link #VIRTUAL_KEYBOARD}
     * device id.
     */
    @Deprecated
    public static final int BUILT_IN_KEYBOARD = 0;

    /**
+73 −1
Original line number Diff line number Diff line
@@ -1082,6 +1082,14 @@ public class KeyEvent extends InputEvent implements Parcelable {
    static final boolean DEBUG = false;
    static final String TAG = "KeyEvent";

    private static final int MAX_RECYCLED = 10;
    private static final Object gRecyclerLock = new Object();
    private static int gRecyclerUsed;
    private static KeyEvent gRecyclerTop;

    private KeyEvent mNext;
    private boolean mRecycled;

    private int mMetaState;
    private int mAction;
    private int mKeyCode;
@@ -1160,6 +1168,9 @@ public class KeyEvent extends InputEvent implements Parcelable {
        }
    }

    private KeyEvent() {
    }

    /**
     * Create a new key event.
     * 
@@ -1382,6 +1393,67 @@ public class KeyEvent extends InputEvent implements Parcelable {
        mCharacters = origEvent.mCharacters;
    }

    private static KeyEvent obtain() {
        final KeyEvent ev;
        synchronized (gRecyclerLock) {
            ev = gRecyclerTop;
            if (ev == null) {
                return new KeyEvent();
            }
            gRecyclerTop = ev.mNext;
            gRecyclerUsed -= 1;
        }
        ev.mRecycled = false;
        ev.mNext = null;
        return ev;
    }

    /**
     * Obtains a (potentially recycled) key event.
     *
     * @hide
     */
    public static KeyEvent obtain(long downTime, long eventTime, int action,
                    int code, int repeat, int metaState,
                    int deviceId, int scancode, int flags, int source, String characters) {
        KeyEvent ev = obtain();
        ev.mDownTime = downTime;
        ev.mEventTime = eventTime;
        ev.mAction = action;
        ev.mKeyCode = code;
        ev.mRepeatCount = repeat;
        ev.mMetaState = metaState;
        ev.mDeviceId = deviceId;
        ev.mScanCode = scancode;
        ev.mFlags = flags;
        ev.mSource = source;
        ev.mCharacters = characters;
        return ev;
    }

    /**
     * Recycles a key event.
     * Key events should only be recycled if they are owned by the system since user
     * code expects them to be essentially immutable, "tracking" notwithstanding.
     *
     * @hide
     */
    public final void recycle() {
        if (mRecycled) {
            throw new RuntimeException(toString() + " recycled twice!");
        }
        mRecycled = true;
        mCharacters = null;

        synchronized (gRecyclerLock) {
            if (gRecyclerUsed < MAX_RECYCLED) {
                gRecyclerUsed++;
                mNext = gRecyclerTop;
                gRecyclerTop = this;
            }
        }
    }

    /**
     * Create a new key event that is the same as the given one, but whose
     * event time and repeat count are replaced with the given value.
+6 −6
Original line number Diff line number Diff line
@@ -314,10 +314,10 @@ public final class MotionEvent extends InputEvent implements Parcelable {
     */
    static private final int BASE_AVAIL_SAMPLES = 8;
    
    static private final int MAX_RECYCLED = 10;
    static private Object gRecyclerLock = new Object();
    static private int gRecyclerUsed = 0;
    static private MotionEvent gRecyclerTop = null;
    private static final int MAX_RECYCLED = 10;
    private static final Object gRecyclerLock = new Object();
    private static int gRecyclerUsed;
    private static MotionEvent gRecyclerTop;

    private long mDownTimeNano;
    private int mAction;
@@ -361,7 +361,8 @@ public final class MotionEvent extends InputEvent implements Parcelable {
    static private MotionEvent obtain(int pointerCount, int sampleCount) {
        final MotionEvent ev;
        synchronized (gRecyclerLock) {
            if (gRecyclerTop == null) {
            ev = gRecyclerTop;
            if (ev == null) {
                if (pointerCount < BASE_AVAIL_POINTERS) {
                    pointerCount = BASE_AVAIL_POINTERS;
                }
@@ -370,7 +371,6 @@ public final class MotionEvent extends InputEvent implements Parcelable {
                }
                return new MotionEvent(pointerCount, sampleCount);
            }
            ev = gRecyclerTop;
            gRecyclerTop = ev.mNext;
            gRecyclerUsed -= 1;
        }
+6 −23
Original line number Diff line number Diff line
@@ -551,19 +551,14 @@ public interface WindowManagerPolicy {
     * affect the power state of the device, for example, the power keys.
     * Generally, it's best to keep as little as possible in the queue thread
     * because it's the most fragile.
     * @param whenNanos The event time in uptime nanoseconds.
     * @param action The key event action.
     * @param flags The key event flags.
     * @param keyCode The key code.
     * @param scanCode The key's scan code.
     * @param event The key event.
     * @param policyFlags The policy flags associated with the key.
     * @param isScreenOn True if the screen is already on
     *
     * @return The bitwise or of the {@link #ACTION_PASS_TO_USER},
     *          {@link #ACTION_POKE_USER_ACTIVITY} and {@link #ACTION_GO_TO_SLEEP} flags.
     */
    public int interceptKeyBeforeQueueing(long whenNanos, int action, int flags,
            int keyCode, int scanCode, int policyFlags, boolean isScreenOn);
    public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn);
    
    /**
     * Called from the input dispatcher thread before a key is dispatched to a window.
@@ -574,18 +569,12 @@ public interface WindowManagerPolicy {
     * 
     * @param win The window that currently has focus.  This is where the key
     *            event will normally go.
     * @param action The key event action.
     * @param flags The key event flags.
     * @param keyCode The key code.
     * @param scanCode The key's scan code.
     * @param metaState bit mask of meta keys that are held.
     * @param repeatCount Number of times a key down has repeated.
     * @param event The key event.
     * @param policyFlags The policy flags associated with the key.
     * @return Returns true if the policy consumed the event and it should
     * not be further dispatched.
     */
    public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
            int keyCode, int scanCode, int metaState, int repeatCount, int policyFlags);
    public boolean interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags);

    /**
     * Called from the input dispatcher thread when an application did not handle
@@ -596,17 +585,11 @@ public interface WindowManagerPolicy {
     * 
     * @param win The window that currently has focus.  This is where the key
     *            event will normally go.
     * @param action The key event action.
     * @param flags The key event flags.
     * @param keyCode The key code.
     * @param scanCode The key's scan code.
     * @param metaState bit mask of meta keys that are held.
     * @param repeatCount Number of times a key down has repeated.
     * @param event The key event.
     * @param policyFlags The policy flags associated with the key.
     * @return Returns true if the policy consumed the event.
     */
    public boolean dispatchUnhandledKey(WindowState win, int action, int flags,
            int keyCode, int scanCode, int metaState, int repeatCount, int policyFlags);
    public boolean dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags);

    /**
     * Called when layout of the windows is about to start.
Loading