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

Commit a7739acf authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka Committed by Android Git Automerger
Browse files

am b7f62601: Merge "Move non-distinct multitouch support to a separate class"

* commit 'b7f62601':
  Move non-distinct multitouch support to a separate class
parents 52977770 b7f62601
Loading
Loading
Loading
Loading
+17 −63
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import com.android.inputmethod.keyboard.internal.GestureFloatingPreviewText;
import com.android.inputmethod.keyboard.internal.GestureTrailsPreview;
import com.android.inputmethod.keyboard.internal.KeyDrawParams;
import com.android.inputmethod.keyboard.internal.KeyPreviewDrawParams;
import com.android.inputmethod.keyboard.internal.NonDistinctMultitouchHelper;
import com.android.inputmethod.keyboard.internal.PreviewPlacerView;
import com.android.inputmethod.keyboard.internal.SlidingKeyInputPreview;
import com.android.inputmethod.latin.Constants;
@@ -179,9 +180,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
    private int mGestureFloatingPreviewTextLingerTimeout;

    private KeyDetector mKeyDetector;
    private final boolean mHasDistinctMultitouch;
    private int mOldPointerCount = 1;
    private Key mOldKey;
    private final NonDistinctMultitouchHelper mNonDistinctMultitouchHelper;

    private final KeyTimerHandler mKeyTimerHandler;

