aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com')
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java67
-rw-r--r--java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java65
-rw-r--r--java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java78
-rw-r--r--java/src/com/android/inputmethod/accessibility/MoreKeysKeyboardAccessibilityDelegate.java114
-rw-r--r--java/src/com/android/inputmethod/accessibility/MoreSuggestionsAccessibilityDelegate.java37
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java48
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java8
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java4
-rw-r--r--java/src/com/android/inputmethod/latin/InputView.java20
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java24
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsFragment.java15
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java14
-rw-r--r--java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java34
13 files changed, 477 insertions, 51 deletions
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java b/java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java
new file mode 100644
index 000000000..967cafad0
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2014 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.accessibility;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.latin.R;
+
+// Handling long press timer to show a more keys keyboard.
+final class AccessibilityLongPressTimer extends Handler {
+ public interface LongPressTimerCallback {
+ public void onLongPressed(Key key);
+ }
+
+ private static final int MSG_LONG_PRESS = 1;
+
+ private final LongPressTimerCallback mCallback;
+ private final long mConfigAccessibilityLongPressTimeout;
+
+ public AccessibilityLongPressTimer(final LongPressTimerCallback callback,
+ final Context context) {
+ super();
+ mCallback = callback;
+ mConfigAccessibilityLongPressTimeout = context.getResources().getInteger(
+ R.integer.config_accessibility_long_press_key_timeout);
+ }
+
+ @Override
+ public void handleMessage(final Message msg) {
+ switch (msg.what) {
+ case MSG_LONG_PRESS:
+ cancelLongPress();
+ mCallback.onLongPressed((Key)msg.obj);
+ return;
+ default:
+ super.handleMessage(msg);
+ return;
+ }
+ }
+
+ public void startLongPress(final Key key) {
+ cancelLongPress();
+ final Message longPressMessage = obtainMessage(MSG_LONG_PRESS, key);
+ sendMessageDelayed(longPressMessage, mConfigAccessibilityLongPressTimeout);
+ }
+
+ public void cancelLongPress() {
+ removeMessages(MSG_LONG_PRESS);
+ }
+}
diff --git a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java
index bbc18f020..d67d9dc4b 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java
@@ -33,14 +33,29 @@ import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardView;
import com.android.inputmethod.keyboard.PointerTracker;
+/**
+ * This class represents a delegate that can be registered in a class that extends
+ * {@link KeyboardView} to enhance accessibility support via composition rather via inheritance.
+ *
+ * To implement accessibility mode, the target keyboard view has to:<p>
+ * - Call {@link #setKeyboard(Keyboard)} when a new keyboard is set to the keyboard view.
+ * - Dispatch a hover event by calling {@link #onHoverEnter(MotionEvent)}.
+ *
+ * @param <KV> The keyboard view class type.
+ */
public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
extends AccessibilityDelegateCompat {
+ private static final String TAG = KeyboardAccessibilityDelegate.class.getSimpleName();
+ protected static final boolean DEBUG_HOVER = false;
+
protected final KV mKeyboardView;
protected final KeyDetector mKeyDetector;
private Keyboard mKeyboard;
private KeyboardAccessibilityNodeProvider mAccessibilityNodeProvider;
private Key mLastHoverKey;
+ public static final int HOVER_EVENT_POINTER_ID = 0;
+
public KeyboardAccessibilityDelegate(final KV keyboardView, final KeyDetector keyDetector) {
super();
mKeyboardView = keyboardView;
@@ -180,8 +195,11 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
*/
protected void onHoverEnter(final MotionEvent event) {
final Key key = getHoverKeyOf(event);
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverEnter: key=" + key);
+ }
if (key != null) {
- onHoverEnterKey(key, event);
+ onHoverEnterTo(key);
}
setLastHoverKey(key);
}
@@ -196,14 +214,14 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
final Key key = getHoverKeyOf(event);
if (key != lastKey) {
if (lastKey != null) {
- onHoverExitKey(lastKey, event);
+ onHoverExitFrom(lastKey);
}
if (key != null) {
- onHoverEnterKey(key, event);
+ onHoverEnterTo(key);
}
}
if (key != null) {
- onHoverMoveKey(key, event);
+ onHoverMoveWithin(key);
}
setLastHoverKey(key);
}
@@ -215,21 +233,37 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
*/
protected void onHoverExit(final MotionEvent event) {
final Key lastKey = getLastHoverKey();
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverExit: key=" + getHoverKeyOf(event) + " last=" + lastKey);
+ }
if (lastKey != null) {
- onHoverExitKey(lastKey, event);
+ onHoverExitFrom(lastKey);
}
final Key key = getHoverKeyOf(event);
// Make sure we're not getting an EXIT event because the user slid
// off the keyboard area, then force a key press.
if (key != null) {
- simulateTouchEvent(MotionEvent.ACTION_DOWN, event);
- simulateTouchEvent(MotionEvent.ACTION_UP, event);
- onHoverExitKey(key, event);
+ onRegisterHoverKey(key, event);
+ onHoverExitFrom(key);
}
setLastHoverKey(null);
}
/**
+ * Register a key that is selected by a hover event
+ *
+ * @param key A key to be registered.
+ * @param event A hover exit event that triggers key registering.
+ */
+ protected void onRegisterHoverKey(final Key key, final MotionEvent event) {
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onRegisterHoverKey: key=" + key);
+ }
+ simulateTouchEvent(MotionEvent.ACTION_DOWN, event);
+ simulateTouchEvent(MotionEvent.ACTION_UP, event);
+ }
+
+ /**
* Simulating a touch event by injecting a synthesized touch event into {@link PointerTracker}.
*
* @param touchAction The action of the synthesizing touch event.
@@ -263,9 +297,11 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
* Handles a hover enter event on a key.
*
* @param key The currently hovered key.
- * @param event The hover event that triggers a call to this method.
*/
- protected void onHoverEnterKey(final Key key, final MotionEvent event) {
+ protected void onHoverEnterTo(final Key key) {
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverEnterTo: key=" + key);
+ }
key.onPressed();
mKeyboardView.invalidateKey(key);
final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider();
@@ -277,17 +313,18 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
* Handles a hover move event on a key.
*
* @param key The currently hovered key.
- * @param event The hover event that triggers a call to this method.
*/
- protected void onHoverMoveKey(final Key key, final MotionEvent event) { }
+ protected void onHoverMoveWithin(final Key key) { }
/**
* Handles a hover exit event on a key.
*
* @param key The currently hovered key.
- * @param event The hover event that triggers a call to this method.
*/
- protected void onHoverExitKey(final Key key, final MotionEvent event) {
+ protected void onHoverExitFrom(final Key key) {
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverExitFrom: key=" + key);
+ }
key.onReleased();
mKeyboardView.invalidateKey(key);
final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider();
diff --git a/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
index ec6bb0156..4fdf5b8fa 100644
--- a/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
+++ b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
@@ -17,17 +17,29 @@
package com.android.inputmethod.accessibility;
import android.content.Context;
+import android.os.SystemClock;
+import android.util.Log;
import android.util.SparseIntArray;
+import android.view.MotionEvent;
+import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.KeyDetector;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.MainKeyboardView;
+import com.android.inputmethod.keyboard.PointerTracker;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
+/**
+ * This class represents a delegate that can be registered in {@link MainKeyboardView} to enhance
+ * accessibility support via composition rather via inheritance.
+ */
public final class MainKeyboardAccessibilityDelegate
- extends KeyboardAccessibilityDelegate<MainKeyboardView> {
+ extends KeyboardAccessibilityDelegate<MainKeyboardView>
+ implements AccessibilityLongPressTimer.LongPressTimerCallback {
+ private static final String TAG = MainKeyboardAccessibilityDelegate.class.getSimpleName();
+
/** Map of keyboard modes to resource IDs. */
private static final SparseIntArray KEYBOARD_MODE_RES_IDS = new SparseIntArray();
@@ -46,10 +58,15 @@ public final class MainKeyboardAccessibilityDelegate
/** The most recently set keyboard mode. */
private int mLastKeyboardMode = KEYBOARD_IS_HIDDEN;
private static final int KEYBOARD_IS_HIDDEN = -1;
+ private boolean mShouldIgnoreOnRegisterHoverKey;
+
+ private final AccessibilityLongPressTimer mAccessibilityLongPressTimer;
public MainKeyboardAccessibilityDelegate(final MainKeyboardView mainKeyboardView,
final KeyDetector keyDetector) {
super(mainKeyboardView, keyDetector);
+ mAccessibilityLongPressTimer = new AccessibilityLongPressTimer(
+ this /* callback */, mainKeyboardView.getContext());
}
/**
@@ -172,4 +189,63 @@ public final class MainKeyboardAccessibilityDelegate
private void announceKeyboardHidden() {
sendWindowStateChanged(R.string.announce_keyboard_hidden);
}
+
+ @Override
+ protected void onRegisterHoverKey(final Key key, final MotionEvent event) {
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onRegisterHoverKey: key=" + key + " ignore="
+ + mShouldIgnoreOnRegisterHoverKey);
+ }
+ if (!mShouldIgnoreOnRegisterHoverKey) {
+ super.onRegisterHoverKey(key, event);
+ }
+ mShouldIgnoreOnRegisterHoverKey = false;
+ }
+
+ @Override
+ protected void onHoverEnterTo(final Key key) {
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverEnterTo: key=" + key);
+ }
+ mAccessibilityLongPressTimer.cancelLongPress();
+ super.onHoverEnterTo(key);
+ if (key.isLongPressEnabled()) {
+ mAccessibilityLongPressTimer.startLongPress(key);
+ }
+ }
+
+ protected void onHoverExitFrom(final Key key) {
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverExitFrom: key=" + key);
+ }
+ mAccessibilityLongPressTimer.cancelLongPress();
+ super.onHoverExitFrom(key);
+ }
+
+ @Override
+ public void onLongPressed(final Key key) {
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onLongPressed: key=" + key);
+ }
+ final PointerTracker tracker = PointerTracker.getPointerTracker(HOVER_EVENT_POINTER_ID);
+ final long eventTime = SystemClock.uptimeMillis();
+ final int x = key.getHitBox().centerX();
+ final int y = key.getHitBox().centerY();
+ final MotionEvent downEvent = MotionEvent.obtain(
+ eventTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0 /* metaState */);
+ // Inject a fake down event to {@link PointerTracker} to handle a long press correctly.
+ tracker.processMotionEvent(downEvent, mKeyDetector);
+ // The above fake down event triggers an unnecessary long press timer that should be
+ // canceled.
+ tracker.cancelLongPressTimer();
+ downEvent.recycle();
+ // Invoke {@link MainKeyboardView#onLongPress(PointerTracker)} as if a long press timeout
+ // has passed.
+ mKeyboardView.onLongPress(tracker);
+ // If {@link Key#hasNoPanelAutoMoreKeys()} is true (such as "0 +" key on the phone layout)
+ // or a key invokes IME switcher dialog, we should just ignore the next
+ // {@link #onRegisterHoverKey(Key,MotionEvent)}. It can be determined by whether
+ // {@link PointerTracker} is in operation or not.
+ mShouldIgnoreOnRegisterHoverKey = !tracker.isInOperation();
+ }
}
diff --git a/java/src/com/android/inputmethod/accessibility/MoreKeysKeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/MoreKeysKeyboardAccessibilityDelegate.java
new file mode 100644
index 000000000..3a56c5d2a
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/MoreKeysKeyboardAccessibilityDelegate.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2014 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.accessibility;
+
+import android.graphics.Rect;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.KeyDetector;
+import com.android.inputmethod.keyboard.MoreKeysKeyboardView;
+import com.android.inputmethod.latin.Constants;
+
+/**
+ * This class represents a delegate that can be registered in {@link MoreKeysKeyboardView} to
+ * enhance accessibility support via composition rather via inheritance.
+ */
+public class MoreKeysKeyboardAccessibilityDelegate
+ extends KeyboardAccessibilityDelegate<MoreKeysKeyboardView> {
+ private static final String TAG = MoreKeysKeyboardAccessibilityDelegate.class.getSimpleName();
+
+ private final Rect mMoreKeysKeyboardValidBounds = new Rect();
+ private static final int CLOSING_INSET_IN_PIXEL = 1;
+ private int mOpenAnnounceResId;
+ private int mCloseAnnounceResId;
+
+ public MoreKeysKeyboardAccessibilityDelegate(final MoreKeysKeyboardView moreKeysKeyboardView,
+ final KeyDetector keyDetector) {
+ super(moreKeysKeyboardView, keyDetector);
+ }
+
+ public void setOpenAnnounce(final int resId) {
+ mOpenAnnounceResId = resId;
+ }
+
+ public void setCloseAnnounce(final int resId) {
+ mCloseAnnounceResId = resId;
+ }
+
+ public void onShowMoreKeysKeyboard() {
+ sendWindowStateChanged(mOpenAnnounceResId);
+ }
+
+ @Override
+ protected void onHoverEnter(final MotionEvent event) {
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverEnter: key=" + getHoverKeyOf(event));
+ }
+ super.onHoverEnter(event);
+ final int actionIndex = event.getActionIndex();
+ final int x = (int)event.getX(actionIndex);
+ final int y = (int)event.getY(actionIndex);
+ final int pointerId = event.getPointerId(actionIndex);
+ final long eventTime = event.getEventTime();
+ mKeyboardView.onDownEvent(x, y, pointerId, eventTime);
+ }
+
+ @Override
+ protected void onHoverMove(final MotionEvent event) {
+ super.onHoverMove(event);
+ final int actionIndex = event.getActionIndex();
+ final int x = (int)event.getX(actionIndex);
+ final int y = (int)event.getY(actionIndex);
+ final int pointerId = event.getPointerId(actionIndex);
+ final long eventTime = event.getEventTime();
+ mKeyboardView.onMoveEvent(x, y, pointerId, eventTime);
+ }
+
+ @Override
+ protected void onHoverExit(final MotionEvent event) {
+ final Key lastKey = getLastHoverKey();
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverExit: key=" + getHoverKeyOf(event) + " last=" + lastKey);
+ }
+ if (lastKey != null) {
+ super.onHoverExitFrom(lastKey);
+ }
+ setLastHoverKey(null);
+ final int actionIndex = event.getActionIndex();
+ final int x = (int)event.getX(actionIndex);
+ final int y = (int)event.getY(actionIndex);
+ final int pointerId = event.getPointerId(actionIndex);
+ final long eventTime = event.getEventTime();
+ // A hover exit event at one pixel width or height area on the edges of more keys keyboard
+ // are treated as closing.
+ mMoreKeysKeyboardValidBounds.set(0, 0, mKeyboardView.getWidth(), mKeyboardView.getHeight());
+ mMoreKeysKeyboardValidBounds.inset(CLOSING_INSET_IN_PIXEL, CLOSING_INSET_IN_PIXEL);
+ if (mMoreKeysKeyboardValidBounds.contains(x, y)) {
+ // Invoke {@link MoreKeysKeyboardView#onUpEvent(int,int,int,long)} as if this hover
+ // exit event selects a key.
+ mKeyboardView.onUpEvent(x, y, pointerId, eventTime);
+ mKeyboardView.dismissMoreKeysPanel();
+ return;
+ }
+ // Close the more keys keyboard.
+ mKeyboardView.onMoveEvent(
+ Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, pointerId, eventTime);
+ sendWindowStateChanged(mCloseAnnounceResId);
+ }
+}
diff --git a/java/src/com/android/inputmethod/accessibility/MoreSuggestionsAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/MoreSuggestionsAccessibilityDelegate.java
new file mode 100644
index 000000000..dfc866113
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/MoreSuggestionsAccessibilityDelegate.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 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.accessibility;
+
+import android.view.MotionEvent;
+
+import com.android.inputmethod.keyboard.KeyDetector;
+import com.android.inputmethod.keyboard.MoreKeysKeyboardView;
+
+public final class MoreSuggestionsAccessibilityDelegate
+ extends MoreKeysKeyboardAccessibilityDelegate {
+ public MoreSuggestionsAccessibilityDelegate(final MoreKeysKeyboardView moreKeysKeyboardView,
+ final KeyDetector keyDetector) {
+ super(moreKeysKeyboardView, keyDetector);
+ }
+
+ @Override
+ protected void simulateTouchEvent(final int touchAction, final MotionEvent hoverEvent) {
+ final MotionEvent touchEvent = synthesizeTouchEvent(touchAction, hoverEvent);
+ mKeyboardView.onTouchEvent(touchEvent);
+ touchEvent.recycle();
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index 50c82e5f7..4ca4abec6 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -17,12 +17,13 @@
package com.android.inputmethod.keyboard;
import android.content.Context;
-import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import com.android.inputmethod.accessibility.AccessibilityUtils;
+import com.android.inputmethod.accessibility.MoreKeysKeyboardAccessibilityDelegate;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.utils.CoordinateUtils;
@@ -34,7 +35,7 @@ import com.android.inputmethod.latin.utils.CoordinateUtils;
public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel {
private final int[] mCoordinates = CoordinateUtils.newInstance();
- protected final KeyDetector mKeyDetector;
+ protected KeyDetector mKeyDetector;
private Controller mController = EMPTY_CONTROLLER;
protected KeyboardActionListener mListener;
private int mOriginX;
@@ -43,6 +44,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
private int mActivePointerId;
+ protected MoreKeysKeyboardAccessibilityDelegate mAccessibilityDelegate;
+
public MoreKeysKeyboardView(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.moreKeysKeyboardViewStyle);
}
@@ -50,10 +53,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
public MoreKeysKeyboardView(final Context context, final AttributeSet attrs,
final int defStyle) {
super(context, attrs, defStyle);
-
- final Resources res = context.getResources();
- mKeyDetector = new MoreKeysDetector(
- res.getDimension(R.dimen.config_more_keys_keyboard_slide_allowance));
+ mKeyDetector = new MoreKeysDetector(getResources().getDimension(
+ R.dimen.config_more_keys_keyboard_slide_allowance));
}
@Override
@@ -71,8 +72,23 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
@Override
public void setKeyboard(final Keyboard keyboard) {
super.setKeyboard(keyboard);
- mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
- -getPaddingTop() + getVerticalCorrection());
+ if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
+ // With accessibility mode on, any hover event outside {@link MoreKeysKeyboardView} is
+ // discarded at {@link InputView#dispatchHoverEvent(MotionEvent)}. Because only a hover
+ // event that is on this view is dispatched by the platform, we should use a
+ // {@link KeyDetector} that has no sliding allowance and no hysteresis.
+ mKeyDetector = new KeyDetector();
+ mAccessibilityDelegate = new MoreKeysKeyboardAccessibilityDelegate(this, mKeyDetector);
+ mAccessibilityDelegate.setOpenAnnounce(R.string.spoken_open_more_keys_keyboard);
+ mAccessibilityDelegate.setCloseAnnounce(R.string.spoken_close_more_keys_keyboard);
+ mAccessibilityDelegate.setKeyboard(keyboard);
+ } else {
+ mKeyDetector = new MoreKeysDetector(getResources().getDimension(
+ R.dimen.config_more_keys_keyboard_slide_allowance));
+ mAccessibilityDelegate = null;
+ }
+ mKeyDetector.setKeyboard(
+ keyboard, -getPaddingLeft(), -getPaddingTop() + getVerticalCorrection());
}
@Override
@@ -98,6 +114,10 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
mOriginX = x + container.getPaddingLeft();
mOriginY = y + container.getPaddingTop();
controller.onShowMoreKeysPanel(this);
+ final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate;
+ if (accessibilityDelegate != null) {
+ accessibilityDelegate.onShowMoreKeysKeyboard();
+ }
}
/**
@@ -228,6 +248,18 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
return true;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean onHoverEvent(final MotionEvent event) {
+ final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate;
+ if (accessibilityDelegate != null) {
+ return accessibilityDelegate.onHoverEvent(event);
+ }
+ return super.onHoverEvent(event);
+ }
+
private View getContainerView() {
return (View)getParent();
}
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index ff6fd86d0..b6905bc1c 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -1078,6 +1078,14 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
mIsTrackingForActionDisabled = true;
}
+ public boolean isInOperation() {
+ return !mIsTrackingForActionDisabled;
+ }
+
+ public void cancelLongPressTimer() {
+ sTimerProxy.cancelLongPressTimerOf(this);
+ }
+
public void onLongPressed() {
resetKeySelectionByDraggingFinger();
cancelTrackingForAction();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
index 40c915c8d..ab2555802 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
@@ -602,7 +602,7 @@ public final class KeyboardTextsTable {
/* keyspec_right_double_angle_quote */ "\u00BB|\u00AB",
/* keyspec_left_single_angle_quote */ "\u2039|\u203A",
/* keyspec_right_single_angle_quote */ "\u203A|\u2039",
- /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,/,\",\'",
+ /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,\",\'",
// U+0651: "ّ" ARABIC SHADDA
/* keyhintlabel_period */ "\u0651",
/* morekeys_tablet_period */ "!text/morekeys_arabic_diacritics",
@@ -1551,7 +1551,7 @@ public final class KeyboardTextsTable {
/* keyspec_right_double_angle_quote */ "\u00BB|\u00AB",
/* keyspec_left_single_angle_quote */ "\u2039|\u203A",
/* keyspec_right_single_angle_quote */ "\u203A|\u2039",
- /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,/,!text/keyspec_left_double_angle_quote,!text/keyspec_right_double_angle_quote",
+ /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,!text/keyspec_left_double_angle_quote,!text/keyspec_right_double_angle_quote",
// U+064B: "ً" ARABIC FATHATAN
/* keyhintlabel_period */ "\u064B",
/* morekeys_tablet_period */ "!text/morekeys_arabic_diacritics",
diff --git a/java/src/com/android/inputmethod/latin/InputView.java b/java/src/com/android/inputmethod/latin/InputView.java
index ea7859e60..0801cfa88 100644
--- a/java/src/com/android/inputmethod/latin/InputView.java
+++ b/java/src/com/android/inputmethod/latin/InputView.java
@@ -23,12 +23,14 @@ import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
+import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.keyboard.MainKeyboardView;
import com.android.inputmethod.latin.suggestions.MoreSuggestionsView;
import com.android.inputmethod.latin.suggestions.SuggestionStripView;
public final class InputView extends LinearLayout {
private final Rect mInputViewRect = new Rect();
+ private MainKeyboardView mMainKeyboardView;
private KeyboardTopPaddingForwarder mKeyboardTopPaddingForwarder;
private MoreSuggestionsViewCanceler mMoreSuggestionsViewCanceler;
private MotionEventForwarder<?, ?> mActiveForwarder;
@@ -41,12 +43,11 @@ public final class InputView extends LinearLayout {
protected void onFinishInflate() {
final SuggestionStripView suggestionStripView =
(SuggestionStripView)findViewById(R.id.suggestion_strip_view);
- final MainKeyboardView mainKeyboardView =
- (MainKeyboardView)findViewById(R.id.keyboard_view);
+ mMainKeyboardView = (MainKeyboardView)findViewById(R.id.keyboard_view);
mKeyboardTopPaddingForwarder = new KeyboardTopPaddingForwarder(
- mainKeyboardView, suggestionStripView);
+ mMainKeyboardView, suggestionStripView);
mMoreSuggestionsViewCanceler = new MoreSuggestionsViewCanceler(
- mainKeyboardView, suggestionStripView);
+ mMainKeyboardView, suggestionStripView);
}
public void setKeyboardTopPadding(final int keyboardTopPadding) {
@@ -54,6 +55,17 @@ public final class InputView extends LinearLayout {
}
@Override
+ protected boolean dispatchHoverEvent(final MotionEvent event) {
+ if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()
+ && mMainKeyboardView.isShowingMoreKeysPanel()) {
+ // With accessibility mode on, discard hover events while a more keys keyboard is shown.
+ // The {@link MoreKeysKeyboard} receives hover events directly from the platform.
+ return true;
+ }
+ return super.dispatchHoverEvent(event);
+ }
+
+ @Override
public boolean onInterceptTouchEvent(final MotionEvent me) {
final Rect rect = mInputViewRect;
getGlobalVisibleRect(rect);
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index f36b42a40..dbbe1a0c5 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -134,7 +134,7 @@ public final class InputLogic {
resetComposingState(true /* alsoResetLastComposedWord */);
mDeleteCount = 0;
mSpaceState = SpaceState.NONE;
- mRecapitalizeStatus.deactivate();
+ mRecapitalizeStatus.disable(); // Do not perform recapitalize until the cursor is moved once
mCurrentlyPressedHardwareKeys.clear();
mSuggestedWords = SuggestedWords.EMPTY;
// In some cases (namely, after rotation of the device) editorInfo.initialSelStart is lying
@@ -345,10 +345,12 @@ public final class InputLogic {
newSelStart, newSelEnd, false /* shouldFinishComposition */);
}
+ // The cursor has been moved : we now accept to perform recapitalization
+ mRecapitalizeStatus.enable();
// We moved the cursor. If we are touching a word, we need to resume suggestion.
mLatinIME.mHandler.postResumeSuggestions();
- // Reset the last recapitalization.
- mRecapitalizeStatus.deactivate();
+ // Stop the last recapitalization, if started.
+ mRecapitalizeStatus.stop();
return true;
}
@@ -369,10 +371,6 @@ public final class InputLogic {
final int keyboardShiftMode,
// TODO: remove this argument
final LatinIME.UIHandler handler) {
- // TODO: rework the following to not squash the keycode and the code point into the same
- // var because it's confusing. Instead the switch() should handle this in a readable manner.
- final int code =
- Event.NOT_A_CODE_POINT == event.mCodePoint ? event.mKeyCode : event.mCodePoint;
final InputTransaction inputTransaction = new InputTransaction(settingsValues, event,
SystemClock.uptimeMillis(), mSpaceState,
getActualCapsMode(settingsValues, keyboardShiftMode));
@@ -1138,8 +1136,8 @@ public final class InputLogic {
* @param settingsValues The current settings values.
*/
private void performRecapitalization(final SettingsValues settingsValues) {
- if (!mConnection.hasSelection()) {
- return; // No selection
+ if (!mConnection.hasSelection() || !mRecapitalizeStatus.mIsEnabled()) {
+ return; // No selection or recapitalize is disabled for now
}
final int selectionStart = mConnection.getExpectedSelectionStart();
final int selectionEnd = mConnection.getExpectedSelectionEnd();
@@ -1149,13 +1147,13 @@ public final class InputLogic {
// to suck possibly multiple-megabyte data.
return;
}
- // If we have a recapitalize in progress, use it; otherwise, create a new one.
- if (!mRecapitalizeStatus.isActive()
+ // If we have a recapitalize in progress, use it; otherwise, start a new one.
+ if (!mRecapitalizeStatus.isStarted()
|| !mRecapitalizeStatus.isSetAt(selectionStart, selectionEnd)) {
final CharSequence selectedText =
mConnection.getSelectedText(0 /* flags, 0 for no styles */);
if (TextUtils.isEmpty(selectedText)) return; // Race condition with the input connection
- mRecapitalizeStatus.initialize(selectionStart, selectionEnd, selectedText.toString(),
+ mRecapitalizeStatus.start(selectionStart, selectionEnd, selectedText.toString(),
settingsValues.mLocale,
settingsValues.mSpacingAndPunctuations.mSortedWordSeparators);
// We trim leading and trailing whitespace.
@@ -1498,7 +1496,7 @@ public final class InputLogic {
}
public int getCurrentRecapitalizeState() {
- if (!mRecapitalizeStatus.isActive()
+ if (!mRecapitalizeStatus.isStarted()
|| !mRecapitalizeStatus.isSetAt(mConnection.getExpectedSelectionStart(),
mConnection.getExpectedSelectionEnd())) {
// Not recapitalizing at the moment
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index af46aad96..5eb0377c7 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -41,6 +41,7 @@ import com.android.inputmethod.keyboard.KeyboardTheme;
import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SubtypeSwitcher;
+import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.setup.LauncherIconVisibilityManager;
import com.android.inputmethod.latin.userdictionary.UserDictionaryList;
import com.android.inputmethod.latin.userdictionary.UserDictionarySettings;
@@ -212,6 +213,20 @@ public final class SettingsFragment extends InputMethodSettingsFragment
textCorrectionGroup.removePreference(dictionaryLink);
}
+ if (ProductionFlag.IS_METRICS_LOGGING_SUPPORTED) {
+ final Preference enableMetricsLogging =
+ findPreference(Settings.PREF_ENABLE_METRICS_LOGGING);
+ if (enableMetricsLogging != null) {
+ final int applicationLabelRes = context.getApplicationInfo().labelRes;
+ final String applicationName = res.getString(applicationLabelRes);
+ final String enableMetricsLoggingTitle = res.getString(
+ R.string.enable_metrics_logging, applicationName);
+ enableMetricsLogging.setTitle(enableMetricsLoggingTitle);
+ }
+ } else {
+ removePreference(Settings.PREF_ENABLE_METRICS_LOGGING, textCorrectionGroup);
+ }
+
final Preference editPersonalDictionary =
findPreference(Settings.PREF_EDIT_PERSONAL_DICTIONARY);
final Intent editPersonalDictionaryIntent = editPersonalDictionary.getIntent();
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
index aa59db678..79a735ad6 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
@@ -20,6 +20,8 @@ import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
+import com.android.inputmethod.accessibility.AccessibilityUtils;
+import com.android.inputmethod.accessibility.MoreSuggestionsAccessibilityDelegate;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardActionListener;
@@ -50,6 +52,18 @@ public final class MoreSuggestionsView extends MoreKeysKeyboardView {
}
@Override
+ public void setKeyboard(final Keyboard keyboard) {
+ super.setKeyboard(keyboard);
+ // With accessibility mode off, {@link #mAccessibilityDelegate} is set to null at the
+ // above {@link MoreKeysKeyboardView#setKeyboard(Keyboard)} call.
+ if (AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
+ mAccessibilityDelegate = new MoreSuggestionsAccessibilityDelegate(this, mKeyDetector);
+ mAccessibilityDelegate.setOpenAnnounce(R.string.spoken_open_more_suggestions);
+ mAccessibilityDelegate.setCloseAnnounce(R.string.spoken_close_more_suggestions);
+ }
+ }
+
+ @Override
protected int getDefaultCoordX() {
final MoreSuggestions pane = (MoreSuggestions)getKeyboard();
return pane.mOccupiedWidth / 2;
diff --git a/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java b/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java
index 4521ec531..e3cac97f0 100644
--- a/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java
+++ b/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java
@@ -62,18 +62,22 @@ public class RecapitalizeStatus {
private Locale mLocale;
private int[] mSortedSeparators;
private String mStringAfter;
- private boolean mIsActive;
+ private boolean mIsStarted;
+ private boolean mIsEnabled = true;
private static final int[] EMPTY_STORTED_SEPARATORS = {};
public RecapitalizeStatus() {
// By default, initialize with dummy values that won't match any real recapitalize.
- initialize(-1, -1, "", Locale.getDefault(), EMPTY_STORTED_SEPARATORS);
- deactivate();
+ start(-1, -1, "", Locale.getDefault(), EMPTY_STORTED_SEPARATORS);
+ stop();
}
- public void initialize(final int cursorStart, final int cursorEnd, final String string,
+ public void start(final int cursorStart, final int cursorEnd, final String string,
final Locale locale, final int[] sortedSeparators) {
+ if (!mIsEnabled) {
+ return;
+ }
mCursorStartBefore = cursorStart;
mStringBefore = string;
mCursorStartAfter = cursorStart;
@@ -96,15 +100,27 @@ public class RecapitalizeStatus {
mRotationStyleCurrentIndex = currentMode;
mSkipOriginalMixedCaseMode = true;
}
- mIsActive = true;
+ mIsStarted = true;
+ }
+
+ public void stop() {
+ mIsStarted = false;
+ }
+
+ public boolean isStarted() {
+ return mIsStarted;
+ }
+
+ public void enable() {
+ mIsEnabled = true;
}
- public void deactivate() {
- mIsActive = false;
+ public void disable() {
+ mIsEnabled = false;
}
- public boolean isActive() {
- return mIsActive;
+ public boolean mIsEnabled() {
+ return mIsEnabled;
}
public boolean isSetAt(final int cursorStart, final int cursorEnd) {