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

Commit 49ed71db authored by Jeff Brown's avatar Jeff Brown
Browse files

Add support for fallback keycodes.

This change enables the framework to synthesize key events to implement
default behavior when an application does not handle a key.
For example, this change enables numeric keypad keys to perform
their associated special function when numlock is off.

The application is informed that it is processing a fallback keypress
so it can choose to ignore it.

Added a new keycode for switching applications.

Added ALT key deadkeys.

New default key mappings:
- ESC -> BACK
- Meta+ESC -> HOME
- Alt+ESC -> MENU
- Meta+Space -> SEARCH
- Meta+Tab -> APP_SWITCH

Fixed some comments.
Fixed some tests.

Change-Id: Id7f3b6645f3a350275e624547822f72652f3defe
parent f30c8287
Loading
Loading
Loading
Loading
+22 −0
Original line number Original line Diff line number Diff line
@@ -198463,6 +198463,17 @@
 visibility="public"
 visibility="public"
>
>
</field>
</field>
<field name="FLAG_FALLBACK"
 type="int"
 transient="false"
 volatile="false"
 value="1024"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="FLAG_FROM_SYSTEM"
<field name="FLAG_FROM_SYSTEM"
 type="int"
 type="int"
 transient="false"
 transient="false"
@@ -198694,6 +198705,17 @@
 visibility="public"
 visibility="public"
>
>
</field>
</field>
<field name="KEYCODE_APP_SWITCH"
 type="int"
 transient="false"
 volatile="false"
 value="187"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="KEYCODE_AT"
<field name="KEYCODE_AT"
 type="int"
 type="int"
 transient="false"
 transient="false"