@@ -423,13 +422,16 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
    public MainKeyboardView(final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);

        PointerTracker.init(getResources());
        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        final boolean forceNonDistinctMultitouch = prefs.getBoolean(
                DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH, false);
        final boolean hasDistinctMultitouch = context.getPackageManager()
                .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
        mHasDistinctMultitouch = hasDistinctMultitouch && !forceNonDistinctMultitouch;
        PointerTracker.init(getResources());
                .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT)
                && !forceNonDistinctMultitouch;
        mNonDistinctMultitouchHelper = hasDistinctMultitouch ? null
                : new NonDistinctMultitouchHelper();

        mPreviewPlacerView = new PreviewPlacerView(context, attrs);

        final TypedArray mainKeyboardViewAttr = context.obtainStyledAttributes(
@@ -1032,25 +1034,21 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
        if (getKeyboard() == null) {
            return false;
        }
        // TODO: Add multi-touch to single-touch event converter for non-distinct multi-touch
        // device.
        if (mNonDistinctMultitouchHelper != null) {
            if (me.getPointerCount() > 1 && mKeyTimerHandler.isInKeyRepeat()) {
                // Key repeating timer will be canceled if 2 or more keys are in action.
                mKeyTimerHandler.cancelKeyRepeatTimer();
            }
            // Non distinct multitouch screen support
            mNonDistinctMultitouchHelper.processMotionEvent(me, this);
            return true;
        }
        return processMotionEvent(me);
    }

    public boolean processMotionEvent(final MotionEvent me) {
        final boolean nonDistinctMultitouch = !mHasDistinctMultitouch;
        final int action = me.getActionMasked();
        final int pointerCount = me.getPointerCount();
        final int oldPointerCount = mOldPointerCount;
        mOldPointerCount = pointerCount;

        // TODO: cleanup this code into a multi-touch to single-touch event converter class?
        // If the device does not have distinct multi-touch support panel, ignore all multi-touch
        // events except a transition from/to single-touch.
        if (nonDistinctMultitouch && pointerCount > 1 && oldPointerCount > 1) {
            return true;
        }

        final long eventTime = me.getEventTime();
        final int index = me.getActionIndex();
        final int id = me.getPointerId(index);
@@ -1068,50 +1066,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
                    me, action, eventTime, index, id, x, y);
        }

        if (mKeyTimerHandler.isInKeyRepeat()) {
            final PointerTracker tracker = PointerTracker.getPointerTracker(id, this);
            // Key repeating timer will be canceled if 2 or more keys are in action, and current
            // event (UP or DOWN) is non-modifier key.
            if (pointerCount > 1 && !tracker.isModifier()) {
                mKeyTimerHandler.cancelKeyRepeatTimer();
            }
            // Up event will pass through.
        }

        // TODO: cleanup this code into a multi-touch to single-touch event converter class?
        // Translate mutli-touch event to single-touch events on the device that has no distinct
        // multi-touch panel.
        if (nonDistinctMultitouch) {
            // Use only main (id=0) pointer tracker.
            final PointerTracker tracker = PointerTracker.getPointerTracker(0, this);
            if (pointerCount == 1 && oldPointerCount == 2) {
                // Multi-touch to single touch transition.
                // Send a down event for the latest pointer if the key is different from the
                // previous key.
                final Key newKey = tracker.getKeyOn(x, y);
                if (mOldKey != newKey) {
                    tracker.onDownEvent(x, y, eventTime, this);
                    if (action == MotionEvent.ACTION_UP) {
                        tracker.onUpEvent(x, y, eventTime);
                    }
                }
            } else if (pointerCount == 2 && oldPointerCount == 1) {
                // Single-touch to multi-touch transition.
                // Send an up event for the last pointer.
                final int[] lastCoords = CoordinateUtils.newInstance();
                mOldKey = tracker.getKeyOn(
                        CoordinateUtils.x(lastCoords), CoordinateUtils.y(lastCoords));
                tracker.onUpEvent(
                        CoordinateUtils.x(lastCoords), CoordinateUtils.y(lastCoords), eventTime);
            } else if (pointerCount == 1 && oldPointerCount == 1) {
                tracker.processMotionEvent(action, x, y, eventTime, this);
            } else {
                Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount
                        + " (old " + oldPointerCount + ")");
            }
            return true;
        }

        if (action == MotionEvent.ACTION_MOVE) {
            for (int i = 0; i < pointerCount; i++) {
                final int pointerId = me.getPointerId(i);
+5 −4
Original line number Diff line number Diff line
@@ -478,6 +478,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
        mPointerId = id;
        mGestureStrokeWithPreviewPoints = new GestureStrokeWithPreviewPoints(
                id, sGestureStrokeParams, sGesturePreviewParams);
        setKeyEventHandler(handler);
    }

    private void setKeyEventHandler(final KeyEventHandler handler) {
        setKeyDetectorInner(handler.getKeyDetector());
        mListener = handler.getKeyboardActionListener();
        mDrawingProxy = handler.getDrawingProxy();
@@ -891,10 +895,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
        if (DEBUG_EVENT) {
            printTouchEvent("onDownEvent:", x, y, eventTime);
        }
        mDrawingProxy = handler.getDrawingProxy();
        mTimerProxy = handler.getTimerProxy();
        setKeyboardActionListener(handler.getKeyboardActionListener());
        setKeyDetectorInner(handler.getKeyDetector());
        setKeyEventHandler(handler);
        // Naive up-to-down noise filter.
        final long deltaT = eventTime - mUpTime;
        if (deltaT < sParams.mTouchNoiseThresholdTime) {
+90 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.inputmethod.keyboard.internal;

import android.util.Log;
import android.view.MotionEvent;

import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.PointerTracker;
import com.android.inputmethod.keyboard.PointerTracker.KeyEventHandler;
import com.android.inputmethod.latin.utils.CoordinateUtils;

public final class NonDistinctMultitouchHelper {
    private static final String TAG = NonDistinctMultitouchHelper.class.getSimpleName();

    private int mOldPointerCount = 1;
    private Key mOldKey;

    public void processMotionEvent(final MotionEvent me, final KeyEventHandler keyEventHandler) {
        final int pointerCount = me.getPointerCount();
        final int oldPointerCount = mOldPointerCount;
        mOldPointerCount = pointerCount;
        // Ignore continuous multitouch events because we can't trust the coordinates in mulitouch
        // events.
        if (pointerCount > 1 && oldPointerCount > 1) {
            return;
        }

        final int action = me.getActionMasked();
        final int index = me.getActionIndex();
        final long eventTime = me.getEventTime();
        final int x = (int)me.getX(index);
        final int y = (int)me.getY(index);
        // Use only main (id=0) pointer tracker.
        final PointerTracker mainTracker = PointerTracker.getPointerTracker(0, keyEventHandler);

        // In single touch.
        if (oldPointerCount == 1 && pointerCount == 1) {
            mainTracker.processMotionEvent(action, x, y, eventTime, keyEventHandler);
            return;
        }

        // Single-touch to multi-touch transition.
        if (oldPointerCount == 1 && pointerCount == 2) {
            // Send an up event for the last pointer, be cause we can't trust the corrdinates of
            // this multitouch event.
            final int[] lastCoords = CoordinateUtils.newInstance();
            mainTracker.getLastCoordinates(lastCoords);
            mOldKey = mainTracker.getKeyOn(
                    CoordinateUtils.x(lastCoords), CoordinateUtils.y(lastCoords));
            // TODO: Stop calling PointerTracker.onUpEvent directly.
            mainTracker.onUpEvent(
                    CoordinateUtils.x(lastCoords), CoordinateUtils.y(lastCoords), eventTime);
            return;
        }

        // Multi-touch to single touch transition.
        if (oldPointerCount == 2 && pointerCount == 1) {
            // Send a down event for the latest pointer if the key is different from the
            // previous key.
            final Key newKey = mainTracker.getKeyOn(x, y);
            if (mOldKey != newKey) {
                // TODO: Stop calling PointerTracker.onDownEvent directly.
                mainTracker.onDownEvent(x, y, eventTime, keyEventHandler);
                if (action == MotionEvent.ACTION_UP) {
                    // TODO: Stop calling PointerTracker.onUpEvent directly.
                    mainTracker.onUpEvent(x, y, eventTime);
                }
            }
            return;
        }

        Log.w(TAG, "Unknown touch panel behavior: pointer count is "
                + pointerCount + " (previously " + oldPointerCount + ")");
    }
}