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

Commit 30f420fd authored by keunyoung's avatar keunyoung
Browse files

add local focus mode and input event injection API to Window

 - This enables keyboard navigation for window without focus.
 - FLAG_LOCAL_FOCUS_MODE puts window into local focus mode.
 - Application needs to put window in local focus mode, control focus, and
   inject events to make dpad navigation work.
 - Window in local focus mode does not interact with window manager or ime
   regarding focus related events.
 - Also renamed ViewRootImpl.dispatchKey to dispatchInputEvent to allow both key and touch events injection.

Change-Id: I8e8561f29e0dade3797fb7ae3ee7690e6b7f8895
parent 37ee68fc
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -27827,6 +27827,7 @@ package android.view {
    method public final boolean hasChildren();
    method public final boolean hasChildren();
    method public boolean hasFeature(int);
    method public boolean hasFeature(int);
    method protected final boolean hasSoftInputMode();
    method protected final boolean hasSoftInputMode();
    method public void injectInputEvent(android.view.InputEvent);
    method public abstract void invalidatePanelMenu(int);
    method public abstract void invalidatePanelMenu(int);
    method public final boolean isActive();
    method public final boolean isActive();
    method public abstract boolean isFloating();
    method public abstract boolean isFloating();
@@ -27864,6 +27865,7 @@ package android.view {
    method public void setGravity(int);
    method public void setGravity(int);
    method public void setIcon(int);
    method public void setIcon(int);
    method public void setLayout(int, int);
    method public void setLayout(int, int);
    method public void setLocalFocus(boolean, boolean);
    method public void setLogo(int);
    method public void setLogo(int);
    method public void setSoftInputMode(int);
    method public void setSoftInputMode(int);
    method public abstract void setTitle(java.lang.CharSequence);
    method public abstract void setTitle(java.lang.CharSequence);
@@ -28002,6 +28004,7 @@ package android.view {
    field public static final int FLAG_LAYOUT_IN_OVERSCAN = 33554432; // 0x2000000
    field public static final int FLAG_LAYOUT_IN_OVERSCAN = 33554432; // 0x2000000
    field public static final int FLAG_LAYOUT_IN_SCREEN = 256; // 0x100
    field public static final int FLAG_LAYOUT_IN_SCREEN = 256; // 0x100
    field public static final int FLAG_LAYOUT_NO_LIMITS = 512; // 0x200
    field public static final int FLAG_LAYOUT_NO_LIMITS = 512; // 0x200
    field public static final int FLAG_LOCAL_FOCUS_MODE = 268435456; // 0x10000000
    field public static final int FLAG_NOT_FOCUSABLE = 8; // 0x8
    field public static final int FLAG_NOT_FOCUSABLE = 8; // 0x8
    field public static final int FLAG_NOT_TOUCHABLE = 16; // 0x10
    field public static final int FLAG_NOT_TOUCHABLE = 16; // 0x10
    field public static final int FLAG_NOT_TOUCH_MODAL = 32; // 0x20
    field public static final int FLAG_NOT_TOUCH_MODAL = 32; // 0x20
+21 −13
Original line number Original line Diff line number Diff line
@@ -608,6 +608,11 @@ public final class ViewRootImpl implements ViewParent,
        }
        }
    }
    }


    /** Whether the window is in local focus mode or not */
    private boolean isInLocalFocusMode() {
        return (mWindowAttributes.flags & WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE) != 0;
    }

    void destroyHardwareResources() {
    void destroyHardwareResources() {
        if (mAttachInfo.mHardwareRenderer != null) {
        if (mAttachInfo.mHardwareRenderer != null) {
            if (mAttachInfo.mHardwareRenderer.isEnabled()) {
            if (mAttachInfo.mHardwareRenderer.isEnabled()) {
@@ -1818,7 +1823,7 @@ public final class ViewRootImpl implements ViewParent,
        mNewSurfaceNeeded = false;
        mNewSurfaceNeeded = false;
        mViewVisibility = viewVisibility;
        mViewVisibility = viewVisibility;


        if (mAttachInfo.mHasWindowFocus) {
        if (mAttachInfo.mHasWindowFocus && !isInLocalFocusMode()) {
            final boolean imTarget = WindowManager.LayoutParams
            final boolean imTarget = WindowManager.LayoutParams
                    .mayUseInputMethod(mWindowAttributes.flags);
                    .mayUseInputMethod(mWindowAttributes.flags);
            if (imTarget != mLastWasImTarget) {
            if (imTarget != mLastWasImTarget) {
@@ -2906,7 +2911,7 @@ public final class ViewRootImpl implements ViewParent,
    private final static int MSG_RESIZED = 4;
    private final static int MSG_RESIZED = 4;
    private final static int MSG_RESIZED_REPORT = 5;
    private final static int MSG_RESIZED_REPORT = 5;
    private final static int MSG_WINDOW_FOCUS_CHANGED = 6;
    private final static int MSG_WINDOW_FOCUS_CHANGED = 6;
    private final static int MSG_DISPATCH_KEY = 7;
    private final static int MSG_DISPATCH_INPUT_EVENT = 7;
    private final static int MSG_DISPATCH_APP_VISIBILITY = 8;
    private final static int MSG_DISPATCH_APP_VISIBILITY = 8;
    private final static int MSG_DISPATCH_GET_NEW_SURFACE = 9;
    private final static int MSG_DISPATCH_GET_NEW_SURFACE = 9;
    private final static int MSG_DISPATCH_KEY_FROM_IME = 11;
    private final static int MSG_DISPATCH_KEY_FROM_IME = 11;
@@ -2941,8 +2946,8 @@ public final class ViewRootImpl implements ViewParent,
                    return "MSG_RESIZED_REPORT";
                    return "MSG_RESIZED_REPORT";
                case MSG_WINDOW_FOCUS_CHANGED:
                case MSG_WINDOW_FOCUS_CHANGED:
                    return "MSG_WINDOW_FOCUS_CHANGED";
                    return "MSG_WINDOW_FOCUS_CHANGED";
                case MSG_DISPATCH_KEY:
                case MSG_DISPATCH_INPUT_EVENT:
                    return "MSG_DISPATCH_KEY";
                    return "MSG_DISPATCH_INPUT_EVENT";
                case MSG_DISPATCH_APP_VISIBILITY:
                case MSG_DISPATCH_APP_VISIBILITY:
                    return "MSG_DISPATCH_APP_VISIBILITY";
                    return "MSG_DISPATCH_APP_VISIBILITY";
                case MSG_DISPATCH_GET_NEW_SURFACE:
                case MSG_DISPATCH_GET_NEW_SURFACE:
@@ -3092,7 +3097,8 @@ public final class ViewRootImpl implements ViewParent,


                    InputMethodManager imm = InputMethodManager.peekInstance();
                    InputMethodManager imm = InputMethodManager.peekInstance();
                    if (mView != null) {
                    if (mView != null) {
                        if (hasWindowFocus && imm != null && mLastWasImTarget) {
                        if (hasWindowFocus && imm != null && mLastWasImTarget &&
                                !isInLocalFocusMode()) {
                            imm.startGettingWindowFocus(mView);
                            imm.startGettingWindowFocus(mView);
                        }
                        }
                        mAttachInfo.mKeyDispatchState.reset();
                        mAttachInfo.mKeyDispatchState.reset();
@@ -3103,7 +3109,7 @@ public final class ViewRootImpl implements ViewParent,
                    // Note: must be done after the focus change callbacks,
                    // Note: must be done after the focus change callbacks,
                    // so all of the view state is set up correctly.
                    // so all of the view state is set up correctly.
                    if (hasWindowFocus) {
                    if (hasWindowFocus) {
                        if (imm != null && mLastWasImTarget) {
                        if (imm != null && mLastWasImTarget && !isInLocalFocusMode()) {
                            imm.onWindowFocus(mView, mView.findFocus(),
                            imm.onWindowFocus(mView, mView.findFocus(),
                                    mWindowAttributes.softInputMode,
                                    mWindowAttributes.softInputMode,
                                    !mHasHadWindowFocus, mWindowAttributes.flags);
                                    !mHasHadWindowFocus, mWindowAttributes.flags);
@@ -3131,8 +3137,8 @@ public final class ViewRootImpl implements ViewParent,
            case MSG_DIE:
            case MSG_DIE:
                doDie();
                doDie();
                break;
                break;
            case MSG_DISPATCH_KEY: {
            case MSG_DISPATCH_INPUT_EVENT: {
                KeyEvent event = (KeyEvent)msg.obj;
                InputEvent event = (InputEvent)msg.obj;
                enqueueInputEvent(event, null, 0, true);
                enqueueInputEvent(event, null, 0, true);
            } break;
            } break;
            case MSG_DISPATCH_KEY_FROM_IME: {
            case MSG_DISPATCH_KEY_FROM_IME: {
@@ -3222,7 +3228,9 @@ public final class ViewRootImpl implements ViewParent,


        // tell the window manager
        // tell the window manager
        try {
        try {
            if (!isInLocalFocusMode()) {
                mWindowSession.setInTouchMode(inTouchMode);
                mWindowSession.setInTouchMode(inTouchMode);
            }
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            throw new RuntimeException(e);
            throw new RuntimeException(e);
        }
        }
@@ -3624,7 +3632,7 @@ public final class ViewRootImpl implements ViewParent,


        @Override
        @Override
        protected int onProcess(QueuedInputEvent q) {
        protected int onProcess(QueuedInputEvent q) {
            if (mLastWasImTarget) {
            if (mLastWasImTarget && !isInLocalFocusMode()) {
                InputMethodManager imm = InputMethodManager.peekInstance();
                InputMethodManager imm = InputMethodManager.peekInstance();
                if (imm != null) {
                if (imm != null) {
                    final InputEvent event = q.mEvent;
                    final InputEvent event = q.mEvent;
@@ -5666,8 +5674,8 @@ public final class ViewRootImpl implements ViewParent,
        mInvalidateOnAnimationRunnable.removeView(view);
        mInvalidateOnAnimationRunnable.removeView(view);
    }
    }


    public void dispatchKey(KeyEvent event) {
    public void dispatchInputEvent(InputEvent event) {
        Message msg = mHandler.obtainMessage(MSG_DISPATCH_KEY, event);
        Message msg = mHandler.obtainMessage(MSG_DISPATCH_INPUT_EVENT, event);
        msg.setAsynchronous(true);
        msg.setAsynchronous(true);
        mHandler.sendMessage(msg);
        mHandler.sendMessage(msg);
    }
    }
@@ -5697,7 +5705,7 @@ public final class ViewRootImpl implements ViewParent,
                        flags, event.getSource(), null);
                        flags, event.getSource(), null);
                fallbackAction.recycle();
                fallbackAction.recycle();


                dispatchKey(fallbackEvent);
                dispatchInputEvent(fallbackEvent);
            }
            }
        }
        }
    }
    }
+14 −0
Original line number Original line Diff line number Diff line
@@ -1290,4 +1290,18 @@ public abstract class Window {
     * @hide
     * @hide
     */
     */
    public void setDefaultLogo(int resId) { }
    public void setDefaultLogo(int resId) { }

    /**
     * Set focus locally. The window should have the
     * {@link WindowManager.LayoutParams#FLAG_LOCAL_FOCUS_MODE} flag set already.
     * @param hasFocus Whether this window has focus or not.
     * @param inTouchMode Whether this window is in touch mode or not.
     */
    public void setLocalFocus(boolean hasFocus, boolean inTouchMode) { }

    /**
     * Inject an event to window locally.
     * @param event A key or touch event to inject to this window.
     */
    public void injectInputEvent(InputEvent event) { }
}
}
+13 −1
Original line number Original line Diff line number Diff line
@@ -866,6 +866,15 @@ public interface WindowManager extends ViewManager {
         */
         */
        public static final int FLAG_NEEDS_MENU_KEY = 0x08000000;
        public static final int FLAG_NEEDS_MENU_KEY = 0x08000000;


        /**
         * Flag for a window in local focus mode.
         * Window in local focus mode can control focus independent of window manager using
         * {@link Window#setLocalFocus(boolean, boolean)}.
         * Usually window in this mode will not get touch/key events from window manager, but will
         * get events only via local injection using {@link Window#injectInputEvent(InputEvent)}.
         */
        public static final int FLAG_LOCAL_FOCUS_MODE = 0x10000000;

        /** Window flag: special flag to limit the size of the window to be
        /** Window flag: special flag to limit the size of the window to be
         * original size ([320x480] x density). Used to create window for applications
         * original size ([320x480] x density). Used to create window for applications
         * running under compatibility mode.
         * running under compatibility mode.
@@ -905,6 +914,7 @@ public interface WindowManager extends ViewManager {
         * @see #FLAG_DISMISS_KEYGUARD
         * @see #FLAG_DISMISS_KEYGUARD
         * @see #FLAG_SPLIT_TOUCH
         * @see #FLAG_SPLIT_TOUCH
         * @see #FLAG_HARDWARE_ACCELERATED
         * @see #FLAG_HARDWARE_ACCELERATED
         * @see #FLAG_LOCAL_FOCUS_MODE
         */
         */
        @ViewDebug.ExportedProperty(flagMapping = {
        @ViewDebug.ExportedProperty(flagMapping = {
            @ViewDebug.FlagToString(mask = FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, equals = FLAG_ALLOW_LOCK_WHILE_SCREEN_ON,
            @ViewDebug.FlagToString(mask = FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, equals = FLAG_ALLOW_LOCK_WHILE_SCREEN_ON,
@@ -956,7 +966,9 @@ public interface WindowManager extends ViewManager {
            @ViewDebug.FlagToString(mask = FLAG_SPLIT_TOUCH, equals = FLAG_SPLIT_TOUCH,
            @ViewDebug.FlagToString(mask = FLAG_SPLIT_TOUCH, equals = FLAG_SPLIT_TOUCH,
                    name = "FLAG_SPLIT_TOUCH"),
                    name = "FLAG_SPLIT_TOUCH"),
            @ViewDebug.FlagToString(mask = FLAG_HARDWARE_ACCELERATED, equals = FLAG_HARDWARE_ACCELERATED,
            @ViewDebug.FlagToString(mask = FLAG_HARDWARE_ACCELERATED, equals = FLAG_HARDWARE_ACCELERATED,
                    name = "FLAG_HARDWARE_ACCELERATED")
                    name = "FLAG_HARDWARE_ACCELERATED"),
            @ViewDebug.FlagToString(mask = FLAG_LOCAL_FOCUS_MODE, equals = FLAG_LOCAL_FOCUS_MODE,
                    name = "FLAG_LOCAL_FOCUS_MODE")
        })
        })
        public int flags;
        public int flags;


+1 −1
Original line number Original line Diff line number Diff line
@@ -503,7 +503,7 @@ public class ZoomButtonsController implements View.OnTouchListener {


            ViewRootImpl viewRoot = mOwnerView.getViewRootImpl();
            ViewRootImpl viewRoot = mOwnerView.getViewRootImpl();
            if (viewRoot != null) {
            if (viewRoot != null) {
                viewRoot.dispatchKey(event);
                viewRoot.dispatchInputEvent(event);
            }
            }


            // We gave the key to the owner, don't let the container handle this key
            // We gave the key to the owner, don't let the container handle this key
Loading