Loading java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +17 −63 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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( Loading Loading @@ -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); Loading @@ -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); Loading java/src/com/android/inputmethod/keyboard/PointerTracker.java +5 −4 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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) { Loading java/src/com/android/inputmethod/keyboard/internal/NonDistinctMultitouchHelper.java 0 → 100644 +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 + ")"); } } Loading
java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +17 −63 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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( Loading Loading @@ -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); Loading @@ -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); Loading
java/src/com/android/inputmethod/keyboard/PointerTracker.java +5 −4 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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) { Loading
java/src/com/android/inputmethod/keyboard/internal/NonDistinctMultitouchHelper.java 0 → 100644 +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 + ")"); } }