aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java5
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/MainKeyboardView.java30
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java30
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/GestureTrailsPreview.java1
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/NonDistinctMultitouchHelper.java71
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java3
-rw-r--r--java/src/com/android/inputmethod/latin/settings/Settings.java41
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.