+54 −7
Original line number Original line Diff line number Diff line
@@ -144,6 +144,8 @@ public class KeyCharacterMap {
    private static native void nativeDispose(int ptr);
    private static native void nativeDispose(int ptr);


    private static native char nativeGetCharacter(int ptr, int keyCode, int metaState);
    private static native char nativeGetCharacter(int ptr, int keyCode, int metaState);
    private static native boolean nativeGetFallbackAction(int ptr, int keyCode, int metaState,
            FallbackAction outFallbackAction);
    private static native char nativeGetNumber(int ptr, int keyCode);
    private static native char nativeGetNumber(int ptr, int keyCode);
    private static native char nativeGetMatch(int ptr, int keyCode, char[] chars, int metaState);
    private static native char nativeGetMatch(int ptr, int keyCode, char[] chars, int metaState);
    private static native char nativeGetDisplayLabel(int ptr, int keyCode);
    private static native char nativeGetDisplayLabel(int ptr, int keyCode);
@@ -206,14 +208,9 @@ public class KeyCharacterMap {
     * @return The associated character or combining accent, or 0 if none.
     * @return The associated character or combining accent, or 0 if none.
     */
     */
    public int get(int keyCode, int metaState) {
    public int get(int keyCode, int metaState) {
        if ((metaState & MetaKeyKeyListener.META_CAP_LOCKED) != 0) {
        metaState = applyLockedModifiers(metaState);
            metaState |= KeyEvent.META_CAPS_LOCK_ON;
        }
        if ((metaState & MetaKeyKeyListener.META_ALT_LOCKED) != 0) {
            metaState |= KeyEvent.META_ALT_ON;
        }

        char ch = nativeGetCharacter(mPtr, keyCode, metaState);
        char ch = nativeGetCharacter(mPtr, keyCode, metaState);

        int map = COMBINING.get(ch);
        int map = COMBINING.get(ch);
        if (map != 0) {
        if (map != 0) {
            return map;
            return map;
@@ -222,6 +219,34 @@ public class KeyCharacterMap {
        }
        }
    }
    }


    /**
     * Gets the fallback action to perform if the application does not
     * handle the specified key.
     * <p>
     * When an application does not handle a particular key, the system may
     * translate the key to an alternate fallback key (specified in the
     * fallback action) and dispatch it to the application.
     * The event containing the fallback key is flagged
     * with {@link KeyEvent#FLAG_FALLBACK}.
     * </p>
     *
     * @param keyCode The key code.
     * @param metaState The meta key modifier state.
     * @param outFallbackAction The fallback action object to populate.
     * @return True if a fallback action was found, false otherwise.
     *
     * @hide
     */
    public boolean getFallbackAction(int keyCode, int metaState,
            FallbackAction outFallbackAction) {
        if (outFallbackAction == null) {
            throw new IllegalArgumentException("fallbackAction must not be null");
        }

        metaState = applyLockedModifiers(metaState);
        return nativeGetFallbackAction(mPtr, keyCode, metaState, outFallbackAction);
    }

    /**
    /**
     * Gets the number or symbol associated with the key.
     * Gets the number or symbol associated with the key.
     * <p>
     * <p>
@@ -277,6 +302,8 @@ public class KeyCharacterMap {
        if (chars == null) {
        if (chars == null) {
            throw new IllegalArgumentException("chars must not be null.");
            throw new IllegalArgumentException("chars must not be null.");
        }
        }

        metaState = applyLockedModifiers(metaState);
        return nativeGetMatch(mPtr, keyCode, chars, metaState);
        return nativeGetMatch(mPtr, keyCode, chars, metaState);
    }
    }


@@ -509,6 +536,16 @@ public class KeyCharacterMap {
        return ret;
        return ret;
    }
    }


    private static int applyLockedModifiers(int metaState) {
        if ((metaState & MetaKeyKeyListener.META_CAP_LOCKED) != 0) {
            metaState |= KeyEvent.META_CAPS_LOCK_ON;
        }
        if ((metaState & MetaKeyKeyListener.META_ALT_LOCKED) != 0) {
            metaState |= KeyEvent.META_ALT_ON;
        }
        return metaState;
    }

    /**
    /**
     * Maps Unicode combining diacritical to display-form dead key
     * Maps Unicode combining diacritical to display-form dead key
     * (display character shifted left 16 bits).
     * (display character shifted left 16 bits).
@@ -670,4 +707,14 @@ public class KeyCharacterMap {
            super(msg);
            super(msg);
        }
        }
    }
    }

    /**
     * Specifies a substitute key code and meta state as a fallback action
     * for an unhandled key.
     * @hide
     */
    public static final class FallbackAction {
        public int keyCode;
        public int metaState;
    }
}
}
+16 −3
Original line number Original line Diff line number Diff line
@@ -529,15 +529,17 @@ public class KeyEvent extends InputEvent implements Parcelable {
    /** Key code constant: Blue "programmable" key.
    /** Key code constant: Blue "programmable" key.
     * On TV remotes, acts as a contextual/programmable key. */
     * On TV remotes, acts as a contextual/programmable key. */
    public static final int KEYCODE_PROG_BLUE       = 186;
    public static final int KEYCODE_PROG_BLUE       = 186;
    /** Key code constant: App switch key.
     * Should bring up the application switcher dialog. */
    public static final int KEYCODE_APP_SWITCH      = 187;


    private static final int LAST_KEYCODE           = KEYCODE_PROG_BLUE;
    private static final int LAST_KEYCODE           = KEYCODE_APP_SWITCH;


    // NOTE: If you add a new keycode here you must also add it to:
    // NOTE: If you add a new keycode here you must also add it to:
    //  isSystem()
    //  isSystem()
    //  native/include/android/keycodes.h
    //  native/include/android/keycodes.h
    //  frameworks/base/include/ui/KeycodeLabels.h
    //  frameworks/base/include/ui/KeycodeLabels.h
    //  external/webkit/WebKit/android/plugins/ANPKeyCodes.h
    //  external/webkit/WebKit/android/plugins/ANPKeyCodes.h
    //  tools/puppet_master/PuppetMaster/nav_keys.py
    //  frameworks/base/core/res/res/values/attrs.xml
    //  frameworks/base/core/res/res/values/attrs.xml
    //  emulator?
    //  emulator?
    //
    //
@@ -737,6 +739,7 @@ public class KeyEvent extends InputEvent implements Parcelable {
        "KEYCODE_PROG_GREEN",
        "KEYCODE_PROG_GREEN",
        "KEYCODE_PROG_YELLOW",
        "KEYCODE_PROG_YELLOW",
        "KEYCODE_PROG_BLUE",
        "KEYCODE_PROG_BLUE",
        "KEYCODE_APP_SWITCH",
    };
    };


    // Symbolic names of all metakeys in bit order from least significant to most significant.
    // Symbolic names of all metakeys in bit order from least significant to most significant.
@@ -1057,6 +1060,16 @@ public class KeyEvent extends InputEvent implements Parcelable {
     */
     */
    public static final int FLAG_TRACKING = 0x200;
    public static final int FLAG_TRACKING = 0x200;


    /**
     * Set when a key event has been synthesized to implement default behavior
     * for an event that the application did not handle.
     * Fallback key events are generated by unhandled trackball motions
     * (to emulate a directional keypad) and by certain unhandled key presses
     * that are declared in the key map (such as special function numeric keypad
     * keys when numlock is off).
     */
    public static final int FLAG_FALLBACK = 0x400;

    /**
    /**
     * Private control to determine when an app is tracking a key sequence.
     * Private control to determine when an app is tracking a key sequence.
     * @hide
     * @hide
+1 −1
Original line number Original line Diff line number Diff line
@@ -556,7 +556,7 @@ import java.util.WeakHashMap;
 * improve the security of views that provide access to sensitive functionality.
 * improve the security of views that provide access to sensitive functionality.
 * </p><p>
 * </p><p>
 * To enable touch filtering, call {@link #setFilterTouchesWhenObscured} or set the
 * To enable touch filtering, call {@link #setFilterTouchesWhenObscured} or set the
 * andoird:filterTouchesWhenObscured attribute to true.  When enabled, the framework
 * android:filterTouchesWhenObscured layout attribute to true.  When enabled, the framework
 * will discard touches that are received whenever the view's window is obscured by
 * will discard touches that are received whenever the view's window is obscured by
 * another visible window.  As a result, the view will not receive touches whenever a
 * another visible window.  As a result, the view will not receive touches whenever a
 * toast, dialog or other window appears above the view's window.
 * toast, dialog or other window appears above the view's window.
+18 −10
Original line number Original line Diff line number Diff line
@@ -2310,21 +2310,23 @@ public final class ViewRoot extends Handler implements ViewParent,
        }
        }


        final int action = event.getAction();
        final int action = event.getAction();
        final int metastate = event.getMetaState();
        final int metaState = event.getMetaState();
        switch (action) {
        switch (action) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_DOWN:
                x.reset(2);
                x.reset(2);
                y.reset(2);
                y.reset(2);
                deliverKeyEvent(new KeyEvent(curTime, curTime,
                deliverKeyEvent(new KeyEvent(curTime, curTime,
                        KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER,
                        KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER, 0, metaState,
                        0, metastate), false);
                        KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
                        InputDevice.SOURCE_KEYBOARD), false);
                break;
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_UP:
                x.reset(2);
                x.reset(2);
                y.reset(2);
                y.reset(2);
                deliverKeyEvent(new KeyEvent(curTime, curTime,
                deliverKeyEvent(new KeyEvent(curTime, curTime,
                        KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER,
                        KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER, 0, metaState,
                        0, metastate), false);
                        KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
                        InputDevice.SOURCE_KEYBOARD), false);
                break;
                break;
        }
        }


@@ -2374,9 +2376,11 @@ public final class ViewRoot extends Handler implements ViewParent,
                if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
                if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
                        + keycode);
                        + keycode);
                movement--;
                movement--;
                int repeatCount = accelMovement - movement;
                deliverKeyEvent(new KeyEvent(curTime, curTime,
                deliverKeyEvent(new KeyEvent(curTime, curTime,
                        KeyEvent.ACTION_MULTIPLE, keycode,
                        KeyEvent.ACTION_MULTIPLE, keycode, repeatCount, metaState,
                        accelMovement-movement, metastate), false);
                        KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
                        InputDevice.SOURCE_KEYBOARD), false);
            }
            }
            while (movement > 0) {
            while (movement > 0) {
                if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
                if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
@@ -2384,9 +2388,13 @@ public final class ViewRoot extends Handler implements ViewParent,
                movement--;
                movement--;
                curTime = SystemClock.uptimeMillis();
                curTime = SystemClock.uptimeMillis();
                deliverKeyEvent(new KeyEvent(curTime, curTime,
                deliverKeyEvent(new KeyEvent(curTime, curTime,
                        KeyEvent.ACTION_DOWN, keycode, 0, event.getMetaState()), false);
                        KeyEvent.ACTION_DOWN, keycode, 0, metaState,
                        KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
                        InputDevice.SOURCE_KEYBOARD), false);
                deliverKeyEvent(new KeyEvent(curTime, curTime,
                deliverKeyEvent(new KeyEvent(curTime, curTime,
                        KeyEvent.ACTION_UP, keycode, 0, metastate), false);
                        KeyEvent.ACTION_UP, keycode, 0, metaState,
                        KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
                        InputDevice.SOURCE_KEYBOARD), false);
                }
                }
            mLastTrackballTime = curTime;
            mLastTrackballTime = curTime;
        }
        }
Loading