aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java42
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java29
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java28
-rw-r--r--java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java10
-rw-r--r--java/src/com/android/inputmethod/keyboard/PopupPanel.java2
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java1
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java50
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java13
9 files changed, 128 insertions, 53 deletions
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
index 8ca834148..86a56308a 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
@@ -105,13 +105,13 @@ public class AccessibleKeyboardViewProxy {
}
/**
- * Receives hover events when accessibility is turned on in API > 11. In
- * earlier API levels, events are manually routed from onTouchEvent.
+ * Receives hover events when accessibility is turned on in SDK versions ICS
+ * and higher.
*
* @param event The hover event.
* @return {@code true} if the event is handled
*/
- public boolean onHoverEvent(MotionEvent event, PointerTracker tracker) {
+ public boolean dispatchHoverEvent(MotionEvent event, PointerTracker tracker) {
if (mGestureDetector.onHoverEvent(event, this, tracker))
return true;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 1010adbe0..fc47713b8 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -87,8 +87,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
private final KeyDrawParams mKeyDrawParams;
// Key preview
+ private final int mKeyPreviewLayoutId;
private final KeyPreviewDrawParams mKeyPreviewDrawParams;
- private final TextView mPreviewText;
private boolean mShowKeyPreviewPopup = true;
private final int mDelayBeforePreview;
private int mDelayAfterPreview;
@@ -139,9 +139,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
keyboardView.showKey(msg.arg1, tracker);
break;
case MSG_DISMISS_KEY_PREVIEW:
- if (keyboardView.mPreviewText != null) {
- keyboardView.mPreviewText.setVisibility(View.INVISIBLE);
- }
+ tracker.getKeyPreviewText().setVisibility(View.INVISIBLE);
break;
}
}
@@ -150,7 +148,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
removeMessages(MSG_SHOW_KEY_PREVIEW);
final KeyboardView keyboardView = getOuterInstance();
if (keyboardView == null) return;
- if (keyboardView.mPreviewText.getVisibility() == VISIBLE || delay == 0) {
+ if (tracker.getKeyPreviewText().getVisibility() == VISIBLE || delay == 0) {
// Show right away, if it's already visible and finger is moving around
keyboardView.showKey(keyIndex, tracker);
} else {
@@ -171,6 +169,10 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
sendMessageDelayed(obtainMessage(MSG_DISMISS_KEY_PREVIEW, tracker), delay);
}
+ public void cancelDismissKeyPreview(PointerTracker tracker) {
+ removeMessages(MSG_DISMISS_KEY_PREVIEW, tracker);
+ }
+
public void cancelAllDismissKeyPreviews() {
removeMessages(MSG_DISMISS_KEY_PREVIEW);
}
@@ -317,11 +319,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
mKeyDrawParams = new KeyDrawParams(a);
mKeyPreviewDrawParams = new KeyPreviewDrawParams(a, mKeyDrawParams);
- final int previewLayout = a.getResourceId(R.styleable.KeyboardView_keyPreviewLayout, 0);
- if (previewLayout != 0) {
- mPreviewText = (TextView) LayoutInflater.from(context).inflate(previewLayout, null);
- } else {
- mPreviewText = null;
+ mKeyPreviewLayoutId = a.getResourceId(R.styleable.KeyboardView_keyPreviewLayout, 0);
+ if (mKeyPreviewLayoutId == 0) {
mShowKeyPreviewPopup = false;
}
mBackgroundDimAmount = a.getFloat(R.styleable.KeyboardView_backgroundDimAmount, 0.5f);
@@ -730,6 +729,17 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
mDrawingHandler.cancelAllMessages();
}
+ // Called by {@link PointerTracker} constructor to create a TextView.
+ @Override
+ public TextView inflateKeyPreviewText() {
+ final Context context = getContext();
+ if (mKeyPreviewLayoutId != 0) {
+ return (TextView)LayoutInflater.from(context).inflate(mKeyPreviewLayoutId, null);
+ } else {
+ return new TextView(context);
+ }
+ }
+
@Override
public void showKeyPreview(int keyIndex, PointerTracker tracker) {
if (mShowKeyPreviewPopup) {
@@ -760,15 +770,15 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
// TODO: Introduce minimum duration for displaying key previews
- // TODO: Display up to two key previews when the user presses two keys at the same time
private void showKey(final int keyIndex, PointerTracker tracker) {
- final TextView previewText = mPreviewText;
+ final TextView previewText = tracker.getKeyPreviewText();
// If the key preview has no parent view yet, add it to the ViewGroup which can place
// key preview absolutely in SoftInputWindow.
if (previewText.getParent() == null) {
addKeyPreview(previewText);
}
+ mDrawingHandler.cancelDismissKeyPreview(tracker);
final Key key = tracker.getKey(keyIndex);
// If keyIndex is invalid or IME is already closed, we must not show key preview.
// Trying to show key preview while root window is closed causes
@@ -776,7 +786,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
if (key == null)
return;
- mDrawingHandler.cancelAllDismissKeyPreviews();
final KeyPreviewDrawParams params = mKeyPreviewDrawParams;
final int keyDrawX = key.mX + key.mVisualInsetsLeft;
final int keyDrawWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
@@ -858,13 +867,18 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
public void closing() {
- mPreviewText.setVisibility(View.GONE);
+ PointerTracker.dismissAllKeyPreviews();
cancelAllMessages();
mDirtyRect.union(0, 0, getWidth(), getHeight());
requestLayout();
}
+ @Override
+ public boolean dismissPopupPanel() {
+ return false;
+ }
+
public void purgeKeyboardAndClosing() {
mKeyboard = null;
closing();
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
index 0ad91dbb0..cb1a2b782 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
@@ -400,11 +400,10 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
mPopupPanel = popupPanel;
mPopupPanelPointerTrackerId = tracker.mPointerId;
- tracker.onLongPressed();
- popupPanel.showPanel(this, parentKey, tracker, mPopupWindow);
+ popupPanel.showPopupPanel(this, parentKey, tracker, mPopupWindow);
final int translatedX = popupPanel.translateX(tracker.getLastX());
final int translatedY = popupPanel.translateY(tracker.getLastY());
- tracker.onDownEvent(translatedX, translatedY, SystemClock.uptimeMillis(), popupPanel);
+ tracker.onShowPopupPanel(translatedX, translatedY, SystemClock.uptimeMillis(), popupPanel);
invalidateAllKeys();
return true;
@@ -546,11 +545,12 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
@Override
public void closing() {
super.closing();
- dismissMiniKeyboard();
+ dismissPopupPanel();
mPopupPanelCache.clear();
}
- public boolean dismissMiniKeyboard() {
+ @Override
+ public boolean dismissPopupPanel() {
if (mPopupWindow != null && mPopupWindow.isShowing()) {
mPopupWindow.dismiss();
mPopupPanel = null;
@@ -562,7 +562,7 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
}
public boolean handleBack() {
- return dismissMiniKeyboard();
+ return dismissPopupPanel();
}
@Override
@@ -586,15 +586,22 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
return super.dispatchPopulateAccessibilityEvent(event);
}
- public boolean onHoverEvent(MotionEvent event) {
- // Since reflection doesn't support calling superclass methods, this
- // method checks for the existence of onHoverEvent() in the View class
- // before returning a value.
+ /**
+ * Receives hover events from the input framework. This method overrides
+ * View.dispatchHoverEvent(MotionEvent) on SDK version ICS or higher. On
+ * lower SDK versions, this method is never called.
+ *
+ * @param event The motion event to be dispatched.
+ * @return {@code true} if the event was handled by the view, {@code false}
+ * otherwise
+ */
+ public boolean dispatchHoverEvent(MotionEvent event) {
if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
final PointerTracker tracker = getPointerTracker(0);
- return AccessibleKeyboardViewProxy.getInstance().onHoverEvent(event, tracker);
+ return AccessibleKeyboardViewProxy.getInstance().dispatchHoverEvent(event, tracker);
}
+ // Reflection doesn't support calling superclass methods.
return false;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index e66ea7b79..f64835726 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.keyboard;
import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
+import android.widget.TextView;
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
import com.android.inputmethod.latin.LatinImeLogger;
@@ -64,9 +65,11 @@ public class PointerTracker {
public interface DrawingProxy {
public void invalidateKey(Key key);
+ public TextView inflateKeyPreviewText();
public void showKeyPreview(int keyIndex, PointerTracker tracker);
public void cancelShowKeyPreview(PointerTracker tracker);
public void dismissKeyPreview(PointerTracker tracker);
+ public boolean dismissPopupPanel();
}
public interface TimerProxy {
@@ -99,6 +102,7 @@ public class PointerTracker {
private Keyboard mKeyboard;
private List<Key> mKeys;
private int mKeyQuarterWidthSquared;
+ private final TextView mKeyPreviewText;
// The position and time at which first down event occurred.
private long mDownTime;
@@ -117,9 +121,12 @@ public class PointerTracker {
// true if keyboard layout has been changed.
private boolean mKeyboardLayoutHasBeenChanged;
- // true if event is already translated to a key action (long press or mini-keyboard)
+ // true if event is already translated to a key action.
private boolean mKeyAlreadyProcessed;
+ // true if this pointer has been long-pressed and is showing a popup panel.
+ private boolean mIsShowingPopupPanel;
+
// true if this pointer is repeatable key
private boolean mIsRepeatableKey;
@@ -211,6 +218,11 @@ public class PointerTracker {
mListener = handler.getKeyboardActionListener();
mDrawingProxy = handler.getDrawingProxy();
mTimerProxy = handler.getTimerProxy();
+ mKeyPreviewText = mDrawingProxy.inflateKeyPreviewText();
+ }
+
+ public TextView getKeyPreviewText() {
+ return mKeyPreviewText;
}
// Returns true if keyboard has been changed by this callback.
@@ -579,6 +591,10 @@ public class PointerTracker {
}
final int keyIndex = onUpKey(keyX, keyY, eventTime);
setReleasedKeyGraphics(keyIndex);
+ if (mIsShowingPopupPanel) {
+ mDrawingProxy.dismissPopupPanel();
+ mIsShowingPopupPanel = false;
+ }
if (mKeyAlreadyProcessed)
return;
if (!mIsRepeatableKey) {
@@ -586,6 +602,12 @@ public class PointerTracker {
}
}
+ public void onShowPopupPanel(int x, int y, long eventTime, KeyEventHandler handler) {
+ onLongPressed();
+ onDownEvent(x, y, eventTime, handler);
+ mIsShowingPopupPanel = true;
+ }
+
public void onLongPressed() {
mKeyAlreadyProcessed = true;
setReleasedKeyGraphics(mKeyIndex);
@@ -612,6 +634,10 @@ public class PointerTracker {
mDrawingProxy.cancelShowKeyPreview(this);
setReleasedKeyGraphics(mKeyIndex);
mIsInSlidingKeyInput = false;
+ if (mIsShowingPopupPanel) {
+ mDrawingProxy.dismissPopupPanel();
+ mIsShowingPopupPanel = false;
+ }
}
private void startRepeatKey(int keyIndex) {
diff --git a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
index a90f57c62..2741ee80b 100644
--- a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
@@ -59,19 +59,16 @@ public class PopupMiniKeyboardView extends KeyboardView implements PopupPanel {
public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {
mParentKeyboardView.getKeyboardActionListener()
.onCodeInput(primaryCode, keyCodes, x, y);
- mParentKeyboardView.dismissMiniKeyboard();
}
@Override
public void onTextInput(CharSequence text) {
mParentKeyboardView.getKeyboardActionListener().onTextInput(text);
- mParentKeyboardView.dismissMiniKeyboard();
}
@Override
public void onCancelInput() {
mParentKeyboardView.getKeyboardActionListener().onCancelInput();
- mParentKeyboardView.dismissMiniKeyboard();
}
@Override
@@ -159,7 +156,7 @@ public class PopupMiniKeyboardView extends KeyboardView implements PopupPanel {
}
@Override
- public void showPanel(LatinKeyboardBaseView parentKeyboardView, Key parentKey,
+ public void showPopupPanel(LatinKeyboardBaseView parentKeyboardView, Key parentKey,
PointerTracker tracker, PopupWindow window) {
mParentKeyboardView = parentKeyboardView;
final View container = (View)getParent();
@@ -192,6 +189,11 @@ public class PopupMiniKeyboardView extends KeyboardView implements PopupPanel {
}
@Override
+ public boolean dismissPopupPanel() {
+ return mParentKeyboardView.dismissPopupPanel();
+ }
+
+ @Override
public int translateX(int x) {
return x - mOriginX;
}
diff --git a/java/src/com/android/inputmethod/keyboard/PopupPanel.java b/java/src/com/android/inputmethod/keyboard/PopupPanel.java
index f94d1c562..dc526e74f 100644
--- a/java/src/com/android/inputmethod/keyboard/PopupPanel.java
+++ b/java/src/com/android/inputmethod/keyboard/PopupPanel.java
@@ -26,7 +26,7 @@ public interface PopupPanel extends PointerTracker.KeyEventHandler {
* @param tracker the pointer tracker that pressesd the parent key
* @param window PopupWindow to be used to show this popup panel
*/
- public void showPanel(LatinKeyboardBaseView parentKeyboardView, Key parentKey,
+ public void showPopupPanel(LatinKeyboardBaseView parentKeyboardView, Key parentKey,
PointerTracker tracker, PopupWindow window);
/**
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index 00d80f566..41b577cf3 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -107,6 +107,7 @@ public class BinaryDictionaryFileDumper {
if (null == afd) return null;
final String fileName =
copyFileTo(afd.createInputStream(), getCacheFileNameForLocale(locale, context));
+ afd.close();
return Arrays.asList(AssetFileAddress.makeFromFileName(fileName));
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 8ae653f2f..c2452b947 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -102,6 +102,8 @@ public class Suggest implements Dictionary.WordCallback {
private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
ArrayList<CharSequence> mBigramSuggestions = new ArrayList<CharSequence>();
+ // TODO: maybe this should be synchronized, it's quite scary as it is.
+ // TODO: if it becomes synchronized, also move initPool in the thread in initAsynchronously
private ArrayList<CharSequence> mStringPool = new ArrayList<CharSequence>();
private CharSequence mTypedWord;
@@ -111,27 +113,39 @@ public class Suggest implements Dictionary.WordCallback {
private int mCorrectionMode = CORRECTION_BASIC;
- public Suggest(Context context, int dictionaryResId, Locale locale) {
- init(context, DictionaryFactory.createDictionaryFromManager(context, locale,
- dictionaryResId));
+ public Suggest(final Context context, final int dictionaryResId, final Locale locale) {
+ initAsynchronously(context, dictionaryResId, locale);
}
/* package for test */ Suggest(Context context, File dictionary, long startOffset, long length,
Flag[] flagArray) {
- init(null, DictionaryFactory.createDictionaryForTest(context, dictionary, startOffset,
- length, flagArray));
+ initSynchronously(null, DictionaryFactory.createDictionaryForTest(context, dictionary,
+ startOffset, length, flagArray));
}
- private void init(Context context, Dictionary mainDict) {
- mMainDict = mainDict;
- addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, mainDict);
- addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, mainDict);
+ private void initWhitelistAndAutocorrectAndPool(final Context context) {
mWhiteListDictionary = WhitelistDictionary.init(context);
addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_WHITELIST, mWhiteListDictionary);
mAutoCorrection = new AutoCorrection();
initPool();
}
+ private void initAsynchronously(final Context context, final int dictionaryResId,
+ final Locale locale) {
+ resetMainDict(context, dictionaryResId, locale);
+
+ // TODO: read the whitelist and init the pool asynchronously too.
+ // initPool should be done asynchronously but the pool is not thread-safe at the moment.
+ initWhitelistAndAutocorrectAndPool(context);
+ }
+
+ private void initSynchronously(Context context, Dictionary mainDict) {
+ mMainDict = mainDict;
+ addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, mainDict);
+ addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, mainDict);
+ initWhitelistAndAutocorrectAndPool(context);
+ }
+
private void addOrReplaceDictionary(Map<String, Dictionary> dictionaries, String key,
Dictionary dict) {
final Dictionary oldDict = (dict == null)
@@ -142,12 +156,18 @@ public class Suggest implements Dictionary.WordCallback {
}
}
- public void resetMainDict(Context context, int dictionaryResId, Locale locale) {
- final Dictionary newMainDict = DictionaryFactory.createDictionaryFromManager(
- context, locale, dictionaryResId);
- mMainDict = newMainDict;
- addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, newMainDict);
- addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, newMainDict);
+ public void resetMainDict(final Context context, final int dictionaryResId,
+ final Locale locale) {
+ mMainDict = null;
+ new Thread("InitializeBinaryDictionary") {
+ public void run() {
+ final Dictionary newMainDict = DictionaryFactory.createDictionaryFromManager(
+ context, locale, dictionaryResId);
+ mMainDict = newMainDict;
+ addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, newMainDict);
+ addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, newMainDict);
+ }
+ }.start();
}
private void initPool() {
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 84db17504..b77cbd199 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin;
+import android.text.TextUtils;
import android.view.inputmethod.CompletionInfo;
import java.util.ArrayList;
@@ -105,14 +106,18 @@ public class SuggestedWords {
}
private Builder addWord(CharSequence word, SuggestedWordInfo suggestedWordInfo) {
- mWords.add(word);
- mSuggestedWordInfoList.add(suggestedWordInfo);
+ if (!TextUtils.isEmpty(word)) {
+ mWords.add(word);
+ // It's okay if suggestedWordInfo is null since it's checked where it's used.
+ mSuggestedWordInfoList.add(suggestedWordInfo);
+ }
return this;
}
public Builder setApplicationSpecifiedCompletions(CompletionInfo[] infos) {
- for (CompletionInfo info : infos)
- addWord(info.getText());
+ for (CompletionInfo info : infos) {
+ if (null != info) addWord(info.getText());
+ }
return this;
}