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

Commit f1f186c7 authored by Taran Singh's avatar Taran Singh Committed by Automerger Merge Worker
Browse files

DO NOT MERGE: Verify KeyEvents in IME am: ca6ddbf9

parents 4cccf6cf ca6ddbf9
Loading
Loading
Loading
Loading
+37 −2
Original line number Diff line number Diff line
@@ -19,9 +19,11 @@ package android.inputmethodservice;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.graphics.Rect;
import android.hardware.input.InputManager;
import android.os.Bundle;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.util.SparseArray;
import android.view.InputChannel;
@@ -41,6 +43,8 @@ import com.android.internal.os.SomeArgs;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodSession;

import java.util.Objects;

class IInputMethodSessionWrapper extends IInputMethodSession.Stub
        implements HandlerCaller.Callback {
    private static final String TAG = "InputMethodWrapper";
@@ -56,6 +60,7 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
    private static final int DO_REMOVE_IME_SURFACE = 130;
    private static final int DO_FINISH_INPUT = 140;
    private static final int DO_INVALIDATE_INPUT = 150;
    private final Context mContext;


    @UnsupportedAppUsage
@@ -66,6 +71,7 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub

    public IInputMethodSessionWrapper(Context context,
            InputMethodSession inputMethodSession, InputChannel channel) {
        mContext = context;
        mCaller = new HandlerCaller(context, null,
                this, true /*asyncHandler*/);
        mInputMethodSession = inputMethodSession;
@@ -232,6 +238,8 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
    }
    private final class ImeInputEventReceiver extends InputEventReceiver
            implements InputMethodSession.EventCallback {
        // Time after which a KeyEvent is invalid
        private static final long KEY_EVENT_ALLOW_PERIOD_MS = 100L;
        private final SparseArray<InputEvent> mPendingEvents = new SparseArray<InputEvent>();

        public ImeInputEventReceiver(InputChannel inputChannel, Looper looper) {
@@ -246,10 +254,27 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
                return;
            }

            KeyEvent keyEvent = null;
            if (event != null && event instanceof KeyEvent) {
                keyEvent = (KeyEvent) event;
                if (hasKeyModifiers(keyEvent)) {
                    // any KeyEvent with modifiers (e.g. Ctrl/Alt/Fn) must be verified that
                    // they originated from system.
                    InputManager im = mContext.getSystemService(InputManager.class);
                    Objects.requireNonNull(im);
                    final long age = SystemClock.uptimeMillis() - keyEvent.getEventTime();
                    if (age >= KEY_EVENT_ALLOW_PERIOD_MS || im.verifyInputEvent(keyEvent) == null) {
                        Log.w(TAG, "Unverified or Invalid KeyEvent injected into IME. Dropping "
                                + keyEvent);
                        finishInputEvent(event, false /* handled */);
                        return;
                    }
                }
            }

            final int seq = event.getSequenceNumber();
            mPendingEvents.put(seq, event);
            if (event instanceof KeyEvent) {
                KeyEvent keyEvent = (KeyEvent)event;
            if (keyEvent != null) {
                mInputMethodSession.dispatchKeyEvent(seq, keyEvent, this);
            } else {
                MotionEvent motionEvent = (MotionEvent)event;
@@ -270,5 +295,15 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
                finishInputEvent(event, handled);
            }
        }

        private boolean hasKeyModifiers(KeyEvent event) {
            if (event.hasNoModifiers()) {
                return false;
            }
            return event.isCtrlPressed()
                    || event.isAltPressed()
                    || event.isFunctionPressed()
                    || event.isMetaPressed();
        }
    }
}