diff options
Diffstat (limited to 'java/src')
8 files changed, 116 insertions, 71 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 166be817f..8880af48c 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -314,10 +314,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { R.layout.input_view, null); mKeyboardView = (MainKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view); - if (isHardwareAcceleratedDrawingEnabled) { - mKeyboardView.setLayerType(View.LAYER_TYPE_HARDWARE, null); - // TODO: Should use LAYER_TYPE_SOFTWARE when hardware acceleration is off? - } + mKeyboardView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled); mKeyboardView.setKeyboardActionListener(mLatinIME); // This always needs to be set since the accessibility state can diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index 2a02682e5..054c503d8 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -154,6 +154,12 @@ public class KeyboardView extends View { Color.red(color), Color.green(color), Color.blue(color)); } + public void setHardwareAcceleratedDrawingEnabled(final boolean enabled) { + if (!enabled) return; + // TODO: Should use LAYER_TYPE_SOFTWARE when hardware acceleration is off? + setLayerType(LAYER_TYPE_HARDWARE, null); + } + /** * Attaches a keyboard to this view. The keyboard can be switched at any time and the * view will re-layout itself to accommodate the keyboard. diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index 5334b45b6..6782317d0 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -512,6 +512,12 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack mKeyboardActionListener = KeyboardActionListener.EMPTY_LISTENER; } + @Override + public void setHardwareAcceleratedDrawingEnabled(final boolean enabled) { + super.setHardwareAcceleratedDrawingEnabled(enabled); + mPreviewPlacerView.setHardwareAcceleratedDrawingEnabled(enabled); + } + private ObjectAnimator loadObjectAnimator(final int resId, final Object target) { if (resId == 0) { // TODO: Stop returning null. @@ -1055,26 +1061,10 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack ResearchLogger.mainKeyboardView_processMotionEvent(me); } - final int action = me.getActionMasked(); - final long eventTime = me.getEventTime(); - if (action == MotionEvent.ACTION_MOVE) { - final int pointerCount = me.getPointerCount(); - for (int index = 0; index < pointerCount; index++) { - final int id = me.getPointerId(index); - final PointerTracker tracker = PointerTracker.getPointerTracker(id, this); - final int x = (int)me.getX(index); - final int y = (int)me.getY(index); - tracker.onMoveEvent(x, y, eventTime, me); - } - } else { - final int index = me.getActionIndex(); - final int id = me.getPointerId(index); - final int x = (int)me.getX(index); - final int y = (int)me.getY(index); - final PointerTracker tracker = PointerTracker.getPointerTracker(id, this); - tracker.processMotionEvent(action, x, y, eventTime, this); - } - + final int index = me.getActionIndex(); + final int id = me.getPointerId(index); + final PointerTracker tracker = PointerTracker.getPointerTracker(id, this); + tracker.processMotionEvent(me, this); return true; } diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index bbaf96982..ab5fee99d 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -870,8 +870,23 @@ public final class PointerTracker implements PointerTrackerQueue.Element { mListener.onCancelBatchInput(); } - public void processMotionEvent(final int action, final int x, final int y, final long eventTime, - final KeyEventHandler handler) { + public void processMotionEvent(final MotionEvent me, final KeyEventHandler handler) { + final int action = me.getActionMasked(); + final long eventTime = me.getEventTime(); + if (action == MotionEvent.ACTION_MOVE) { + final int pointerCount = me.getPointerCount(); + for (int index = 0; index < pointerCount; index++) { + final int id = me.getPointerId(index); + final PointerTracker tracker = getPointerTracker(id, handler); + final int x = (int)me.getX(index); + final int y = (int)me.getY(index); + tracker.onMoveEvent(x, y, eventTime, me); + } + return; + } + final int index = me.getActionIndex(); + final int x = (int)me.getX(index); + final int y = (int)me.getY(index); switch (action) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: @@ -881,16 +896,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element { case MotionEvent.ACTION_POINTER_UP: onUpEvent(x, y, eventTime); break; - case MotionEvent.ACTION_MOVE: - onMoveEvent(x, y, eventTime, null); - break; case MotionEvent.ACTION_CANCEL: onCancelEvent(x, y, eventTime); break; } } - public void onDownEvent(final int x, final int y, final long eventTime, + private void onDownEvent(final int x, final int y, final long eventTime, final KeyEventHandler handler) { if (DEBUG_EVENT) { printTouchEvent("onDownEvent:", x, y, eventTime); @@ -1005,7 +1017,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { } } - public void onMoveEvent(final int x, final int y, final long eventTime, final MotionEvent me) { + private void onMoveEvent(final int x, final int y, final long eventTime, final MotionEvent me) { if (DEBUG_MOVE_EVENT) { printTouchEvent("onMoveEvent:", x, y, eventTime); } @@ -1193,7 +1205,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { } } - public void onUpEvent(final int x, final int y, final long eventTime) { + private void onUpEvent(final int x, final int y, final long eventTime) { if (DEBUG_EVENT) { printTouchEvent("onUpEvent :", x, y, eventTime); } @@ -1293,7 +1305,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { sPointerTrackerQueue.remove(this); } - public void onCancelEvent(final int x, final int y, final long eventTime) { + private void onCancelEvent(final int x, final int y, final long eventTime) { if (DEBUG_EVENT) { printTouchEvent("onCancelEvt:", x, y, eventTime); } diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java index d4c25941c..19e995548 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java +++ b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java @@ -110,6 +110,7 @@ public final class GestureTrailsPreview extends AbstractDrawingPreview { private void freeOffscreenBuffer() { mOffscreenCanvas.setBitmap(null); + mOffscreenCanvas.setMatrix(null); if (mOffscreenBuffer != null) { mOffscreenBuffer.recycle(); mOffscreenBuffer = null; diff --git a/java/src/com/android/inputmethod/keyboard/internal/NonDistinctMultitouchHelper.java b/java/src/com/android/inputmethod/keyboard/internal/NonDistinctMultitouchHelper.java index 53fff6986..a0935b985 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/NonDistinctMultitouchHelper.java +++ b/java/src/com/android/inputmethod/keyboard/internal/NonDistinctMultitouchHelper.java @@ -29,56 +29,67 @@ public final class NonDistinctMultitouchHelper { private int mOldPointerCount = 1; private Key mOldKey; + private int[] mLastCoords = CoordinateUtils.newInstance(); 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. + // Ignore continuous multi-touch events because we can't trust the coordinates + // in multi-touch events. if (pointerCount > 1 && oldPointerCount > 1) { return; } + // Use only main (id=0) pointer tracker. + final PointerTracker mainTracker = PointerTracker.getPointerTracker(0, keyEventHandler); 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); + final long downTime = me.getDownTime(); - // In single touch. + // In single-touch. if (oldPointerCount == 1 && pointerCount == 1) { - mainTracker.processMotionEvent(action, x, y, eventTime, keyEventHandler); + if (me.getPointerId(index) == mainTracker.mPointerId) { + mainTracker.processMotionEvent(me, keyEventHandler); + return; + } + // Inject a copied event. + injectMotionEvent(action, me.getX(index), me.getY(index), downTime, eventTime, + mainTracker, 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); + // Send an up event for the last pointer, be cause we can't trust the coordinates of + // this multi-touch event. + mainTracker.getLastCoordinates(mLastCoords); + final int x = CoordinateUtils.x(mLastCoords); + final int y = CoordinateUtils.y(mLastCoords); + mOldKey = mainTracker.getKeyOn(x, y); + // Inject an artifact up event for the old key. + injectMotionEvent(MotionEvent.ACTION_UP, x, y, downTime, eventTime, + mainTracker, keyEventHandler); return; } - // Multi-touch to single touch transition. + // 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. + // Send a down event for the latest pointer if the key is different from the previous + // key. + final int x = (int)me.getX(index); + final int y = (int)me.getY(index); final Key newKey = mainTracker.getKeyOn(x, y); if (mOldKey != newKey) { - // TODO: Stop calling PointerTracker.onDownEvent directly. - mainTracker.onDownEvent(x, y, eventTime, keyEventHandler); + // Inject an artifact down event for the new key. + // An artifact up event for the new key will usually be injected as a single-touch. + injectMotionEvent(MotionEvent.ACTION_DOWN, x, y, downTime, eventTime, + mainTracker, keyEventHandler); if (action == MotionEvent.ACTION_UP) { - // TODO: Stop calling PointerTracker.onUpEvent directly. - mainTracker.onUpEvent(x, y, eventTime); + // Inject an artifact up event for the new key also. + injectMotionEvent(MotionEvent.ACTION_UP, x, y, downTime, eventTime, + mainTracker, keyEventHandler); } } return; @@ -87,4 +98,16 @@ public final class NonDistinctMultitouchHelper { Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount + " (previously " + oldPointerCount + ")"); } + + private static void injectMotionEvent(final int action, final float x, final float y, + final long downTime, final long eventTime, final PointerTracker tracker, + final KeyEventHandler handler) { + final MotionEvent me = MotionEvent.obtain( + downTime, eventTime, action, x, y, 0 /* metaState */); + try { + tracker.processMotionEvent(me, handler); + } finally { + me.recycle(); + } + } } diff --git a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java index 3388c5701..4c8607da8 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java +++ b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java @@ -37,7 +37,10 @@ public final class PreviewPlacerView extends RelativeLayout { public PreviewPlacerView(final Context context, final AttributeSet attrs) { super(context, attrs); setWillNotDraw(false); + } + public void setHardwareAcceleratedDrawingEnabled(final boolean enabled) { + if (!enabled) return; final Paint layerPaint = new Paint(); layerPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); setLayerType(LAYER_TYPE_HARDWARE, layerPaint); diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java index e6a0c07d7..d432087d3 100644 --- a/java/src/com/android/inputmethod/latin/settings/Settings.java +++ b/java/src/com/android/inputmethod/latin/settings/Settings.java @@ -27,12 +27,14 @@ import com.android.inputmethod.latin.AudioAndHapticFeedbackManager; import com.android.inputmethod.latin.InputAttributes; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; +import com.android.inputmethod.latin.utils.DebugLogUtils; import com.android.inputmethod.latin.utils.LocaleUtils; import com.android.inputmethod.latin.utils.ResourceUtils; import com.android.inputmethod.latin.utils.RunInLocale; import java.util.HashMap; import java.util.Locale; +import java.util.concurrent.locks.ReentrantLock; public final class Settings implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = Settings.class.getSimpleName(); @@ -94,6 +96,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang private Resources mRes; private SharedPreferences mPrefs; private SettingsValues mSettingsValues; + private final ReentrantLock mSettingsValuesLock = new ReentrantLock(); private static final Settings sInstance = new Settings(); @@ -121,24 +124,34 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang @Override public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) { - if (mSettingsValues == null) { - // TODO: Introduce a static function to register this class and ensure that - // loadSettings must be called before "onSharedPreferenceChanged" is called. - Log.w(TAG, "onSharedPreferenceChanged called before loadSettings."); - return; + mSettingsValuesLock.lock(); + try { + if (mSettingsValues == null) { + // TODO: Introduce a static function to register this class and ensure that + // loadSettings must be called before "onSharedPreferenceChanged" is called. + Log.w(TAG, "onSharedPreferenceChanged called before loadSettings."); + return; + } + loadSettings(mSettingsValues.mLocale, mSettingsValues.mInputAttributes); + } finally { + mSettingsValuesLock.unlock(); } - loadSettings(mSettingsValues.mLocale, mSettingsValues.mInputAttributes); } public void loadSettings(final Locale locale, final InputAttributes inputAttributes) { - final SharedPreferences prefs = mPrefs; - final RunInLocale<SettingsValues> job = new RunInLocale<SettingsValues>() { - @Override - protected SettingsValues job(final Resources res) { - return new SettingsValues(prefs, locale, res, inputAttributes); - } - }; - mSettingsValues = job.runInLocale(mRes, locale); + mSettingsValuesLock.lock(); + try { + final SharedPreferences prefs = mPrefs; + final RunInLocale<SettingsValues> job = new RunInLocale<SettingsValues>() { + @Override + protected SettingsValues job(final Resources res) { + return new SettingsValues(prefs, locale, res, inputAttributes); + } + }; + mSettingsValues = job.runInLocale(mRes, locale); + } finally { + mSettingsValuesLock.unlock(); + } } // TODO: Remove this method and add proxy method to SettingsValues. |