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

Commit 310ea9ab authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka
Browse files

Remove sudden jump touch event hack

This hack was for Nexus One and Droid that can't run on ICS or later.

Change-Id: I1f9cef2022b0bbb333235e6b7c311c9785a1d894
parent 3b5c05f1
Loading
Loading
Loading
Loading
+0 −31
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2011, 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.
*/
-->
<resources>
    <string-array name="sudden_jumping_touch_event_device_list" translatable="false">
        <!-- "Build condition,true" that needs "sudden jump touch event" hack.
             See {@link com.android.inputmethod.keyboard.SuddenJumpingTouchEventHandler}. -->
        <!-- Nexus One -->
        <item>HARDWARE=mahimahi,true</item>
        <!-- Droid -->
        <item>HARDWARE=sholes,true</item>
        <!-- Default value for unknown device -->
        <item>,false</item>
    </string-array>
</resources>
+4 −10
Original line number Diff line number Diff line
@@ -55,7 +55,6 @@ import com.android.inputmethod.keyboard.internal.KeyDrawParams;
import com.android.inputmethod.keyboard.internal.KeyPreviewDrawParams;
import com.android.inputmethod.keyboard.internal.PreviewPlacerView;
import com.android.inputmethod.keyboard.internal.SlidingKeyInputPreview;
import com.android.inputmethod.keyboard.internal.TouchScreenRegulator;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
@@ -115,8 +114,7 @@ import java.util.WeakHashMap;
 * @attr ref R.styleable#MainKeyboardView_suppressKeyPreviewAfterBatchInputDuration
 */
public final class MainKeyboardView extends KeyboardView implements PointerTracker.KeyEventHandler,
        PointerTracker.DrawingProxy, MoreKeysPanel.Controller,
        TouchScreenRegulator.ProcessMotionEvent {
        PointerTracker.DrawingProxy, MoreKeysPanel.Controller {
    private static final String TAG = MainKeyboardView.class.getSimpleName();

    // TODO: Kill process when the usability study mode was changed.
@@ -183,8 +181,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
    // TODO: Make this parameter customizable by user via settings.
    private int mGestureFloatingPreviewTextLingerTimeout;

    private final TouchScreenRegulator mTouchScreenRegulator;

    private KeyDetector mKeyDetector;
    private final boolean mHasDistinctMultitouch;
    private int mOldPointerCount = 1;
@@ -450,8 +446,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
    public MainKeyboardView(final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);

        mTouchScreenRegulator = new TouchScreenRegulator(context, this);

        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        final boolean forceNonDistinctMultitouch = prefs.getBoolean(
                DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH, false);
@@ -628,7 +622,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
        mKeyDetector.setKeyboard(
                keyboard, -getPaddingLeft(), -getPaddingTop() + getVerticalCorrection());
        PointerTracker.setKeyDetector(mKeyDetector);
        mTouchScreenRegulator.setKeyboardGeometry(keyboard.mOccupiedWidth);
        mMoreKeysKeyboardCache.clear();

        mSpaceKey = keyboard.getKey(Constants.CODE_SPACE);
@@ -1050,10 +1043,11 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
        if (getKeyboard() == null) {
            return false;
        }
        return mTouchScreenRegulator.onTouchEvent(me);
        // TODO: Add multi-touch to single-touch event converter for non-distinct multi-touch
        // device.
        return processMotionEvent(me);
    }

    @Override
    public boolean processMotionEvent(final MotionEvent me) {
        final boolean nonDistinctMultitouch = !mHasDistinctMultitouch;
        final int action = me.getActionMasked();
+0 −155
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 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.content.Context;
import android.util.Log;
import android.view.MotionEvent;

import com.android.inputmethod.keyboard.MainKeyboardView;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.utils.ResourceUtils;
import com.android.inputmethod.research.ResearchLogger;

public final class TouchScreenRegulator {
    private static final String TAG = TouchScreenRegulator.class.getSimpleName();
    private static boolean DEBUG_MODE = LatinImeLogger.sDBG;

    public interface ProcessMotionEvent {
        public boolean processMotionEvent(MotionEvent me);
    }

    private final ProcessMotionEvent mView;
    private final boolean mNeedsSuddenJumpingHack;

    /** Whether we've started dropping move events because we found a big jump */
    private boolean mDroppingEvents;
    /**
     * Whether multi-touch disambiguation needs to be disabled if a real multi-touch event has
     * occured
     */
    private boolean mDisableDisambiguation;
    /** The distance threshold at which we start treating the touch session as a multi-touch */
    private int mJumpThresholdSquare = Integer.MAX_VALUE;
    private int mLastX;
    private int mLastY;
    // One-seventh of the keyboard width seems like a reasonable threshold
    private static final float JUMP_THRESHOLD_RATIO_TO_KEYBOARD_WIDTH = 1.0f / 7.0f;

    public TouchScreenRegulator(final Context context, final ProcessMotionEvent view) {
        mView = view;
        mNeedsSuddenJumpingHack = Boolean.parseBoolean(ResourceUtils.getDeviceOverrideValue(
                context.getResources(), R.array.sudden_jumping_touch_event_device_list));
    }

    public void setKeyboardGeometry(final int keyboardWidth) {
        final float jumpThreshold = keyboardWidth * JUMP_THRESHOLD_RATIO_TO_KEYBOARD_WIDTH;
        mJumpThresholdSquare = (int)(jumpThreshold * jumpThreshold);
    }

    /**
     * This function checks to see if we need to handle any sudden jumps in the pointer location
     * that could be due to a multi-touch being treated as a move by the firmware or hardware.
     * Once a sudden jump is detected, all subsequent move events are discarded
     * until an UP is received.<P>
     * When a sudden jump is detected, an UP event is simulated at the last position and when
     * the sudden moves subside, a DOWN event is simulated for the second key.
     * @param me the motion event
     * @return true if the event was consumed, so that it doesn't continue to be handled by
     * {@link MainKeyboardView}.
     */
    private boolean handleSuddenJumping(final MotionEvent me) {
        if (!mNeedsSuddenJumpingHack)
            return false;
        final int action = me.getAction();
        final int x = (int) me.getX();
        final int y = (int) me.getY();
        boolean result = false;

        // Real multi-touch event? Stop looking for sudden jumps
        if (me.getPointerCount() > 1) {
            mDisableDisambiguation = true;
        }
        if (mDisableDisambiguation) {
            // If UP, reset the multi-touch flag
            if (action == MotionEvent.ACTION_UP) mDisableDisambiguation = false;
            return false;
        }

        switch (action) {
        case MotionEvent.ACTION_DOWN:
            // Reset the "session"
            mDroppingEvents = false;
            mDisableDisambiguation = false;
            break;
        case MotionEvent.ACTION_MOVE:
            // Is this a big jump?
            final int distanceSquare = (mLastX - x) * (mLastX - x) + (mLastY - y) * (mLastY - y);
            // Check the distance.
            if (distanceSquare > mJumpThresholdSquare) {
                // If we're not yet dropping events, start dropping and send an UP event
                if (!mDroppingEvents) {
                    mDroppingEvents = true;
                    // Send an up event
                    MotionEvent translated = MotionEvent.obtain(
                            me.getEventTime(), me.getEventTime(),
                            MotionEvent.ACTION_UP,
                            mLastX, mLastY, me.getMetaState());
                    mView.processMotionEvent(translated);
                    translated.recycle();
                }
                result = true;
            } else if (mDroppingEvents) {
                // If moves are small and we're already dropping events, continue dropping
                result = true;
            }
            break;
        case MotionEvent.ACTION_UP:
            if (mDroppingEvents) {
                // Send a down event first, as we dropped a bunch of sudden jumps and assume that
                // the user is releasing the touch on the second key.
                MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
                        MotionEvent.ACTION_DOWN,
                        x, y, me.getMetaState());
                mView.processMotionEvent(translated);
                translated.recycle();
                mDroppingEvents = false;
                // Let the up event get processed as well, result = false
            }
            break;
        }
        // Track the previous coordinate
        mLastX = x;
        mLastY = y;
        return result;
    }

    public boolean onTouchEvent(final MotionEvent me) {
        // If there was a sudden jump, return without processing the actual motion event.
        if (handleSuddenJumping(me)) {
            if (DEBUG_MODE)
                Log.w(TAG, "onTouchEvent: ignore sudden jump " + me);
            if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
                ResearchLogger.suddenJumpingTouchEventHandler_onTouchEvent(me);
            }
            return true;
        }
        return mView.processMotionEvent(me);
    }
}