diff options
Diffstat (limited to 'java/src')
119 files changed, 1127 insertions, 934 deletions
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java index d50dd3ee6..27896fd11 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java @@ -114,7 +114,7 @@ public final class AccessibilityUtils { * @param event The event to check. * @return {@true} is the event is a touch exploration event */ - public boolean isTouchExplorationEvent(final MotionEvent event) { + public static boolean isTouchExplorationEvent(final MotionEvent event) { final int action = event.getAction(); return action == MotionEvent.ACTION_HOVER_ENTER || action == MotionEvent.ACTION_HOVER_EXIT diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java index 2c87fc1e9..58672ace7 100644 --- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java +++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java @@ -285,15 +285,14 @@ public final class KeyCodeDescriptionMapper { if (index >= 0) { return context.getString(mKeyCodeMap.valueAt(index)); } - final String accentedLetter = getSpokenAccentedLetterDescriptionId(context, code); + final String accentedLetter = getSpokenAccentedLetterDescription(context, code); if (accentedLetter != null) { return accentedLetter; } - // Here, <code>code</code> may be a base letter. - final int spokenEmojiId = getSpokenDescriptionId( - context, code, SPOKEN_EMOJI_RESOURCE_NAME_FORMAT); - if (spokenEmojiId != 0) { - return context.getString(spokenEmojiId); + // Here, <code>code</code> may be a base (non-accented) letter. + final String emojiDescription = getSpokenEmojiDescription(context, code); + if (emojiDescription != null) { + return emojiDescription; } if (isDefinedNonCtrl) { return Character.toString((char) code); @@ -304,7 +303,7 @@ public final class KeyCodeDescriptionMapper { return context.getString(R.string.spoken_description_unknown, code); } - private String getSpokenAccentedLetterDescriptionId(final Context context, final int code) { + private String getSpokenAccentedLetterDescription(final Context context, final int code) { final boolean isUpperCase = Character.isUpperCase(code); final int baseCode = isUpperCase ? Character.toLowerCase(code) : code; final int baseIndex = mKeyCodeMap.indexOfKey(baseCode); @@ -314,7 +313,17 @@ public final class KeyCodeDescriptionMapper { return null; } final String spokenText = context.getString(resId); - return isUpperCase ? context.getString(R.string.spoke_description_upper_case, spokenText) + return isUpperCase ? context.getString(R.string.spoken_description_upper_case, spokenText) + : spokenText; + } + + private String getSpokenEmojiDescription(final Context context, final int code) { + final int resId = getSpokenDescriptionId(context, code, SPOKEN_EMOJI_RESOURCE_NAME_FORMAT); + if (resId == 0) { + return null; + } + final String spokenText = context.getString(resId); + return TextUtils.isEmpty(spokenText) ? context.getString(R.string.spoken_emoji_unknown) : spokenText; } diff --git a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java index eed40f4a9..7cae9861c 100644 --- a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java +++ b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java @@ -16,11 +16,12 @@ package com.android.inputmethod.accessibility; -import android.os.SystemClock; +import android.content.Context; import android.support.v4.view.AccessibilityDelegateCompat; import android.support.v4.view.ViewCompat; import android.support.v4.view.accessibility.AccessibilityEventCompat; import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; +import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewParent; @@ -30,6 +31,7 @@ import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.KeyDetector; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardView; +import com.android.inputmethod.keyboard.PointerTracker; public class KeyboardAccessibilityDelegate<KV extends KeyboardView> extends AccessibilityDelegateCompat { @@ -37,7 +39,7 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView> protected final KeyDetector mKeyDetector; private Keyboard mKeyboard; private KeyboardAccessibilityNodeProvider mAccessibilityNodeProvider; - private Key mLastHoverKey; + private Key mCurrentHoverKey; public KeyboardAccessibilityDelegate(final KV keyboardView, final KeyDetector keyDetector) { super(); @@ -65,10 +67,31 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView> mKeyboard = keyboard; } - protected Keyboard getKeyboard() { + protected final Keyboard getKeyboard() { return mKeyboard; } + protected final void setCurrentHoverKey(final Key key) { + mCurrentHoverKey = key; + } + + protected final Key getCurrentHoverKey() { + return mCurrentHoverKey; + } + + /** + * Sends a window state change event with the specified string resource id. + * + * @param resId The string resource id of the text to send with the event. + */ + protected void sendWindowStateChanged(final int resId) { + if (resId == 0) { + return; + } + final Context context = mKeyboardView.getContext(); + sendWindowStateChanged(context.getString(resId)); + } + /** * Sends a window state change event with the specified text. * @@ -114,119 +137,157 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView> } /** + * Get a key that a hover event is on. + * + * @param event The hover event. + * @return key The key that the <code>event</code> is on. + */ + protected final Key getHoverKey(final MotionEvent event) { + final int actionIndex = event.getActionIndex(); + final int x = (int)event.getX(actionIndex); + final int y = (int)event.getY(actionIndex); + return mKeyDetector.detectHitKey(x, y); + } + + /** * Receives hover events when touch exploration is turned on in SDK versions ICS and higher. * * @param event The hover event. - * @return {@code true} if the event is handled + * @return {@code true} if the event is handled. */ - public boolean dispatchHoverEvent(final MotionEvent event) { - final int x = (int) event.getX(); - final int y = (int) event.getY(); - final Key previousKey = mLastHoverKey; - final Key key = mKeyDetector.detectHitKey(x, y); - mLastHoverKey = key; - - switch (event.getAction()) { - case MotionEvent.ACTION_HOVER_EXIT: - // 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) { - final long downTime = simulateKeyPress(key); - simulateKeyRelease(key, downTime); - } - //$FALL-THROUGH$ + public boolean onHoverEvent(final MotionEvent event) { + switch (event.getActionMasked()) { case MotionEvent.ACTION_HOVER_ENTER: - return onHoverKey(key, event); + onHoverEnter(event); + break; case MotionEvent.ACTION_HOVER_MOVE: - if (key != previousKey) { - return onTransitionKey(key, previousKey, event); + onHoverMove(event); + break; + case MotionEvent.ACTION_HOVER_EXIT: + onHoverExit(event); + break; + default: + Log.w(getClass().getSimpleName(), "Unknown hover event: " + event); + break; + } + return true; + } + + /** + * Process {@link MotionEvent#ACTION_HOVER_ENTER} event. + * + * @param event A hover enter event. + */ + protected void onHoverEnter(final MotionEvent event) { + final Key key = getHoverKey(event); + if (key != null) { + onHoverEnterKey(key); + } + setCurrentHoverKey(key); + } + + /** + * Process {@link MotionEvent#ACTION_HOVER_MOVE} event. + * + * @param event A hover move event. + */ + protected void onHoverMove(final MotionEvent event) { + final Key previousKey = getCurrentHoverKey(); + final Key key = getHoverKey(event); + if (key != previousKey) { + if (previousKey != null) { + onHoverExitKey(previousKey); } - return onHoverKey(key, event); + if (key != null) { + onHoverEnterKey(key); + } + } + if (key != null) { + onHoverMoveKey(key); } - return false; + setCurrentHoverKey(key); } /** - * Simulates a key press by injecting touch an event into the keyboard view. - * This avoids the complexity of trackers and listeners within the keyboard. + * Process {@link MotionEvent#ACTION_HOVER_EXIT} event. * - * @param key The key to press. + * @param event A hover exit event. */ - private long simulateKeyPress(final Key key) { - final int x = key.getHitBox().centerX(); - final int y = key.getHitBox().centerY(); - final long downTime = SystemClock.uptimeMillis(); - final MotionEvent downEvent = MotionEvent.obtain( - downTime, downTime, MotionEvent.ACTION_DOWN, x, y, 0); - mKeyboardView.onTouchEvent(downEvent); - downEvent.recycle(); - return downTime; + protected void onHoverExit(final MotionEvent event) { + final Key key = getHoverKey(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); + } + setCurrentHoverKey(null); } /** - * Simulates a key release by injecting touch an event into the keyboard view. - * This avoids the complexity of trackers and listeners within the keyboard. + * Simulating a touch event by injecting a synthesized touch event into {@link PointerTracker}. * - * @param key The key to release. + * @param touchAction The action of the synthesizing touch event. + * @param hoverEvent The base hover event from that the touch event is synthesized. */ - private void simulateKeyRelease(final Key key, final long downTime) { - final int x = key.getHitBox().centerX(); - final int y = key.getHitBox().centerY(); - final MotionEvent upEvent = MotionEvent.obtain( - downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, x, y, 0); - mKeyboardView.onTouchEvent(upEvent); - upEvent.recycle(); + protected void simulateTouchEvent(final int touchAction, final MotionEvent hoverEvent) { + final MotionEvent touchEvent = synthesizeTouchEvent(touchAction, hoverEvent); + final int actionIndex = touchEvent.getActionIndex(); + final int pointerId = touchEvent.getPointerId(actionIndex); + final PointerTracker tracker = PointerTracker.getPointerTracker(pointerId); + tracker.processMotionEvent(touchEvent, mKeyDetector); + touchEvent.recycle(); } /** - * Simulates a transition between two {@link Key}s by sending a HOVER_EXIT on the previous key, - * a HOVER_ENTER on the current key, and a HOVER_MOVE on the current key. + * Synthesize a touch event from a hover event. * - * @param currentKey The currently hovered key. - * @param previousKey The previously hovered key. - * @param event The event that triggered the transition. - * @return {@code true} if the event was handled. + * @param touchAction The action of the synthesizing touch event. + * @param event The base hover event from that the touch event is synthesized. + * @return The synthesized touch event of <code>touchAction</code> that has pointer information + * of <code>event</code>. */ - private boolean onTransitionKey(final Key currentKey, final Key previousKey, + protected static MotionEvent synthesizeTouchEvent(final int touchAction, final MotionEvent event) { - final int savedAction = event.getAction(); - event.setAction(MotionEvent.ACTION_HOVER_EXIT); - onHoverKey(previousKey, event); - event.setAction(MotionEvent.ACTION_HOVER_ENTER); - onHoverKey(currentKey, event); - event.setAction(MotionEvent.ACTION_HOVER_MOVE); - final boolean handled = onHoverKey(currentKey, event); - event.setAction(savedAction); - return handled; + final long downTime = event.getDownTime(); + final long eventTime = event.getEventTime(); + final int actionIndex = event.getActionIndex(); + final float x = event.getX(actionIndex); + final float y = event.getY(actionIndex); + final int pointerId = event.getPointerId(actionIndex); + return MotionEvent.obtain(downTime, eventTime, touchAction, x, y, pointerId); } /** - * Handles a hover event on a key. If {@link Key} extended View, this would be analogous to - * calling View.onHoverEvent(MotionEvent). + * Handles a hover enter event on a key. * * @param key The currently hovered key. - * @param event The hover event. - * @return {@code true} if the event was handled. */ - private boolean onHoverKey(final Key key, final MotionEvent event) { - // Null keys can't receive events. - if (key == null) { - return false; - } + protected void onHoverEnterKey(final Key key) { + key.onPressed(); + mKeyboardView.invalidateKey(key); final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider(); + provider.sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_HOVER_ENTER); + provider.performActionForKey(key, AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS); + } - switch (event.getAction()) { - case MotionEvent.ACTION_HOVER_ENTER: - provider.sendAccessibilityEventForKey( - key, AccessibilityEventCompat.TYPE_VIEW_HOVER_ENTER); - provider.performActionForKey( - key, AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS, null); - break; - case MotionEvent.ACTION_HOVER_EXIT: - provider.sendAccessibilityEventForKey( - key, AccessibilityEventCompat.TYPE_VIEW_HOVER_EXIT); - break; - } - return true; + /** + * Handles a hover move event on a key. + * + * @param key The currently hovered key. + */ + protected void onHoverMoveKey(final Key key) { } + + /** + * Handles a hover exit event on a key. + * + * @param key The currently hovered key. + */ + protected void onHoverExitKey(final Key key) { + key.onReleased(); + mKeyboardView.invalidateKey(key); + final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider(); + provider.sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_HOVER_EXIT); } } diff --git a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java index cddd1c7ed..a6997e2f9 100644 --- a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java +++ b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java @@ -134,7 +134,7 @@ public final class KeyboardAccessibilityNodeProvider extends AccessibilityNodePr event.setClassName(key.getClass().getName()); event.setContentDescription(keyDescription); event.setEnabled(true); - final AccessibilityRecordCompat record = new AccessibilityRecordCompat(event); + final AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event); record.setSource(mKeyboardView, virtualViewId); return event; } @@ -229,7 +229,7 @@ public final class KeyboardAccessibilityNodeProvider extends AccessibilityNodePr if (key == null) { return false; } - return performActionForKey(key, action, arguments); + return performActionForKey(key, action); } /** @@ -237,25 +237,16 @@ public final class KeyboardAccessibilityNodeProvider extends AccessibilityNodePr * * @param key The on which to perform the action. * @param action The action to perform. - * @param arguments The action's arguments. * @return The result of performing the action, or false if the action is not supported. */ - boolean performActionForKey(final Key key, final int action, final Bundle arguments) { - final int virtualViewId = getVirtualViewIdOf(key); - + boolean performActionForKey(final Key key, final int action) { switch (action) { case AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS: - if (mAccessibilityFocusedView == virtualViewId) { - return false; - } - mAccessibilityFocusedView = virtualViewId; + mAccessibilityFocusedView = getVirtualViewIdOf(key); sendAccessibilityEventForKey( key, AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED); return true; case AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS: - if (mAccessibilityFocusedView != virtualViewId) { - return false; - } mAccessibilityFocusedView = UNDEFINED; sendAccessibilityEventForKey( key, AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); diff --git a/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java index c114551c8..ec6bb0156 100644 --- a/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java +++ b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java @@ -17,13 +17,8 @@ package com.android.inputmethod.accessibility; import android.content.Context; -import android.os.SystemClock; -import android.support.v4.view.accessibility.AccessibilityEventCompat; -import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; 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; @@ -168,17 +163,13 @@ public final class MainKeyboardAccessibilityDelegate default: return; } - final String text = mKeyboardView.getContext().getString(resId); - sendWindowStateChanged(text); + sendWindowStateChanged(resId); } /** * Announces that the keyboard has been hidden. */ private void announceKeyboardHidden() { - final Context context = mKeyboardView.getContext(); - final String text = context.getString(R.string.announce_keyboard_hidden); - - sendWindowStateChanged(text); + sendWindowStateChanged(R.string.announce_keyboard_hidden); } } diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java index 60f7e2def..4d51821f2 100644 --- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java +++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java @@ -27,7 +27,6 @@ import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestionSpanPickedNotificationReceiver; -import com.android.inputmethod.latin.utils.CollectionUtils; import java.lang.reflect.Field; import java.util.ArrayList; @@ -73,13 +72,13 @@ public final class SuggestionSpanUtils { return pickedWord; } - final ArrayList<String> suggestionsList = CollectionUtils.newArrayList(); + final ArrayList<String> suggestionsList = new ArrayList<>(); for (int i = 0; i < suggestedWords.size(); ++i) { if (suggestionsList.size() >= SuggestionSpan.SUGGESTIONS_MAX_SIZE) { break; } final SuggestedWordInfo info = suggestedWords.getInfo(i); - if (info.mKind == SuggestedWordInfo.KIND_PREDICTION) { + if (info.isKindOf(SuggestedWordInfo.KIND_PREDICTION)) { continue; } final String word = suggestedWords.getWord(i); diff --git a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java index dec739d39..767cc423d 100644 --- a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java +++ b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java @@ -24,23 +24,13 @@ import java.lang.reflect.Method; // Currently {@link #getPaddingEnd(View)} and {@link #setPaddingRelative(View,int,int,int,int)} // are missing from android-support-v4 static library in KitKat SDK. public final class ViewCompatUtils { - // Note that View.LAYOUT_DIRECTION_LTR and View.LAYOUT_DIRECTION_RTL have been introduced in - // API level 17 (Build.VERSION_CODE.JELLY_BEAN_MR1). - public static final int LAYOUT_DIRECTION_LTR = (Integer)CompatUtils.getFieldValue(null, 0x0, - CompatUtils.getField(View.class, "LAYOUT_DIRECTION_LTR")); - public static final int LAYOUT_DIRECTION_RTL = (Integer)CompatUtils.getFieldValue(null, 0x1, - CompatUtils.getField(View.class, "LAYOUT_DIRECTION_RTL")); - - // Note that View.getPaddingEnd(), View.setPaddingRelative(int,int,int,int), and - // View.getLayoutDirection() have been introduced in API level 17 - // (Build.VERSION_CODE.JELLY_BEAN_MR1). + // Note that View.getPaddingEnd(), View.setPaddingRelative(int,int,int,int) have been + // introduced in API level 17 (Build.VERSION_CODE.JELLY_BEAN_MR1). private static final Method METHOD_getPaddingEnd = CompatUtils.getMethod( View.class, "getPaddingEnd"); private static final Method METHOD_setPaddingRelative = CompatUtils.getMethod( View.class, "setPaddingRelative", Integer.TYPE, Integer.TYPE, Integer.TYPE, Integer.TYPE); - private static final Method METHOD_getLayoutDirection = CompatUtils.getMethod( - View.class, "getLayoutDirection"); private ViewCompatUtils() { // This utility class is not publicly instantiable. @@ -61,11 +51,4 @@ public final class ViewCompatUtils { } CompatUtils.invoke(view, null, METHOD_setPaddingRelative, start, top, end, bottom); } - - public static int getLayoutDirection(final View view) { - if (METHOD_getLayoutDirection == null) { - return LAYOUT_DIRECTION_LTR; - } - return (Integer)CompatUtils.invoke(view, 0, METHOD_getLayoutDirection); - } } diff --git a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java index 3f69cedee..3d294acd7 100644 --- a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java +++ b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java @@ -16,7 +16,6 @@ package com.android.inputmethod.dictionarypack; -import android.app.DownloadManager; import android.app.DownloadManager.Request; import android.content.ContentValues; import android.content.Context; @@ -600,7 +599,7 @@ public final class ActionBatch { private final Queue<Action> mActions; public ActionBatch() { - mActions = new LinkedList<Action>(); + mActions = new LinkedList<>(); } public void add(final Action a) { diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java index 2623eff56..1d84e5888 100644 --- a/java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java +++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java @@ -29,7 +29,6 @@ import android.view.View; import android.widget.ProgressBar; public class DictionaryDownloadProgressBar extends ProgressBar { - @SuppressWarnings("unused") private static final String TAG = DictionaryDownloadProgressBar.class.getSimpleName(); private static final int NOT_A_DOWNLOADMANAGER_PENDING_ID = 0; @@ -119,7 +118,6 @@ public class DictionaryDownloadProgressBar extends ProgressBar { try { final UpdateHelper updateHelper = new UpdateHelper(); final Query query = new Query().setFilterById(mId); - int lastProgress = 0; setIndeterminate(true); while (!isInterrupted()) { final Cursor cursor = mDownloadManagerWrapper.query(query); diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java index 13c07de35..8e026171d 100644 --- a/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java +++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java @@ -18,8 +18,6 @@ package com.android.inputmethod.dictionarypack; import android.view.View; -import com.android.inputmethod.latin.utils.CollectionUtils; - import java.util.ArrayList; import java.util.HashMap; @@ -39,8 +37,8 @@ public class DictionaryListInterfaceState { public int mStatus = MetadataDbHelper.STATUS_UNKNOWN; } - private HashMap<String, State> mWordlistToState = CollectionUtils.newHashMap(); - private ArrayList<View> mViewCache = CollectionUtils.newArrayList(); + private HashMap<String, State> mWordlistToState = new HashMap<>(); + private ArrayList<View> mViewCache = new ArrayList<>(); public boolean isOpen(final String wordlistId) { final State state = mWordlistToState.get(wordlistId); diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java index c35995b24..f5bd84c8c 100644 --- a/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java +++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java @@ -357,7 +357,7 @@ public final class DictionaryProvider extends ContentProvider { return Collections.<WordListInfo>emptyList(); } try { - final HashMap<String, WordListInfo> dicts = new HashMap<String, WordListInfo>(); + final HashMap<String, WordListInfo> dicts = new HashMap<>(); final int idIndex = results.getColumnIndex(MetadataDbHelper.WORDLISTID_COLUMN); final int localeIndex = results.getColumnIndex(MetadataDbHelper.LOCALE_COLUMN); final int localFileNameIndex = diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java index dae2f22a4..11982fa65 100644 --- a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java +++ b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java @@ -33,13 +33,13 @@ import android.preference.PreferenceGroup; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.Log; -import android.view.animation.AnimationUtils; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.view.animation.AnimationUtils; import com.android.inputmethod.latin.R; @@ -67,8 +67,8 @@ public final class DictionarySettingsFragment extends PreferenceFragment private boolean mChangedSettings; private DictionaryListInterfaceState mDictionaryListInterfaceState = new DictionaryListInterfaceState(); - private TreeMap<String, WordListPreference> mCurrentPreferenceMap = - new TreeMap<String, WordListPreference>(); // never null + // never null + private TreeMap<String, WordListPreference> mCurrentPreferenceMap = new TreeMap<>(); private final BroadcastReceiver mConnectivityChangedReceiver = new BroadcastReceiver() { @Override @@ -280,19 +280,18 @@ public final class DictionarySettingsFragment extends PreferenceFragment : activity.getContentResolver().query(contentUri, null, null, null, null); if (null == cursor) { - final ArrayList<Preference> result = new ArrayList<Preference>(); + final ArrayList<Preference> result = new ArrayList<>(); result.add(createErrorMessage(activity, R.string.cannot_connect_to_dict_service)); return result; } try { if (!cursor.moveToFirst()) { - final ArrayList<Preference> result = new ArrayList<Preference>(); + final ArrayList<Preference> result = new ArrayList<>(); result.add(createErrorMessage(activity, R.string.no_dictionaries_available)); return result; } else { final String systemLocaleString = Locale.getDefault().toString(); - final TreeMap<String, WordListPreference> prefMap = - new TreeMap<String, WordListPreference>(); + final TreeMap<String, WordListPreference> prefMap = new TreeMap<>(); final int idIndex = cursor.getColumnIndex(MetadataDbHelper.WORDLISTID_COLUMN); final int versionIndex = cursor.getColumnIndex(MetadataDbHelper.VERSION_COLUMN); final int localeIndex = cursor.getColumnIndex(MetadataDbHelper.LOCALE_COLUMN); diff --git a/java/src/com/android/inputmethod/dictionarypack/LocaleUtils.java b/java/src/com/android/inputmethod/dictionarypack/LocaleUtils.java index 77f67b8a3..4f0805c5c 100644 --- a/java/src/com/android/inputmethod/dictionarypack/LocaleUtils.java +++ b/java/src/com/android/inputmethod/dictionarypack/LocaleUtils.java @@ -175,7 +175,7 @@ public final class LocaleUtils { return saveLocale; } - private static final HashMap<String, Locale> sLocaleCache = new HashMap<String, Locale>(); + private static final HashMap<String, Locale> sLocaleCache = new HashMap<>(); /** * Creates a locale from a string specification. diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java index 668eb925b..17dd781d5 100644 --- a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java +++ b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java @@ -47,7 +47,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper { // used to identify the versions for upgrades. This should never change going forward. private static final int METADATA_DATABASE_VERSION_WITH_CLIENTID = 6; // The current database version. - private static final int CURRENT_METADATA_DATABASE_VERSION = 8; + private static final int CURRENT_METADATA_DATABASE_VERSION = 9; private final static long NOT_A_DOWNLOAD_ID = -1; @@ -160,7 +160,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper { // this legacy database. New clients should make sure to always pass a client ID so as // to avoid conflicts. final String clientId = null != clientIdOrNull ? clientIdOrNull : ""; - if (null == sInstanceMap) sInstanceMap = new TreeMap<String, MetadataDbHelper>(); + if (null == sInstanceMap) sInstanceMap = new TreeMap<>(); MetadataDbHelper helper = sInstanceMap.get(clientId); if (null == helper) { helper = new MetadataDbHelper(context, clientId); @@ -639,7 +639,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper { public static ArrayList<DownloadRecord> getDownloadRecordsForDownloadId(final Context context, final long downloadId) { final SQLiteDatabase defaultDb = getDb(context, ""); - final ArrayList<DownloadRecord> results = new ArrayList<DownloadRecord>(); + final ArrayList<DownloadRecord> results = new ArrayList<>(); final Cursor cursor = defaultDb.query(CLIENT_TABLE_NAME, CLIENT_TABLE_COLUMNS, null, null, null, null, null); try { @@ -923,7 +923,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper { // - Remove the old entry from the table // - Erase the old file // We start by gathering the names of the files we should delete. - final List<String> filenames = new LinkedList<String>(); + final List<String> filenames = new LinkedList<>(); final Cursor c = db.query(METADATA_TABLE_NAME, new String[] { LOCAL_FILENAME_COLUMN }, LOCALE_COLUMN + " = ? AND " + diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataHandler.java b/java/src/com/android/inputmethod/dictionarypack/MetadataHandler.java index 63e419871..d66b69050 100644 --- a/java/src/com/android/inputmethod/dictionarypack/MetadataHandler.java +++ b/java/src/com/android/inputmethod/dictionarypack/MetadataHandler.java @@ -43,7 +43,7 @@ public class MetadataHandler { * @return the constructed list of wordlist metadata. */ private static List<WordListMetadata> makeMetadataObject(final Cursor results) { - final ArrayList<WordListMetadata> buildingMetadata = new ArrayList<WordListMetadata>(); + final ArrayList<WordListMetadata> buildingMetadata = new ArrayList<>(); if (null != results && results.moveToFirst()) { final int localeColumn = results.getColumnIndex(MetadataDbHelper.LOCALE_COLUMN); final int typeColumn = results.getColumnIndex(MetadataDbHelper.TYPE_COLUMN); diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataParser.java b/java/src/com/android/inputmethod/dictionarypack/MetadataParser.java index a88173e8e..52290cadc 100644 --- a/java/src/com/android/inputmethod/dictionarypack/MetadataParser.java +++ b/java/src/com/android/inputmethod/dictionarypack/MetadataParser.java @@ -52,7 +52,7 @@ public class MetadataParser { */ private static WordListMetadata parseOneWordList(final JsonReader reader) throws IOException, BadFormatException { - final TreeMap<String, String> arguments = new TreeMap<String, String>(); + final TreeMap<String, String> arguments = new TreeMap<>(); reader.beginObject(); while (reader.hasNext()) { final String name = reader.nextName(); @@ -100,7 +100,7 @@ public class MetadataParser { public static List<WordListMetadata> parseMetadata(final InputStreamReader input) throws IOException, BadFormatException { JsonReader reader = new JsonReader(input); - final ArrayList<WordListMetadata> readInfo = new ArrayList<WordListMetadata>(); + final ArrayList<WordListMetadata> readInfo = new ArrayList<>(); reader.beginArray(); while (reader.hasNext()) { final WordListMetadata thisMetadata = parseOneWordList(reader); diff --git a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java index dcff490db..95a094232 100644 --- a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java +++ b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java @@ -177,7 +177,7 @@ public final class UpdateHandler { */ public static boolean tryUpdate(final Context context, final boolean updateNow) { // TODO: loop through all clients instead of only doing the default one. - final TreeSet<String> uris = new TreeSet<String>(); + final TreeSet<String> uris = new TreeSet<>(); final Cursor cursor = MetadataDbHelper.queryClientIds(context); if (null == cursor) return false; try { @@ -557,7 +557,7 @@ public final class UpdateHandler { // Instantiation of a parameterized type is not possible in Java, so it's not possible to // return the same type of list that was passed - probably the same reason why Collections // does not do it. So we need to decide statically which concrete type to return. - return new LinkedList<T>(src); + return new LinkedList<>(src); } /** @@ -740,10 +740,10 @@ public final class UpdateHandler { final ActionBatch actions = new ActionBatch(); // Upgrade existing word lists DebugLogUtils.l("Comparing dictionaries"); - final Set<String> wordListIds = new TreeSet<String>(); + final Set<String> wordListIds = new TreeSet<>(); // TODO: Can these be null? - if (null == from) from = new ArrayList<WordListMetadata>(); - if (null == to) to = new ArrayList<WordListMetadata>(); + if (null == from) from = new ArrayList<>(); + if (null == to) to = new ArrayList<>(); for (WordListMetadata wlData : from) wordListIds.add(wlData.mId); for (WordListMetadata wlData : to) wordListIds.add(wlData.mId); for (String id : wordListIds) { diff --git a/java/src/com/android/inputmethod/event/CombinerChain.java b/java/src/com/android/inputmethod/event/CombinerChain.java index 9e7f04d4f..61bc11b39 100644 --- a/java/src/com/android/inputmethod/event/CombinerChain.java +++ b/java/src/com/android/inputmethod/event/CombinerChain.java @@ -20,7 +20,6 @@ import android.text.SpannableStringBuilder; import android.text.TextUtils; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.ArrayList; import java.util.HashMap; @@ -44,8 +43,8 @@ public class CombinerChain { private SpannableStringBuilder mStateFeedback; private final ArrayList<Combiner> mCombiners; - private static final HashMap<String, Class> IMPLEMENTED_COMBINERS - = new HashMap<String, Class>(); + private static final HashMap<String, Class<? extends Combiner>> IMPLEMENTED_COMBINERS = + new HashMap<>(); static { IMPLEMENTED_COMBINERS.put("MyanmarReordering", MyanmarReordering.class); } @@ -63,7 +62,7 @@ public class CombinerChain { * @param combinerList A list of combiners to be applied in order. */ public CombinerChain(final String initialText, final Combiner... combinerList) { - mCombiners = CollectionUtils.newArrayList(); + mCombiners = new ArrayList<>(); // The dead key combiner is always active, and always first mCombiners.add(new DeadKeyCombiner()); for (final Combiner combiner : combinerList) { @@ -87,7 +86,7 @@ public class CombinerChain { * @param newEvent the new event to process */ public void processEvent(final ArrayList<Event> previousEvents, final Event newEvent) { - final ArrayList<Event> modifiablePreviousEvents = new ArrayList<Event>(previousEvents); + final ArrayList<Event> modifiablePreviousEvents = new ArrayList<>(previousEvents); Event event = newEvent; for (final Combiner combiner : mCombiners) { // A combiner can never return more than one event; it can return several @@ -136,12 +135,13 @@ public class CombinerChain { final Combiner[] combiners = new Combiner[combinerDescriptors.length]; int i = 0; for (final String combinerDescriptor : combinerDescriptors) { - final Class combinerClass = IMPLEMENTED_COMBINERS.get(combinerDescriptor); + final Class<? extends Combiner> combinerClass = + IMPLEMENTED_COMBINERS.get(combinerDescriptor); if (null == combinerClass) { throw new RuntimeException("Unknown combiner descriptor: " + combinerDescriptor); } try { - combiners[i++] = (Combiner)combinerClass.newInstance(); + combiners[i++] = combinerClass.newInstance(); } catch (InstantiationException e) { throw new RuntimeException("Unable to instantiate combiner: " + combinerDescriptor, e); diff --git a/java/src/com/android/inputmethod/event/MyanmarReordering.java b/java/src/com/android/inputmethod/event/MyanmarReordering.java index da0228bd2..32919932d 100644 --- a/java/src/com/android/inputmethod/event/MyanmarReordering.java +++ b/java/src/com/android/inputmethod/event/MyanmarReordering.java @@ -17,7 +17,6 @@ package com.android.inputmethod.event; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.ArrayList; import java.util.Arrays; @@ -32,7 +31,7 @@ public class MyanmarReordering implements Combiner { // U+200B ZERO WIDTH SPACE private final static int ZERO_WIDTH_NON_JOINER = 0x200B; // should be 0x200C - private final ArrayList<Event> mCurrentEvents = CollectionUtils.newArrayList(); + private final ArrayList<Event> mCurrentEvents = new ArrayList<>(); // List of consonants : // U+1000 MYANMAR LETTER KA diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index f646a03c2..85dfea4e7 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -22,9 +22,9 @@ import com.android.inputmethod.keyboard.internal.KeyVisualAttributes; import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; import com.android.inputmethod.keyboard.internal.KeyboardParams; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CoordinateUtils; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -83,7 +83,7 @@ public class Keyboard { public final List<Key> mAltCodeKeysWhileTyping; public final KeyboardIconsSet mIconsSet; - private final SparseArray<Key> mKeyCache = CollectionUtils.newSparseArray(); + private final SparseArray<Key> mKeyCache = new SparseArray<>(); private final ProximityInfo mProximityInfo; private final boolean mProximityCharsCorrectionEnabled; @@ -103,8 +103,7 @@ public class Keyboard { mTopPadding = params.mTopPadding; mVerticalGap = params.mVerticalGap; - mSortedKeys = Collections.unmodifiableList( - CollectionUtils.newArrayList(params.mSortedKeys)); + mSortedKeys = Collections.unmodifiableList(new ArrayList<>(params.mSortedKeys)); mShiftKeys = Collections.unmodifiableList(params.mShiftKeys); mAltCodeKeysWhileTyping = Collections.unmodifiableList(params.mAltCodeKeysWhileTyping); mIconsSet = params.mIconsSet; @@ -159,7 +158,7 @@ public class Keyboard { /** * Return the sorted list of keys of this keyboard. * The keys are sorted from top-left to bottom-right order. - * The list may contain {@link Spacer} object as well. + * The list may contain {@link Key.Spacer} object as well. * @return the sorted unmodifiable list of {@link Key}s of this keyboard. */ public List<Key> getSortedKeys() { diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java index cde5091c4..aa646994c 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java @@ -41,7 +41,6 @@ import com.android.inputmethod.latin.InputAttributes; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SubtypeSwitcher; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.InputTypeUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import com.android.inputmethod.latin.utils.XmlParseUtils; @@ -81,7 +80,7 @@ public final class KeyboardLayoutSet { // them from disappearing from sKeyboardCache. private static final Keyboard[] sForcibleKeyboardCache = new Keyboard[FORCIBLE_CACHE_SIZE]; private static final HashMap<KeyboardId, SoftReference<Keyboard>> sKeyboardCache = - CollectionUtils.newHashMap(); + new HashMap<>(); private static final KeysCache sKeysCache = new KeysCache(); @SuppressWarnings("serial") @@ -117,7 +116,7 @@ public final class KeyboardLayoutSet { int mKeyboardHeight; // Sparse array of KeyboardLayoutSet element parameters indexed by element's id. final SparseArray<ElementParams> mKeyboardLayoutSetElementIdToParamsMap = - CollectionUtils.newSparseArray(); + new SparseArray<>(); } public static void clearKeyboardCache() { @@ -181,7 +180,7 @@ public final class KeyboardLayoutSet { } final KeyboardBuilder<KeyboardParams> builder = - new KeyboardBuilder<KeyboardParams>(mContext, new KeyboardParams()); + new KeyboardBuilder<>(mContext, new KeyboardParams()); if (id.isAlphabetKeyboard()) { builder.setAutoGenerate(sKeysCache); } @@ -192,7 +191,7 @@ public final class KeyboardLayoutSet { } builder.setProximityCharsCorrectionEnabled(elementParams.mProximityCharsCorrectionEnabled); final Keyboard keyboard = builder.build(); - sKeyboardCache.put(id, new SoftReference<Keyboard>(keyboard)); + sKeyboardCache.put(id, new SoftReference<>(keyboard)); if ((id.mElementId == KeyboardId.ELEMENT_ALPHABET || id.mElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) && !mParams.mIsSpellChecker) { diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index edfc5fded..f90ad7975 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -38,7 +38,6 @@ import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.define.ProductionFlag; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.TypefaceUtils; import com.android.inputmethod.research.ResearchLogger; @@ -110,7 +109,7 @@ public class KeyboardView extends View { /** True if all keys should be drawn */ private boolean mInvalidateAllKeys; /** The keys that should be drawn */ - private final HashSet<Key> mInvalidatedKeys = CollectionUtils.newHashSet(); + private final HashSet<Key> mInvalidatedKeys = new HashSet<>(); /** The working rectangle variable */ private final Rect mWorkingRect = new Rect(); /** The keyboard bitmap buffer for faster updates */ diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index 86036ccc1..f291a7ed0 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -57,7 +57,6 @@ import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.settings.DebugSettings; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CoordinateUtils; import com.android.inputmethod.latin.utils.SpacebarLanguageUtils; import com.android.inputmethod.latin.utils.TypefaceUtils; @@ -150,8 +149,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack private final Paint mBackgroundDimAlphaPaint = new Paint(); private boolean mNeedsToDimEntireKeyboard; private final View mMoreKeysKeyboardContainer; - private final WeakHashMap<Key, Keyboard> mMoreKeysKeyboardCache = - CollectionUtils.newWeakHashMap(); + private final WeakHashMap<Key, Keyboard> mMoreKeysKeyboardCache = new WeakHashMap<>(); private final boolean mConfigShowMoreKeysKeyboardAtTouchedPoint; // More keys panel (used by both more keys keyboard and more suggestions view) // TODO: Consider extending to support multiple more keys panels @@ -765,19 +763,14 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack } /** - * Receives hover events from the input framework. - * - * @param event The motion event to be dispatched. - * @return {@code true} if the event was handled by the view, {@code false} - * otherwise + * {@inheritDoc} */ @Override - public boolean dispatchHoverEvent(final MotionEvent event) { - if (!AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { - // Reflection doesn't support calling superclass methods. - return false; + public boolean onHoverEvent(final MotionEvent event) { + if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { + return mAccessibilityDelegate.onHoverEvent(event); } - return mAccessibilityDelegate.dispatchHoverEvent(event); + return super.onHoverEvent(event); } public void updateShortcutKey(final boolean available) { diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 4777166ea..303886cd3 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -37,7 +37,6 @@ import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.settings.Settings; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CoordinateUtils; import com.android.inputmethod.latin.utils.ResourceUtils; import com.android.inputmethod.research.ResearchLogger; @@ -144,7 +143,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element, // TODO: Device specific parameter would be better for device specific hack? private static final float PHANTOM_SUDDEN_MOVE_THRESHOLD = 0.25f; // in keyWidth - private static final ArrayList<PointerTracker> sTrackers = CollectionUtils.newArrayList(); + private static final ArrayList<PointerTracker> sTrackers = new ArrayList<>(); private static final PointerTrackerQueue sPointerTrackerQueue = new PointerTrackerQueue(); public final int mPointerId; diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java index c89bda40e..c19cd671a 100644 --- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java @@ -22,7 +22,6 @@ import android.util.Log; import com.android.inputmethod.keyboard.internal.TouchPositionCorrection; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.JniUtils; import java.util.ArrayList; @@ -55,6 +54,7 @@ public class ProximityInfo { private final List<Key>[] mGridNeighbors; private final String mLocaleStr; + @SuppressWarnings("unchecked") ProximityInfo(final String localeStr, final int gridWidth, final int gridHeight, final int minWidth, final int height, final int mostCommonKeyWidth, final int mostCommonKeyHeight, final List<Key> sortedKeys, @@ -360,7 +360,7 @@ y |---+---+---+---+-v-+-|-+---+---+---+---+---| | thresholdBase and get for (int i = 0; i < gridSize; ++i) { final int indexStart = i * keyCount; final int indexEnd = indexStart + neighborCountPerCell[i]; - final ArrayList<Key> neighbors = CollectionUtils.newArrayList(indexEnd - indexStart); + final ArrayList<Key> neighbors = new ArrayList<>(indexEnd - indexStart); for (int index = indexStart; index < indexEnd; index++) { neighbors.add(neighborsFlatBuffer[index]); } diff --git a/java/src/com/android/inputmethod/keyboard/emoji/DynamicGridKeyboard.java b/java/src/com/android/inputmethod/keyboard/emoji/DynamicGridKeyboard.java index c7a9025c0..daeb1f928 100644 --- a/java/src/com/android/inputmethod/keyboard/emoji/DynamicGridKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/emoji/DynamicGridKeyboard.java @@ -23,7 +23,6 @@ import android.util.Log; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.latin.settings.Settings; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.JsonUtils; import java.util.ArrayDeque; @@ -47,8 +46,8 @@ final class DynamicGridKeyboard extends Keyboard { private final int mColumnsNum; private final int mMaxKeyCount; private final boolean mIsRecents; - private final ArrayDeque<GridKey> mGridKeys = CollectionUtils.newArrayDeque(); - private final ArrayDeque<Key> mPendingKeys = CollectionUtils.newArrayDeque(); + private final ArrayDeque<GridKey> mGridKeys = new ArrayDeque<>(); + private final ArrayDeque<Key> mPendingKeys = new ArrayDeque<>(); private List<Key> mCachedGridKeys; @@ -131,7 +130,7 @@ final class DynamicGridKeyboard extends Keyboard { } private void saveRecentKeys() { - final ArrayList<Object> keys = CollectionUtils.newArrayList(); + final ArrayList<Object> keys = new ArrayList<>(); for (final Key key : mGridKeys) { if (key.getOutputText() != null) { keys.add(key.getOutputText()); diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategory.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategory.java index 859099110..512d4615d 100644 --- a/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategory.java +++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategory.java @@ -31,7 +31,6 @@ import com.android.inputmethod.keyboard.KeyboardLayoutSet; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.settings.Settings; -import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.ArrayList; import java.util.Collections; @@ -101,12 +100,11 @@ final class EmojiCategory { private final Resources mRes; private final int mMaxPageKeyCount; private final KeyboardLayoutSet mLayoutSet; - private final HashMap<String, Integer> mCategoryNameToIdMap = CollectionUtils.newHashMap(); + private final HashMap<String, Integer> mCategoryNameToIdMap = new HashMap<>(); private final int[] mCategoryTabIconId = new int[sCategoryName.length]; - private final ArrayList<CategoryProperties> mShownCategories = - CollectionUtils.newArrayList(); - private final ConcurrentHashMap<Long, DynamicGridKeyboard> - mCategoryKeyboardMap = new ConcurrentHashMap<Long, DynamicGridKeyboard>(); + private final ArrayList<CategoryProperties> mShownCategories = new ArrayList<>(); + private final ConcurrentHashMap<Long, DynamicGridKeyboard> mCategoryKeyboardMap = + new ConcurrentHashMap<>(); private int mCurrentCategoryId = EmojiCategory.ID_UNSPECIFIED; private int mCurrentCategoryPageId = 0; @@ -257,7 +255,7 @@ final class EmojiCategory { final int temp = sum; sum += properties.mPageCount; if (sum > position) { - return new Pair<Integer, Integer>(properties.mCategoryId, position - temp); + return new Pair<>(properties.mCategoryId, position - temp); } } return null; @@ -343,7 +341,7 @@ final class EmojiCategory { }; private static Key[][] sortKeysIntoPages(final List<Key> inKeys, final int maxPageCount) { - final ArrayList<Key> keys = CollectionUtils.newArrayList(inKeys); + final ArrayList<Key> keys = new ArrayList<>(inKeys); Collections.sort(keys, EMOJI_KEY_COMPARATOR); final int pageCount = (keys.size() - 1) / maxPageCount + 1; final Key[][] retval = new Key[pageCount][maxPageCount]; diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategoryPageIndicatorView.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategoryPageIndicatorView.java index a6b089169..43d62c71a 100644 --- a/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategoryPageIndicatorView.java +++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategoryPageIndicatorView.java @@ -17,14 +17,11 @@ package com.android.inputmethod.keyboard.emoji; import android.content.Context; -import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; -import com.android.inputmethod.latin.R; - public final class EmojiCategoryPageIndicatorView extends View { private static final float BOTTOM_MARGIN_RATIO = 1.0f; private final Paint mPaint = new Paint(); @@ -33,19 +30,17 @@ public final class EmojiCategoryPageIndicatorView extends View { private float mOffset = 0.0f; public EmojiCategoryPageIndicatorView(final Context context, final AttributeSet attrs) { - this(context, attrs, R.attr.emojiCategoryPageIndicatorViewStyle); + this(context, attrs, 0); } public EmojiCategoryPageIndicatorView(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); - final TypedArray indicatorViewAttr = context.obtainStyledAttributes(attrs, - R.styleable.EmojiCategoryPageIndicatorView, defStyle, - R.style.EmojiCategoryPageIndicatorView); - final int indicatorColor = indicatorViewAttr.getColor( - R.styleable.EmojiCategoryPageIndicatorView_emojiCategoryPageIndicatorColor, 0); - indicatorViewAttr.recycle(); - mPaint.setColor(indicatorColor); + } + + public void setColors(final int foregroundColor, final int backgroundColor) { + mPaint.setColor(foregroundColor); + setBackgroundColor(backgroundColor); } public void setCategoryPageId(final int size, final int id, final float offset) { diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java index 48efa17ad..0166802a4 100644 --- a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java @@ -83,13 +83,15 @@ final class EmojiPageKeyboardView extends KeyboardView implements mKeyDetector.setKeyboard(keyboard, 0 /* correctionX */, 0 /* correctionY */); } + /** + * {@inheritDoc} + */ @Override - public boolean dispatchHoverEvent(final MotionEvent event) { - if (!AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { - // Reflection doesn't support calling superclass methods. - return false; + public boolean onHoverEvent(final MotionEvent event) { + if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { + return mAccessibilityDelegate.onHoverEvent(event); } - return mAccessibilityDelegate.dispatchHoverEvent(event); + return super.onHoverEvent(event); } /** @@ -102,7 +104,7 @@ final class EmojiPageKeyboardView extends KeyboardView implements } final Key key = getKey(e); if (key != null && key != mCurrentKey) { - releaseCurrentKey(); + releaseCurrentKey(false /* withKeyRegistering */); } return true; } @@ -119,7 +121,7 @@ final class EmojiPageKeyboardView extends KeyboardView implements return mKeyDetector.detectHitKey(x, y); } - public void releaseCurrentKey() { + public void releaseCurrentKey(final boolean withKeyRegistering) { mHandler.removeCallbacks(mPendingKeyDown); mPendingKeyDown = null; final Key currentKey = mCurrentKey; @@ -128,13 +130,16 @@ final class EmojiPageKeyboardView extends KeyboardView implements } currentKey.onReleased(); invalidateKey(currentKey); + if (withKeyRegistering) { + mListener.onReleaseKey(currentKey); + } mCurrentKey = null; } @Override public boolean onDown(final MotionEvent e) { final Key key = getKey(e); - releaseCurrentKey(); + releaseCurrentKey(false /* withKeyRegistering */); mCurrentKey = key; if (key == null) { return false; @@ -163,7 +168,7 @@ final class EmojiPageKeyboardView extends KeyboardView implements final Key key = getKey(e); final Runnable pendingKeyDown = mPendingKeyDown; final Key currentKey = mCurrentKey; - releaseCurrentKey(); + releaseCurrentKey(false /* withKeyRegistering */); if (key == null) { return false; } @@ -189,14 +194,14 @@ final class EmojiPageKeyboardView extends KeyboardView implements @Override public boolean onScroll(final MotionEvent e1, final MotionEvent e2, final float distanceX, final float distanceY) { - releaseCurrentKey(); + releaseCurrentKey(false /* withKeyRegistering */); return false; } @Override public boolean onFling(final MotionEvent e1, final MotionEvent e2, final float velocityX, final float velocityY) { - releaseCurrentKey(); + releaseCurrentKey(false /* withKeyRegistering */); return false; } diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java index 52a4dde97..68056e0eb 100644 --- a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java +++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java @@ -27,7 +27,6 @@ import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardView; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.utils.CollectionUtils; final class EmojiPalettesAdapter extends PagerAdapter { private static final String TAG = EmojiPalettesAdapter.class.getSimpleName(); @@ -35,8 +34,7 @@ final class EmojiPalettesAdapter extends PagerAdapter { private final EmojiPageKeyboardView.OnKeyEventListener mListener; private final DynamicGridKeyboard mRecentsKeyboard; - private final SparseArray<EmojiPageKeyboardView> mActiveKeyboardViews = - CollectionUtils.newSparseArray(); + private final SparseArray<EmojiPageKeyboardView> mActiveKeyboardViews = new SparseArray<>(); private final EmojiCategory mEmojiCategory; private int mActivePosition = 0; @@ -70,13 +68,18 @@ final class EmojiPalettesAdapter extends PagerAdapter { } public void onPageScrolled() { + releaseCurrentKey(false /* withKeyRegistering */); + } + + public void releaseCurrentKey(final boolean withKeyRegistering) { // Make sure the delayed key-down event (highlight effect and haptic feedback) will be // canceled. final EmojiPageKeyboardView currentKeyboardView = mActiveKeyboardViews.get(mActivePosition); - if (currentKeyboardView != null) { - currentKeyboardView.releaseCurrentKey(); + if (currentKeyboardView == null) { + return; } + currentKeyboardView.releaseCurrentKey(withKeyRegistering); } @Override @@ -92,7 +95,7 @@ final class EmojiPalettesAdapter extends PagerAdapter { } final EmojiPageKeyboardView oldKeyboardView = mActiveKeyboardViews.get(mActivePosition); if (oldKeyboardView != null) { - oldKeyboardView.releaseCurrentKey(); + oldKeyboardView.releaseCurrentKey(false /* withKeyRegistering */); oldKeyboardView.deallocateMemory(); } mActivePosition = position; diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java index 6b9e880b9..f9e25bcc3 100644 --- a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java +++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java @@ -36,6 +36,7 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TabHost; import android.widget.TabHost.OnTabChangeListener; +import android.widget.TabWidget; import android.widget.TextView; import com.android.inputmethod.keyboard.Key; @@ -68,6 +69,11 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange EmojiPageKeyboardView.OnKeyEventListener { private final int mFunctionalKeyBackgroundId; private final int mSpacebarBackgroundId; + private final boolean mCategoryIndicatorEnabled; + private final int mCategoryIndicatorDrawableResId; + private final int mCategoryIndicatorBackgroundResId; + private final int mCategoryPageIndicatorColor; + private final int mCategoryPageIndicatorBackground; private final DeleteKeyOnTouchListener mDeleteKeyOnTouchListener; private EmojiPalettesAdapter mEmojiPalettesAdapter; private final EmojiLayoutParams mEmojiLayoutParams; @@ -114,6 +120,16 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange R.styleable.EmojiPalettesView, defStyle, R.style.EmojiPalettesView); mEmojiCategory = new EmojiCategory(PreferenceManager.getDefaultSharedPreferences(context), res, layoutSet, emojiPalettesViewAttr); + mCategoryIndicatorEnabled = emojiPalettesViewAttr.getBoolean( + R.styleable.EmojiPalettesView_categoryIndicatorEnabled, false); + mCategoryIndicatorDrawableResId = emojiPalettesViewAttr.getResourceId( + R.styleable.EmojiPalettesView_categoryIndicatorDrawable, 0); + mCategoryIndicatorBackgroundResId = emojiPalettesViewAttr.getResourceId( + R.styleable.EmojiPalettesView_categoryIndicatorBackground, 0); + mCategoryPageIndicatorColor = emojiPalettesViewAttr.getColor( + R.styleable.EmojiPalettesView_categoryPageIndicatorColor, 0); + mCategoryPageIndicatorBackground = emojiPalettesViewAttr.getColor( + R.styleable.EmojiPalettesView_categoryPageIndicatorBackground, 0); emojiPalettesViewAttr.recycle(); mDeleteKeyOnTouchListener = new DeleteKeyOnTouchListener(context); } @@ -152,7 +168,15 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange addTab(mTabHost, properties.mCategoryId); } mTabHost.setOnTabChangedListener(this); - mTabHost.getTabWidget().setStripEnabled(true); + final TabWidget tabWidget = mTabHost.getTabWidget(); + tabWidget.setStripEnabled(mCategoryIndicatorEnabled); + if (mCategoryIndicatorEnabled) { + // On TabWidget's strip, what looks like an indicator is actually a background. + // And what looks like a background are actually left and right drawables. + tabWidget.setBackgroundResource(mCategoryIndicatorDrawableResId); + tabWidget.setLeftStripDrawable(mCategoryIndicatorBackgroundResId); + tabWidget.setRightStripDrawable(mCategoryIndicatorBackgroundResId); + } mEmojiPalettesAdapter = new EmojiPalettesAdapter(mEmojiCategory, this); @@ -165,6 +189,8 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange mEmojiCategoryPageIndicatorView = (EmojiCategoryPageIndicatorView)findViewById(R.id.emoji_category_page_id_view); + mEmojiCategoryPageIndicatorView.setColors( + mCategoryPageIndicatorColor, mCategoryPageIndicatorBackground); mEmojiLayoutParams.setCategoryPageIdViewProperties(mEmojiCategoryPageIndicatorView); setCurrentCategoryId(mEmojiCategory.getCurrentCategoryId(), true /* force */); @@ -354,6 +380,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange } public void stopEmojiPalettes() { + mEmojiPalettesAdapter.releaseCurrentKey(true /* withKeyRegistering */); mEmojiPalettesAdapter.flushPendingRecentKeys(); mEmojiPager.setAdapter(null); } diff --git a/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java index fdc2458d4..3b4c43418 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java +++ b/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java @@ -24,7 +24,6 @@ import android.graphics.PorterDuffXfermode; import android.util.AttributeSet; import android.widget.RelativeLayout; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CoordinateUtils; import java.util.ArrayList; @@ -32,7 +31,7 @@ import java.util.ArrayList; public final class DrawingPreviewPlacerView extends RelativeLayout { private final int[] mKeyboardViewOrigin = CoordinateUtils.newInstance(); - private final ArrayList<AbstractDrawingPreview> mPreviews = CollectionUtils.newArrayList(); + private final ArrayList<AbstractDrawingPreview> mPreviews = new ArrayList<>(); public DrawingPreviewPlacerView(final Context context, final AttributeSet attrs) { super(context, attrs); diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java index d8b00c707..72628e38a 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java +++ b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java @@ -29,15 +29,13 @@ import android.util.SparseArray; import android.view.View; import com.android.inputmethod.keyboard.PointerTracker; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper; /** * Draw preview graphics of multiple gesture trails during gesture input. */ public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview { - private final SparseArray<GestureTrailDrawingPoints> mGestureTrails = - CollectionUtils.newSparseArray(); + private final SparseArray<GestureTrailDrawingPoints> mGestureTrails = new SparseArray<>(); private final GestureTrailDrawingParams mDrawingParams; private final Paint mGesturePaint; private int mOffscreenWidth; diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java index 625d1f0a4..605519b02 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java @@ -32,7 +32,6 @@ import android.widget.TextView; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CoordinateUtils; import com.android.inputmethod.latin.utils.ViewLayoutUtils; @@ -48,9 +47,9 @@ import java.util.HashSet; */ public final class KeyPreviewChoreographer { // Free {@link TextView} pool that can be used for key preview. - private final ArrayDeque<TextView> mFreeKeyPreviewTextViews = CollectionUtils.newArrayDeque(); + private final ArrayDeque<TextView> mFreeKeyPreviewTextViews = new ArrayDeque<>(); // Map from {@link Key} to {@link TextView} that is currently being displayed as key preview. - private final HashMap<Key,TextView> mShowingKeyPreviewTextViews = CollectionUtils.newHashMap(); + private final HashMap<Key,TextView> mShowingKeyPreviewTextViews = new HashMap<>(); private final KeyPreviewDrawParams mParams; @@ -83,7 +82,7 @@ public final class KeyPreviewChoreographer { } public void dismissAllKeyPreviews() { - for (final Key key : new HashSet<Key>(mShowingKeyPreviewTextViews.keySet())) { + for (final Key key : new HashSet<>(mShowingKeyPreviewTextViews.keySet())) { dismissKeyPreview(key, false /* withAnimation */); } } diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java index 700c9b07c..0b0e761d2 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java @@ -21,7 +21,6 @@ import android.util.Log; import android.util.SparseArray; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.XmlParseUtils; import org.xmlpull.v1.XmlPullParser; @@ -34,7 +33,7 @@ public final class KeyStylesSet { private static final String TAG = KeyStylesSet.class.getSimpleName(); private static final boolean DEBUG = false; - private final HashMap<String, KeyStyle> mStyles = CollectionUtils.newHashMap(); + private final HashMap<String, KeyStyle> mStyles = new HashMap<>(); private final KeyboardTextsSet mTextsSet; private final KeyStyle mEmptyKeyStyle; @@ -75,7 +74,7 @@ public final class KeyStylesSet { private static final class DeclaredKeyStyle extends KeyStyle { private final HashMap<String, KeyStyle> mStyles; private final String mParentStyleName; - private final SparseArray<Object> mStyleAttributes = CollectionUtils.newSparseArray(); + private final SparseArray<Object> mStyleAttributes = new SparseArray<>(); public DeclaredKeyStyle(final String parentStyleName, final KeyboardTextsSet textsSet, final HashMap<String, KeyStyle> styles) { diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java index 06da5719b..62b69dcc9 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java @@ -17,14 +17,13 @@ package com.android.inputmethod.keyboard.internal; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.HashMap; public final class KeyboardCodesSet { public static final String PREFIX_CODE = "!code/"; - private static final HashMap<String, Integer> sNameToIdMap = CollectionUtils.newHashMap(); + private static final HashMap<String, Integer> sNameToIdMap = new HashMap<>(); private KeyboardCodesSet() { // This utility class is not publicly instantiable. diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java index b5a94807e..916c4e1a7 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java @@ -23,7 +23,6 @@ import android.util.Log; import android.util.SparseIntArray; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.HashMap; @@ -60,7 +59,7 @@ public final class KeyboardIconsSet { private static final SparseIntArray ATTR_ID_TO_ICON_ID = new SparseIntArray(); // Icon name to icon id map. - private static final HashMap<String, Integer> sNameToIdsMap = CollectionUtils.newHashMap(); + private static final HashMap<String, Integer> sNameToIdsMap = new HashMap<>(); private static final Object[] NAMES_AND_ATTR_IDS = { NAME_UNDEFINED, ATTR_UNDEFINED, diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java index a61a79b85..5df9d3ece 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java @@ -21,7 +21,6 @@ import android.util.SparseIntArray; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.ArrayList; import java.util.Comparator; @@ -61,9 +60,9 @@ public class KeyboardParams { public int GRID_HEIGHT; // Keys are sorted from top-left to bottom-right order. - public final SortedSet<Key> mSortedKeys = new TreeSet<Key>(ROW_COLUMN_COMPARATOR); - public final ArrayList<Key> mShiftKeys = CollectionUtils.newArrayList(); - public final ArrayList<Key> mAltCodeKeysWhileTyping = CollectionUtils.newArrayList(); + public final SortedSet<Key> mSortedKeys = new TreeSet<>(ROW_COLUMN_COMPARATOR); + public final ArrayList<Key> mShiftKeys = new ArrayList<>(); + public final ArrayList<Key> mAltCodeKeysWhileTyping = new ArrayList<>(); public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet(); public final KeyboardTextsSet mTextsSet = new KeyboardTextsSet(); public final KeyStylesSet mKeyStyles = new KeyStylesSet(mTextsSet); diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java index 0f9497c27..6db1d02c9 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java @@ -23,7 +23,6 @@ import android.util.Xml; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.ResourceUtils; import org.xmlpull.v1.XmlPullParser; @@ -44,7 +43,7 @@ public final class KeyboardRow { /** The height of this row. */ private final int mRowHeight; - private final ArrayDeque<RowAttributes> mRowAttributesStack = CollectionUtils.newArrayDeque(); + private final ArrayDeque<RowAttributes> mRowAttributesStack = new ArrayDeque<>(); private static class RowAttributes { /** Default width of a key in this row. */ diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java index 0047aa4a1..cd6abeed3 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java @@ -22,7 +22,6 @@ import android.text.TextUtils; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.RunInLocale; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; @@ -38,7 +37,7 @@ public final class KeyboardTextsSet { private String[] mTextsTable; // Resource name to text map. - private HashMap<String, String> mResourceNameToTextsMap = CollectionUtils.newHashMap(); + private HashMap<String, String> mResourceNameToTextsMap = new HashMap<>(); public void setLocale(final Locale locale, final Context context) { mTextsTable = KeyboardTextsTable.getTextsTable(locale); @@ -141,6 +140,7 @@ public final class KeyboardTextsSet { "label_send_key", "label_next_key", "label_done_key", + "label_search_key", "label_previous_key", // Other labels. "label_pause_key", diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java index 7e6181a4e..40c915c8d 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java @@ -16,8 +16,6 @@ package com.android.inputmethod.keyboard.internal; -import com.android.inputmethod.latin.utils.CollectionUtils; - import java.util.HashMap; import java.util.Locale; @@ -44,14 +42,12 @@ import java.util.Locale; */ public final class KeyboardTextsTable { // Name to index map. - private static final HashMap<String, Integer> sNameToIndexesMap = CollectionUtils.newHashMap(); + private static final HashMap<String, Integer> sNameToIndexesMap = new HashMap<>(); // Locale to texts table map. - private static final HashMap<String, String[]> sLocaleToTextsTableMap = - CollectionUtils.newHashMap(); + private static final HashMap<String, String[]> sLocaleToTextsTableMap = new HashMap<>(); // TODO: Remove this variable after debugging. // Texts table to locale maps. - private static final HashMap<String[], String> sTextsTableToLocaleMap = - CollectionUtils.newHashMap(); + private static final HashMap<String[], String> sTextsTableToLocaleMap = new HashMap<>(); public static String getText(final String name, final String[] textsTable) { final Integer indexObj = sNameToIndexesMap.get(name); diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java b/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java index 7c2e3e174..7743d4744 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java @@ -17,12 +17,11 @@ package com.android.inputmethod.keyboard.internal; import com.android.inputmethod.keyboard.Key; -import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.HashMap; public final class KeysCache { - private final HashMap<Key, Key> mMap = CollectionUtils.newHashMap(); + private final HashMap<Key, Key> mMap = new HashMap<>(); public void clear() { mMap.clear(); diff --git a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java index 56ef4767f..e0d5173ac 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java +++ b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java @@ -149,7 +149,7 @@ public final class MoreKeySpec { // Skip empty entry. if (pos - start > 0) { if (list == null) { - list = CollectionUtils.newArrayList(); + list = new ArrayList<>(); } list.add(text.substring(start, pos)); } diff --git a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java index 5ac34188c..8e89e61ea 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java +++ b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java @@ -18,8 +18,6 @@ package com.android.inputmethod.keyboard.internal; import android.util.Log; -import com.android.inputmethod.latin.utils.CollectionUtils; - import java.util.ArrayList; public final class PointerTrackerQueue { @@ -37,7 +35,7 @@ public final class PointerTrackerQueue { // Note: {@link #mExpandableArrayOfActivePointers} and {@link #mArraySize} are synchronized by // {@link #mExpandableArrayOfActivePointers} private final ArrayList<Element> mExpandableArrayOfActivePointers = - CollectionUtils.newArrayList(INITIAL_CAPACITY); + new ArrayList<>(INITIAL_CAPACITY); private int mArraySize = 0; public int size() { diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index e7ab02ac1..fd34b98f4 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -30,7 +30,6 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException; import com.android.inputmethod.latin.makedict.WordProperty; import com.android.inputmethod.latin.settings.NativeSuggestOptions; import com.android.inputmethod.latin.utils.BinaryDictionaryUtils; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.FileUtils; import com.android.inputmethod.latin.utils.JniUtils; import com.android.inputmethod.latin.utils.LanguageModelParam; @@ -104,8 +103,7 @@ public final class BinaryDictionary extends Dictionary { private final NativeSuggestOptions mNativeSuggestOptions = new NativeSuggestOptions(); - private final SparseArray<DicTraverseSession> mDicTraverseSessions = - CollectionUtils.newSparseArray(); + private final SparseArray<DicTraverseSession> mDicTraverseSessions = new SparseArray<>(); // TODO: There should be a way to remove used DicTraverseSession objects from // {@code mDicTraverseSessions}. @@ -185,13 +183,14 @@ public final class BinaryDictionary extends Dictionary { private static native void getHeaderInfoNative(long dict, int[] outHeaderSize, int[] outFormatVersion, ArrayList<int[]> outAttributeKeys, ArrayList<int[]> outAttributeValues); - private static native void flushNative(long dict, String filePath); + private static native boolean flushNative(long dict, String filePath); private static native boolean needsToRunGCNative(long dict, boolean mindsBlockByGC); - private static native void flushWithGCNative(long dict, String filePath); + private static native boolean flushWithGCNative(long dict, String filePath); private static native void closeNative(long dict); private static native int getFormatVersionNative(long dict); private static native int getProbabilityNative(long dict, int[] word); - private static native int getBigramProbabilityNative(long dict, int[] word0, int[] word1); + private static native int getBigramProbabilityNative(long dict, int[] word0, + boolean isBeginningOfSentence, int[] word1); private static native void getWordPropertyNative(long dict, int[] word, int[] outCodePoints, boolean[] outFlags, int[] outProbabilityInfo, ArrayList<int[]> outBigramTargets, ArrayList<int[]> outBigramProbabilityInfo, @@ -200,15 +199,17 @@ public final class BinaryDictionary extends Dictionary { private static native void getSuggestionsNative(long dict, long proximityInfo, long traverseSession, int[] xCoordinates, int[] yCoordinates, int[] times, int[] pointerIds, int[] inputCodePoints, int inputSize, int[] suggestOptions, - int[] prevWordCodePointArray, int[] outputSuggestionCount, int[] outputCodePoints, - int[] outputScores, int[] outputIndices, int[] outputTypes, - int[] outputAutoCommitFirstWordConfidence, float[] inOutLanguageWeight); - private static native void addUnigramWordNative(long dict, int[] word, int probability, - int[] shortcutTarget, int shortcutProbability, boolean isNotAWord, - boolean isBlacklisted, int timestamp); - private static native void addBigramWordsNative(long dict, int[] word0, int[] word1, - int probability, int timestamp); - private static native void removeBigramWordsNative(long dict, int[] word0, int[] word1); + int[] prevWordCodePointArray, boolean isBeginningOfSentence, + int[] outputSuggestionCount, int[] outputCodePoints, int[] outputScores, + int[] outputIndices, int[] outputTypes, int[] outputAutoCommitFirstWordConfidence, + float[] inOutLanguageWeight); + private static native boolean addUnigramWordNative(long dict, int[] word, int probability, + int[] shortcutTarget, int shortcutProbability, boolean isBeginningOfSentence, + boolean isNotAWord, boolean isBlacklisted, int timestamp); + private static native boolean addBigramWordsNative(long dict, int[] word0, + boolean isBeginningOfSentence, int[] word1, int probability, int timestamp); + private static native boolean removeBigramWordsNative(long dict, int[] word0, + boolean isBeginningOfSentence, int[] word1); private static native int addMultipleDictionaryEntriesNative(long dict, LanguageModelParam[] languageModelParams, int startIndex); private static native String getPropertyNative(long dict, String query); @@ -245,11 +246,11 @@ public final class BinaryDictionary extends Dictionary { } final int[] outHeaderSize = new int[1]; final int[] outFormatVersion = new int[1]; - final ArrayList<int[]> outAttributeKeys = CollectionUtils.newArrayList(); - final ArrayList<int[]> outAttributeValues = CollectionUtils.newArrayList(); + final ArrayList<int[]> outAttributeKeys = new ArrayList<>(); + final ArrayList<int[]> outAttributeValues = new ArrayList<>(); getHeaderInfoNative(mNativeDict, outHeaderSize, outFormatVersion, outAttributeKeys, outAttributeValues); - final HashMap<String, String> attributes = new HashMap<String, String>(); + final HashMap<String, String> attributes = new HashMap<>(); for (int i = 0; i < outAttributeKeys.size(); i++) { final String attributeKey = StringUtils.getStringFromNullTerminatedCodePointArray( outAttributeKeys.get(i)); @@ -301,14 +302,15 @@ public final class BinaryDictionary extends Dictionary { getTraverseSession(sessionId).getSession(), inputPointers.getXCoordinates(), inputPointers.getYCoordinates(), inputPointers.getTimes(), inputPointers.getPointerIds(), mInputCodePoints, inputSize, - mNativeSuggestOptions.getOptions(), prevWordCodePointArray, mOutputSuggestionCount, + mNativeSuggestOptions.getOptions(), prevWordCodePointArray, + prevWordsInfo.mIsBeginningOfSentence, mOutputSuggestionCount, mOutputCodePoints, mOutputScores, mSpaceIndices, mOutputTypes, mOutputAutoCommitFirstWordConfidence, mInputOutputLanguageWeight); if (inOutLanguageWeight != null) { inOutLanguageWeight[0] = mInputOutputLanguageWeight[0]; } final int count = mOutputSuggestionCount[0]; - final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList(); + final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<>(); for (int j = 0; j < count; ++j) { final int start = j * MAX_WORD_LENGTH; int len = 0; @@ -324,13 +326,8 @@ public final class BinaryDictionary extends Dictionary { // offensive, then we don't output it unless it's also an exact match. continue; } - final int kind = mOutputTypes[j] & SuggestedWordInfo.KIND_MASK_KIND; - final int score = SuggestedWordInfo.KIND_WHITELIST == kind - ? SuggestedWordInfo.MAX_SCORE : mOutputScores[j]; - // TODO: check that all users of the `kind' parameter are ready to accept - // flags too and pass mOutputTypes[j] instead of kind suggestions.add(new SuggestedWordInfo(new String(mOutputCodePoints, start, len), - score, kind, this /* sourceDict */, + mOutputScores[j], mOutputTypes[j], this /* sourceDict */, mSpaceIndices[j] /* indexOfTouchPointOfSecondWord */, mOutputAutoCommitFirstWordConfidence[0])); } @@ -364,12 +361,13 @@ public final class BinaryDictionary extends Dictionary { } public int getNgramProbability(final PrevWordsInfo prevWordsInfo, final String word) { - if (TextUtils.isEmpty(prevWordsInfo.mPrevWord) || TextUtils.isEmpty(word)) { + if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) { return NOT_A_PROBABILITY; } final int[] codePoints0 = StringUtils.toCodePointArray(prevWordsInfo.mPrevWord); final int[] codePoints1 = StringUtils.toCodePointArray(word); - return getBigramProbabilityNative(mNativeDict, codePoints0, codePoints1); + return getBigramProbabilityNative(mNativeDict, codePoints0, + prevWordsInfo.mIsBeginningOfSentence, codePoints1); } public WordProperty getWordProperty(final String word) { @@ -381,10 +379,10 @@ public final class BinaryDictionary extends Dictionary { final boolean[] outFlags = new boolean[FORMAT_WORD_PROPERTY_OUTPUT_FLAG_COUNT]; final int[] outProbabilityInfo = new int[FORMAT_WORD_PROPERTY_OUTPUT_PROBABILITY_INFO_COUNT]; - final ArrayList<int[]> outBigramTargets = CollectionUtils.newArrayList(); - final ArrayList<int[]> outBigramProbabilityInfo = CollectionUtils.newArrayList(); - final ArrayList<int[]> outShortcutTargets = CollectionUtils.newArrayList(); - final ArrayList<Integer> outShortcutProbabilities = CollectionUtils.newArrayList(); + final ArrayList<int[]> outBigramTargets = new ArrayList<>(); + final ArrayList<int[]> outBigramProbabilityInfo = new ArrayList<>(); + final ArrayList<int[]> outShortcutTargets = new ArrayList<>(); + final ArrayList<Integer> outShortcutProbabilities = new ArrayList<>(); getWordPropertyNative(mNativeDict, codePoints, outCodePoints, outFlags, outProbabilityInfo, outBigramTargets, outBigramProbabilityInfo, outShortcutTargets, outShortcutProbabilities); @@ -419,42 +417,53 @@ public final class BinaryDictionary extends Dictionary { } // Add a unigram entry to binary dictionary with unigram attributes in native code. - public void addUnigramEntry(final String word, final int probability, - final String shortcutTarget, final int shortcutProbability, final boolean isNotAWord, + public boolean addUnigramEntry(final String word, final int probability, + final String shortcutTarget, final int shortcutProbability, + final boolean isBeginningOfSentence, final boolean isNotAWord, final boolean isBlacklisted, final int timestamp) { - if (TextUtils.isEmpty(word)) { - return; + if (word == null || (word.isEmpty() && !isBeginningOfSentence)) { + return false; } final int[] codePoints = StringUtils.toCodePointArray(word); final int[] shortcutTargetCodePoints = (shortcutTarget != null) ? StringUtils.toCodePointArray(shortcutTarget) : null; - addUnigramWordNative(mNativeDict, codePoints, probability, shortcutTargetCodePoints, - shortcutProbability, isNotAWord, isBlacklisted, timestamp); + if (!addUnigramWordNative(mNativeDict, codePoints, probability, shortcutTargetCodePoints, + shortcutProbability, isBeginningOfSentence, isNotAWord, isBlacklisted, timestamp)) { + return false; + } mHasUpdated = true; + return true; } // Add an n-gram entry to the binary dictionary with timestamp in native code. - public void addNgramEntry(final PrevWordsInfo prevWordsInfo, final String word, - final int probability, - final int timestamp) { - if (TextUtils.isEmpty(prevWordsInfo.mPrevWord) || TextUtils.isEmpty(word)) { - return; + public boolean addNgramEntry(final PrevWordsInfo prevWordsInfo, final String word, + final int probability, final int timestamp) { + if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) { + return false; } final int[] codePoints0 = StringUtils.toCodePointArray(prevWordsInfo.mPrevWord); final int[] codePoints1 = StringUtils.toCodePointArray(word); - addBigramWordsNative(mNativeDict, codePoints0, codePoints1, probability, timestamp); + if (!addBigramWordsNative(mNativeDict, codePoints0, prevWordsInfo.mIsBeginningOfSentence, + codePoints1, probability, timestamp)) { + return false; + } mHasUpdated = true; + return true; } // Remove an n-gram entry from the binary dictionary in native code. - public void removeNgramEntry(final PrevWordsInfo prevWordsInfo, final String word) { - if (TextUtils.isEmpty(prevWordsInfo.mPrevWord) || TextUtils.isEmpty(word)) { - return; + public boolean removeNgramEntry(final PrevWordsInfo prevWordsInfo, final String word) { + if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) { + return false; } final int[] codePoints0 = StringUtils.toCodePointArray(prevWordsInfo.mPrevWord); final int[] codePoints1 = StringUtils.toCodePointArray(word); - removeBigramWordsNative(mNativeDict, codePoints0, codePoints1); + if (!removeBigramWordsNative(mNativeDict, codePoints0, prevWordsInfo.mIsBeginningOfSentence, + codePoints1)) { + return false; + } mHasUpdated = true; + return true; } public void addMultipleDictionaryEntries(final LanguageModelParam[] languageModelParams) { @@ -484,26 +493,33 @@ public final class BinaryDictionary extends Dictionary { } // Flush to dict file if the dictionary has been updated. - public void flush() { - if (!isValidDictionary()) return; + public boolean flush() { + if (!isValidDictionary()) return false; if (mHasUpdated) { - flushNative(mNativeDict, mDictFilePath); + if (!flushNative(mNativeDict, mDictFilePath)) { + return false; + } reopen(); } + return true; } // Run GC and flush to dict file if the dictionary has been updated. - public void flushWithGCIfHasUpdated() { + public boolean flushWithGCIfHasUpdated() { if (mHasUpdated) { - flushWithGC(); + return flushWithGC(); } + return true; } // Run GC and flush to dict file. - public void flushWithGC() { - if (!isValidDictionary()) return; - flushWithGCNative(mNativeDict, mDictFilePath); + public boolean flushWithGC() { + if (!isValidDictionary()) return false; + if (!flushWithGCNative(mNativeDict, mDictFilePath)) { + return false; + } reopen(); + return true; } /** diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java index 72757e086..10b1f1b77 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java @@ -29,7 +29,6 @@ import android.util.Log; import com.android.inputmethod.dictionarypack.DictionaryPackConstants; import com.android.inputmethod.dictionarypack.MD5Calculator; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.DictionaryInfoUtils; import com.android.inputmethod.latin.utils.DictionaryInfoUtils.DictionaryInfo; import com.android.inputmethod.latin.utils.FileTransforms; @@ -44,8 +43,8 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.util.Arrays; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -165,7 +164,7 @@ public final class BinaryDictionaryFileDumper { if (cursor.getCount() <= 0 || !cursor.moveToFirst()) { return Collections.<WordListInfo>emptyList(); } - final ArrayList<WordListInfo> list = CollectionUtils.newArrayList(); + final ArrayList<WordListInfo> list = new ArrayList<>(); do { final String wordListId = cursor.getString(0); final String wordListLocale = cursor.getString(1); diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java index 4c49cb31c..867c18686 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java @@ -24,7 +24,6 @@ import android.util.Log; import com.android.inputmethod.latin.makedict.DictionaryHeader; import com.android.inputmethod.latin.makedict.UnsupportedFormatException; import com.android.inputmethod.latin.utils.BinaryDictionaryUtils; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.DictionaryInfoUtils; import com.android.inputmethod.latin.utils.LocaleUtils; @@ -160,7 +159,7 @@ final public class BinaryDictionaryGetter { public static File[] getCachedWordLists(final String locale, final Context context) { final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context); if (null == directoryList) return EMPTY_FILE_ARRAY; - final HashMap<String, FileAndMatchLevel> cacheFiles = CollectionUtils.newHashMap(); + final HashMap<String, FileAndMatchLevel> cacheFiles = new HashMap<>(); for (File directory : directoryList) { if (!directory.isDirectory()) continue; final String dirLocale = @@ -273,7 +272,7 @@ final public class BinaryDictionaryGetter { final DictPackSettings dictPackSettings = new DictPackSettings(context); boolean foundMainDict = false; - final ArrayList<AssetFileAddress> fileList = CollectionUtils.newArrayList(); + final ArrayList<AssetFileAddress> fileList = new ArrayList<>(); // cachedWordLists may not be null, see doc for getCachedDictionaryList for (final File f : cachedWordLists) { final String wordListId = DictionaryInfoUtils.getWordListIdFromFileName(f.getName()); diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java index 67ca59540..efc5a618b 100644 --- a/java/src/com/android/inputmethod/latin/Constants.java +++ b/java/src/com/android/inputmethod/latin/Constants.java @@ -192,7 +192,6 @@ public final class Constants { public static final int CODE_SPACE = ' '; public static final int CODE_PERIOD = '.'; public static final int CODE_COMMA = ','; - public static final int CODE_ARMENIAN_PERIOD = 0x0589; public static final int CODE_DASH = '-'; public static final int CODE_SINGLE_QUOTE = '\''; public static final int CODE_DOUBLE_QUOTE = '"'; @@ -208,6 +207,8 @@ public final class Constants { public static final int CODE_CLOSING_SQUARE_BRACKET = ']'; public static final int CODE_CLOSING_CURLY_BRACKET = '}'; public static final int CODE_CLOSING_ANGLE_BRACKET = '>'; + public static final int CODE_INVERTED_QUESTION_MARK = 0xBF; // ¿ + public static final int CODE_INVERTED_EXCLAMATION_MARK = 0xA1; // ¡ /** * Special keys code. Must be negative. diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java index 3fb76b142..dd5b376a1 100644 --- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java @@ -31,7 +31,6 @@ import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.personalization.AccountUtils; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.ExecutorUtils; import com.android.inputmethod.latin.utils.StringUtils; @@ -180,7 +179,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { private void addWordsLocked(final Cursor cursor) { int count = 0; - final ArrayList<String> names = CollectionUtils.newArrayList(); + final ArrayList<String> names = new ArrayList<>(); while (!cursor.isAfterLast() && count < MAX_CONTACT_COUNT) { String name = cursor.getString(INDEX_NAME); if (isValidName(name)) { @@ -224,7 +223,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { */ private void addNameLocked(final String name) { int len = StringUtils.codePointCount(name); - PrevWordsInfo prevWordsInfo = new PrevWordsInfo(null); + PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; // TODO: Better tokenization for non-Latin writing systems for (int i = 0; i < len; i++) { if (Character.isLetter(name.codePointAt(i))) { @@ -298,7 +297,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { if (null == cursor) { return false; } - final ArrayList<String> names = CollectionUtils.newArrayList(); + final ArrayList<String> names = new ArrayList<>(); try { if (cursor.moveToFirst()) { while (!cursor.isAfterLast()) { diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java index e6e4e0938..53be28139 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java +++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java @@ -20,7 +20,6 @@ import android.util.Log; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; -import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.ArrayList; import java.util.Collection; @@ -36,22 +35,22 @@ public final class DictionaryCollection extends Dictionary { public DictionaryCollection(final String dictType) { super(dictType); - mDictionaries = CollectionUtils.newCopyOnWriteArrayList(); + mDictionaries = new CopyOnWriteArrayList<>(); } public DictionaryCollection(final String dictType, final Dictionary... dictionaries) { super(dictType); if (null == dictionaries) { - mDictionaries = CollectionUtils.newCopyOnWriteArrayList(); + mDictionaries = new CopyOnWriteArrayList<>(); } else { - mDictionaries = CollectionUtils.newCopyOnWriteArrayList(dictionaries); + mDictionaries = new CopyOnWriteArrayList<>(dictionaries); mDictionaries.removeAll(Collections.singleton(null)); } } public DictionaryCollection(final String dictType, final Collection<Dictionary> dictionaries) { super(dictType); - mDictionaries = CollectionUtils.newCopyOnWriteArrayList(dictionaries); + mDictionaries = new CopyOnWriteArrayList<>(dictionaries); mDictionaries.removeAll(Collections.singleton(null)); } @@ -67,7 +66,7 @@ public final class DictionaryCollection extends Dictionary { ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getSuggestions(composer, prevWordsInfo, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, sessionId, inOutLanguageWeight); - if (null == suggestions) suggestions = CollectionUtils.newArrayList(); + if (null == suggestions) suggestions = new ArrayList<>(); final int length = dictionaries.size(); for (int i = 1; i < length; ++ i) { final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getSuggestions(composer, diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java index 301b832b6..7fa3d0479 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java @@ -19,14 +19,17 @@ package com.android.inputmethod.latin; import android.content.Context; import android.text.TextUtils; import android.util.Log; +import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.personalization.ContextualDictionary; +import com.android.inputmethod.latin.personalization.PersonalizationDataChunk; import com.android.inputmethod.latin.personalization.PersonalizationDictionary; import com.android.inputmethod.latin.personalization.UserHistoryDictionary; -import com.android.inputmethod.latin.utils.CollectionUtils; +import com.android.inputmethod.latin.settings.SpacingAndPunctuations; +import com.android.inputmethod.latin.utils.DistracterFilter; import com.android.inputmethod.latin.utils.ExecutorUtils; import com.android.inputmethod.latin.utils.LanguageModelParam; import com.android.inputmethod.latin.utils.SuggestionResults; @@ -37,16 +40,17 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; // TODO: Consolidate dictionaries in native code. -public class DictionaryFacilitatorForSuggest { - public static final String TAG = DictionaryFacilitatorForSuggest.class.getSimpleName(); +public class DictionaryFacilitator { + public static final String TAG = DictionaryFacilitator.class.getSimpleName(); // HACK: This threshold is being used when adding a capitalized entry in the User History // dictionary. @@ -57,6 +61,7 @@ public class DictionaryFacilitatorForSuggest { private volatile CountDownLatch mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0); // To synchronize assigning mDictionaries to ensure closing dictionaries. private final Object mLock = new Object(); + private final DistracterFilter mDistracterFilter; private static final String[] DICT_TYPES_ORDERED_TO_GET_SUGGESTION = new String[] { @@ -69,7 +74,7 @@ public class DictionaryFacilitatorForSuggest { }; private static final Map<String, Class<? extends ExpandableBinaryDictionary>> - DICT_TYPE_TO_CLASS = CollectionUtils.newHashMap(); + DICT_TYPE_TO_CLASS = new HashMap<>(); static { DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_USER_HISTORY, UserHistoryDictionary.class); @@ -94,7 +99,7 @@ public class DictionaryFacilitatorForSuggest { public final Locale mLocale; private Dictionary mMainDict; public final ConcurrentHashMap<String, ExpandableBinaryDictionary> mSubDictMap = - CollectionUtils.newConcurrentHashMap(); + new ConcurrentHashMap<>(); public Dictionaries() { mLocale = null; @@ -162,7 +167,17 @@ public class DictionaryFacilitatorForSuggest { public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable); } - public DictionaryFacilitatorForSuggest() {} + public DictionaryFacilitator() { + mDistracterFilter = DistracterFilter.EMPTY_DISTRACTER_FILTER; + } + + public DictionaryFacilitator(final DistracterFilter distracterFilter) { + mDistracterFilter = distracterFilter; + } + + public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes) { + mDistracterFilter.updateEnabledSubtypes(enabledSubtypes); + } public Locale getLocale() { return mDictionaries.mLocale; @@ -196,7 +211,7 @@ public class DictionaryFacilitatorForSuggest { // We always try to have the main dictionary. Other dictionaries can be unused. final boolean reloadMainDictionary = localeHasBeenChanged || forceReloadMainDictionary; // TODO: Make subDictTypesToUse configurable by resource or a static final list. - final Set<String> subDictTypesToUse = CollectionUtils.newHashSet(); + final HashSet<String> subDictTypesToUse = new HashSet<>(); if (useContactsDict) { subDictTypesToUse.add(Dictionary.TYPE_CONTACTS); } @@ -215,7 +230,7 @@ public class DictionaryFacilitatorForSuggest { newMainDict = mDictionaries.getDict(Dictionary.TYPE_MAIN); } - final Map<String, ExpandableBinaryDictionary> subDicts = CollectionUtils.newHashMap(); + final Map<String, ExpandableBinaryDictionary> subDicts = new HashMap<>(); for (final String dictType : SUB_DICT_TYPES) { if (!subDictTypesToUse.contains(dictType)) { // This dictionary will not be used. @@ -288,7 +303,7 @@ public class DictionaryFacilitatorForSuggest { final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles, final Map<String, Map<String, String>> additionalDictAttributes) { Dictionary mainDictionary = null; - final Map<String, ExpandableBinaryDictionary> subDicts = CollectionUtils.newHashMap(); + final Map<String, ExpandableBinaryDictionary> subDicts = new HashMap<>(); for (final String dictType : dictionaryTypes) { if (dictType.equals(Dictionary.TYPE_MAIN)) { @@ -321,6 +336,7 @@ public class DictionaryFacilitatorForSuggest { for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTION) { dictionaries.closeDict(dictType); } + mDistracterFilter.close(); } // The main dictionary could have been loaded asynchronously. Don't cache the return value @@ -392,7 +408,7 @@ public class DictionaryFacilitatorForSuggest { if (userHistoryDictionary == null) { return; } - final int maxFreq = getMaxFrequency(word); + final int maxFreq = getFrequency(word); if (maxFreq == 0 && blockPotentiallyOffensive) { return; } @@ -432,7 +448,7 @@ public class DictionaryFacilitatorForSuggest { // We don't add words with 0-frequency (assuming they would be profanity etc.). final boolean isValid = maxFreq > 0; UserHistoryDictionary.addToDictionary(userHistoryDictionary, prevWordsInfo, secondWord, - isValid, timeStampInSeconds); + isValid, timeStampInSeconds, mDistracterFilter); } public void cancelAddingUserHistory(final PrevWordsInfo prevWordsInfo, @@ -500,7 +516,7 @@ public class DictionaryFacilitatorForSuggest { return false; } - private int getMaxFrequency(final String word) { + public int getFrequency(final String word) { if (TextUtils.isEmpty(word)) { return Dictionary.NOT_A_PROBABILITY; } @@ -537,9 +553,16 @@ public class DictionaryFacilitatorForSuggest { personalizationDict.clear(); } - public void addMultipleDictionaryEntriesToPersonalizationDictionary( - final ArrayList<LanguageModelParam> languageModelParams, + public void addEntriesToPersonalizationDictionary( + final PersonalizationDataChunk personalizationDataChunk, + final SpacingAndPunctuations spacingAndPunctuations, final ExpandableBinaryDictionary.AddMultipleDictionaryEntriesCallback callback) { + final ArrayList<LanguageModelParam> languageModelParams = + LanguageModelParam.createLanguageModelParamsFrom( + personalizationDataChunk.mTokens, + personalizationDataChunk.mTimestampInSeconds, + this /* dictionaryFacilitator */, spacingAndPunctuations, + mDistracterFilter); final ExpandableBinaryDictionary personalizationDict = mDictionaries.getSubDict(Dictionary.TYPE_PERSONALIZATION); if (personalizationDict == null || languageModelParams == null diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java index e09c309ea..59de4f82a 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -23,7 +23,6 @@ import android.content.res.Resources; import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.DictionaryInfoUtils; import java.io.File; @@ -55,7 +54,7 @@ public final class DictionaryFactory { createReadOnlyBinaryDictionary(context, locale)); } - final LinkedList<Dictionary> dictList = CollectionUtils.newLinkedList(); + final LinkedList<Dictionary> dictList = new LinkedList<>(); final ArrayList<AssetFileAddress> assetFileList = BinaryDictionaryGetter.getDictionaryFiles(locale, context); if (null != assetFileList) { diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index d67253c3b..b10bae01a 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -27,6 +27,7 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException; import com.android.inputmethod.latin.makedict.WordProperty; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.utils.CombinedFormatUtils; +import com.android.inputmethod.latin.utils.DistracterFilter; import com.android.inputmethod.latin.utils.ExecutorUtils; import com.android.inputmethod.latin.utils.FileUtils; import com.android.inputmethod.latin.utils.LanguageModelParam; @@ -53,7 +54,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { private static final String TAG = ExpandableBinaryDictionary.class.getSimpleName(); /** Whether to print debug output to log */ - private static boolean DEBUG = false; private static final boolean DBG_STRESS_TEST = false; private static final int TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS = 100; @@ -114,7 +114,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { private boolean needsToMigrateDictionary(final int formatVersion) { // When we bump up the dictionary format version, the old version should be added to here // for supporting migration. Note that native code has to support reading such formats. - return formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING; + return formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING + || formatVersion == FormatSpec.VERSION401; } public boolean isValidDictionaryLocked() { @@ -191,7 +192,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } protected Map<String, String> getHeaderAttributeMap() { - HashMap<String, String> attributeMap = new HashMap<String, String>(); + HashMap<String, String> attributeMap = new HashMap<>(); if (mAdditionalAttributeMap != null) { attributeMap.putAll(mAdditionalAttributeMap); } @@ -271,9 +272,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** * Adds unigram information of a word to the dictionary. May overwrite an existing entry. */ - public void addUnigramEntry(final String word, final int frequency, + public void addUnigramEntryWithCheckingDistracter(final String word, final int frequency, final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord, - final boolean isBlacklisted, final int timestamp) { + final boolean isBlacklisted, final int timestamp, + final DistracterFilter distracterFilter) { reloadDictionaryIfRequired(); asyncExecuteTaskWithWriteLock(new Runnable() { @Override @@ -281,6 +283,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { if (mBinaryDictionary == null) { return; } + if (distracterFilter.isDistracterToWordsInDictionaries( + PrevWordsInfo.EMPTY_PREV_WORDS_INFO, word, mLocale)) { + // The word is a distracter. + return; + } runGCIfRequiredLocked(true /* mindsBlockByGC */); addUnigramLocked(word, frequency, shortcutTarget, shortcutFreq, isNotAWord, isBlacklisted, timestamp); @@ -291,8 +298,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { protected void addUnigramLocked(final String word, final int frequency, final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord, final boolean isBlacklisted, final int timestamp) { - mBinaryDictionary.addUnigramEntry(word, frequency, shortcutTarget, shortcutFreq, - isNotAWord, isBlacklisted, timestamp); + if (!mBinaryDictionary.addUnigramEntry(word, frequency, shortcutTarget, shortcutFreq, + false /* isBeginningOfSentence */, isNotAWord, isBlacklisted, timestamp)) { + Log.e(TAG, "Cannot add unigram entry. word: " + word); + } } /** @@ -315,7 +324,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { protected void addNgramEntryLocked(final PrevWordsInfo prevWordsInfo, final String word, final int frequency, final int timestamp) { - mBinaryDictionary.addNgramEntry(prevWordsInfo, word, frequency, timestamp); + if (!mBinaryDictionary.addNgramEntry(prevWordsInfo, word, frequency, timestamp)) { + Log.e(TAG, "Cannot add n-gram entry."); + Log.e(TAG, " PrevWordsInfo: " + prevWordsInfo); + Log.e(TAG, " word: " + word); + } } /** diff --git a/java/src/com/android/inputmethod/latin/InputAttributes.java b/java/src/com/android/inputmethod/latin/InputAttributes.java index df4948322..e778a14f6 100644 --- a/java/src/com/android/inputmethod/latin/InputAttributes.java +++ b/java/src/com/android/inputmethod/latin/InputAttributes.java @@ -20,7 +20,6 @@ import android.text.InputType; import android.util.Log; import android.view.inputmethod.EditorInfo; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.InputTypeUtils; import com.android.inputmethod.latin.utils.StringUtils; @@ -214,7 +213,7 @@ public final class InputAttributes { } private static String toFlagsString(final int flags) { - final ArrayList<String> flagsArray = CollectionUtils.newArrayList(); + final ArrayList<String> flagsArray = new ArrayList<>(); if (0 != (flags & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS)) flagsArray.add("TYPE_TEXT_FLAG_NO_SUGGESTIONS"); if (0 != (flags & InputType.TYPE_TEXT_FLAG_MULTI_LINE)) diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java index 9caec3e01..8cbf8379b 100644 --- a/java/src/com/android/inputmethod/latin/LastComposedWord.java +++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java @@ -69,7 +69,7 @@ public final class LastComposedWord { mInputPointers.copy(inputPointers); } mTypedWord = typedWord; - mEvents = new ArrayList<Event>(events); + mEvents = new ArrayList<>(events); mCommittedWord = committedWord; mSeparatorString = separatorString; mActive = true; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index ab7e66a09..aeae6aab4 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -83,7 +83,7 @@ import com.android.inputmethod.latin.utils.ApplicationUtils; import com.android.inputmethod.latin.utils.CapsModeUtils; import com.android.inputmethod.latin.utils.CoordinateUtils; import com.android.inputmethod.latin.utils.DialogUtils; -import com.android.inputmethod.latin.utils.DistracterFilter; +import com.android.inputmethod.latin.utils.DistracterFilterUsingSuggestion; import com.android.inputmethod.latin.utils.ImportantNoticeUtils; import com.android.inputmethod.latin.utils.IntentUtils; import com.android.inputmethod.latin.utils.JniUtils; @@ -95,6 +95,7 @@ import com.android.inputmethod.research.ResearchLogger; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.List; import java.util.Locale; import java.util.concurrent.TimeUnit; @@ -103,7 +104,7 @@ import java.util.concurrent.TimeUnit; */ public class LatinIME extends InputMethodService implements KeyboardActionListener, SuggestionStripView.Listener, SuggestionStripViewAccessor, - DictionaryFacilitatorForSuggest.DictionaryInitializationListener, + DictionaryFacilitator.DictionaryInitializationListener, ImportantNoticeDialog.ImportantNoticeDialogListener { private static final String TAG = LatinIME.class.getSimpleName(); private static final boolean TRACE = false; @@ -122,12 +123,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private static final String SCHEME_PACKAGE = "package"; private final Settings mSettings; + private final DictionaryFacilitator mDictionaryFacilitator = + new DictionaryFacilitator(new DistracterFilterUsingSuggestion(this /* context */)); private final InputLogic mInputLogic = new InputLogic(this /* LatinIME */, - this /* SuggestionStripViewAccessor */); + this /* SuggestionStripViewAccessor */, mDictionaryFacilitator); // We expect to have only one decoder in almost all cases, hence the default capacity of 1. // If it turns out we need several, it will get grown seamlessly. - final SparseArray<HardwareEventDecoder> mHardwareEventDecoders - = new SparseArray<HardwareEventDecoder>(1); + final SparseArray<HardwareEventDecoder> mHardwareEventDecoders = new SparseArray<>(1); private View mExtractArea; private View mKeyPreviewBackingView; @@ -256,7 +258,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (latinIme == null) { return; } - if (!latinIme.mSettings.getCurrent().isSuggestionStripVisible()) { + if (!latinIme.mSettings.getCurrent() + .isCurrentOrientationAllowingSuggestionsPerUserSettings()) { return; } removeMessages(MSG_RESUME_SUGGESTIONS); @@ -493,8 +496,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { ResearchLogger.getInstance().init(this, mKeyboardSwitcher); - ResearchLogger.getInstance().initDictionary( - mInputLogic.mSuggest.mDictionaryFacilitator); + ResearchLogger.getInstance().initDictionary(mDictionaryFacilitator); } // Register to receive ringer mode change and network state change. @@ -538,13 +540,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (!mHandler.hasPendingReopenDictionaries()) { resetSuggestForLocale(locale); } + mDictionaryFacilitator.updateEnabledSubtypes(mRichImm.getMyEnabledInputMethodSubtypeList( + true /* allowsImplicitlySelectedSubtypes */)); refreshPersonalizationDictionarySession(); StatsUtils.onLoadSettings(currentSettingsValues); } private void refreshPersonalizationDictionarySession() { - final DictionaryFacilitatorForSuggest dictionaryFacilitator = - mInputLogic.mSuggest.mDictionaryFacilitator; final boolean shouldKeepUserHistoryDictionaries; final boolean shouldKeepPersonalizationDictionaries; if (mSettings.getCurrent().mUsePersonalizedDicts) { @@ -559,16 +561,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (!shouldKeepUserHistoryDictionaries) { // Remove user history dictionaries. PersonalizationHelper.removeAllUserHistoryDictionaries(this); - dictionaryFacilitator.clearUserHistoryDictionary(); + mDictionaryFacilitator.clearUserHistoryDictionary(); } if (!shouldKeepPersonalizationDictionaries) { // Remove personalization dictionaries. PersonalizationHelper.removeAllPersonalizationDictionaries(this); PersonalizationDictionarySessionRegistrar.resetAll(this); } else { - final DistracterFilter distracterFilter = createDistracterFilter(); - PersonalizationDictionarySessionRegistrar.init( - this, dictionaryFacilitator, distracterFilter); + PersonalizationDictionarySessionRegistrar.init(this, mDictionaryFacilitator); } } @@ -606,10 +606,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen * @param locale the locale */ private void resetSuggestForLocale(final Locale locale) { - final DictionaryFacilitatorForSuggest dictionaryFacilitator = - mInputLogic.mSuggest.mDictionaryFacilitator; final SettingsValues settingsValues = mSettings.getCurrent(); - dictionaryFacilitator.resetDictionaries(this /* context */, locale, + mDictionaryFacilitator.resetDictionaries(this /* context */, locale, settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts, false /* forceReloadMainDictionary */, this); if (settingsValues.mCorrectionEnabled) { @@ -622,17 +620,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen * Reset suggest by loading the main dictionary of the current locale. */ /* package private */ void resetSuggestMainDict() { - final DictionaryFacilitatorForSuggest dictionaryFacilitator = - mInputLogic.mSuggest.mDictionaryFacilitator; final SettingsValues settingsValues = mSettings.getCurrent(); - dictionaryFacilitator.resetDictionaries(this /* context */, - dictionaryFacilitator.getLocale(), settingsValues.mUseContactsDict, + mDictionaryFacilitator.resetDictionaries(this /* context */, + mDictionaryFacilitator.getLocale(), settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts, true /* forceReloadMainDictionary */, this); } @Override public void onDestroy() { - mInputLogic.mSuggest.mDictionaryFacilitator.closeDictionaries(); + mDictionaryFacilitator.closeDictionaries(); mSettings.onDestroy(); unregisterReceiver(mConnectivityAndRingerModeChangeReceiver); if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { @@ -666,9 +662,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mInputLogic.mConnection.finishComposingText(); mInputLogic.mConnection.endBatchEdit(); } - final DistracterFilter distracterFilter = createDistracterFilter(); PersonalizationDictionarySessionRegistrar.onConfigurationChanged(this, conf, - mInputLogic.mSuggest.mDictionaryFacilitator, distracterFilter); + mDictionaryFacilitator); super.onConfigurationChanged(conf); } @@ -841,7 +836,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen currentSettingsValues = mSettings.getCurrent(); if (currentSettingsValues.mCorrectionEnabled) { - suggest.setAutoCorrectionThreshold(currentSettingsValues.mAutoCorrectionThreshold); + suggest.setAutoCorrectionThreshold( + currentSettingsValues.mAutoCorrectionThreshold); } switcher.loadKeyboard(editorInfo, currentSettingsValues, getCurrentAutoCapsState(), @@ -870,7 +866,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mHandler.cancelUpdateSuggestionStrip(); mainKeyboardView.setMainDictionaryAvailability( - suggest.mDictionaryFacilitator.hasInitializedMainDictionary()); + mDictionaryFacilitator.hasInitializedMainDictionary()); mainKeyboardView.setKeyPreviewPopupEnabled(currentSettingsValues.mKeyPreviewPopupOn, currentSettingsValues.mKeyPreviewPopupDismissDelay); mainKeyboardView.setSlidingKeyInputPreviewEnabled( @@ -1167,8 +1163,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } else { wordToEdit = word; } - mInputLogic.mSuggest.mDictionaryFacilitator.addWordToUserDictionary( - this /* context */, wordToEdit); + mDictionaryFacilitator.addWordToUserDictionary(this /* context */, wordToEdit); } // Callback for the {@link SuggestionStripView}, to call when the important notice strip is @@ -1352,7 +1347,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen currentSettings.mInputAttributes)) { return true; } - if (!currentSettings.isSuggestionStripVisible()) { + if (!currentSettings.isCurrentOrientationAllowingSuggestionsPerUserSettings()) { return false; } if (currentSettings.isApplicationSpecifiedCompletionsOn()) { @@ -1397,8 +1392,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final SettingsValues currentSettings = mSettings.getCurrent(); final boolean showSuggestions; - if (SuggestedWords.EMPTY == suggestedWords || suggestedWords.isPunctuationSuggestions() - || !currentSettings.isSuggestionsRequested()) { + // May show the important notice when there are no suggestions to show, + if (SuggestedWords.EMPTY == suggestedWords + // or the suggestion strip is expected to show punctuation suggestions, + || suggestedWords.isPunctuationSuggestions() + // or it's not requested to show suggestions by the input field, + || !currentSettings.isSuggestionsRequested() + // or the "show correction suggestions" settings is off by users preference. + || !currentSettings.isCurrentOrientationAllowingSuggestionsPerUserSettings()) { showSuggestions = !mSuggestionStripView.maybeShowImportantNoticeTitle( currentSettings.mInputAttributes); } else { @@ -1725,15 +1726,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @UsedForTesting /* package for test */ void waitForLoadingDictionaries(final long timeout, final TimeUnit unit) throws InterruptedException { - mInputLogic.mSuggest.mDictionaryFacilitator.waitForLoadingDictionariesForTesting( - timeout, unit); + mDictionaryFacilitator.waitForLoadingDictionariesForTesting(timeout, unit); } // DO NOT USE THIS for any other purpose than testing. This can break the keyboard badly. @UsedForTesting /* package for test */ void replaceDictionariesForTest(final Locale locale) { final SettingsValues settingsValues = mSettings.getCurrent(); - mInputLogic.mSuggest.mDictionaryFacilitator.resetDictionaries(this, locale, + mDictionaryFacilitator.resetDictionaries(this, locale, settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts, false /* forceReloadMainDictionary */, this /* listener */); } @@ -1741,24 +1741,21 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // DO NOT USE THIS for any other purpose than testing. @UsedForTesting /* package for test */ void clearPersonalizedDictionariesForTest() { - mInputLogic.mSuggest.mDictionaryFacilitator.clearUserHistoryDictionary(); - mInputLogic.mSuggest.mDictionaryFacilitator.clearPersonalizationDictionary(); + mDictionaryFacilitator.clearUserHistoryDictionary(); + mDictionaryFacilitator.clearPersonalizationDictionary(); } @UsedForTesting - /* package for test */ DistracterFilter createDistracterFilter() { - return new DistracterFilter(this /* Context */, - mRichImm.getMyEnabledInputMethodSubtypeList( - true /* allowsImplicitlySelectedSubtypes */)); + /* package for test */ List<InputMethodSubtype> getEnabledSubtypesForTest() { + return (mRichImm != null) ? mRichImm.getMyEnabledInputMethodSubtypeList( + true /* allowsImplicitlySelectedSubtypes */) : new ArrayList<InputMethodSubtype>(); } public void dumpDictionaryForDebug(final String dictName) { - final DictionaryFacilitatorForSuggest dictionaryFacilitator = - mInputLogic.mSuggest.mDictionaryFacilitator; - if (dictionaryFacilitator.getLocale() == null) { + if (mDictionaryFacilitator.getLocale() == null) { resetSuggest(); } - mInputLogic.mSuggest.mDictionaryFacilitator.dumpDictionaryForDebug(dictName); + mDictionaryFacilitator.dumpDictionaryForDebug(dictName); } public void debugDumpStateAndCrashWithException(final String context) { diff --git a/java/src/com/android/inputmethod/latin/PrevWordsInfo.java b/java/src/com/android/inputmethod/latin/PrevWordsInfo.java index ecc8947db..42b311c69 100644 --- a/java/src/com/android/inputmethod/latin/PrevWordsInfo.java +++ b/java/src/com/android/inputmethod/latin/PrevWordsInfo.java @@ -16,23 +16,32 @@ package com.android.inputmethod.latin; -import android.util.Log; - +/** + * Class to represent information of previous words. This class is used to add n-gram entries + * into binary dictionaries, to get predictions, and to get suggestions. + */ // TODO: Support multiple previous words for n-gram. public class PrevWordsInfo { - // The previous word. May be null after resetting and before starting a new composing word, or - // when there is no context like at the start of text for example. It can also be set to null - // externally when the user enters a separator that does not let bigrams across, like a period - // or a comma. + public static final PrevWordsInfo EMPTY_PREV_WORDS_INFO = new PrevWordsInfo(null); + public static final PrevWordsInfo BEGINNING_OF_SENTENCE = new PrevWordsInfo(); + + // The word immediately before the considered word. null means we don't have any context + // including the "beginning of sentence context" - we just don't know what to predict. + // An example of that is after a comma. + // For simplicity of implementation, this may also be null transiently after the WordComposer + // was reset and before starting a new composing word, but we should never be calling + // getSuggetions* in this situation. + // This is an empty string when mIsBeginningOfSentence is true. public final String mPrevWord; // TODO: Have sentence separator. - // Whether the current context is beginning of sentence or not. + // Whether the current context is beginning of sentence or not. This is true when composing at + // the beginning of an input field or composing a word after a sentence separator. public final boolean mIsBeginningOfSentence; // Beginning of sentence. public PrevWordsInfo() { - mPrevWord = null; + mPrevWord = ""; mIsBeginningOfSentence = true; } @@ -40,4 +49,14 @@ public class PrevWordsInfo { mPrevWord = prevWord; mIsBeginningOfSentence = false; } + + public boolean isValid() { + return mPrevWord != null; + } + + @Override + public String toString() { + return "PrevWord: " + mPrevWord + ", isBeginningOfSentence: " + + mIsBeginningOfSentence + "."; + } } diff --git a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java index 4911bcdf6..0fba37c8a 100644 --- a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java +++ b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java @@ -17,8 +17,6 @@ package com.android.inputmethod.latin; import com.android.inputmethod.keyboard.internal.KeySpecParser; -import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.StringUtils; import java.util.ArrayList; @@ -49,7 +47,7 @@ public final class PunctuationSuggestions extends SuggestedWords { */ public static PunctuationSuggestions newPunctuationSuggestions( final String[] punctuationSpecs) { - final ArrayList<SuggestedWordInfo> puncuationsList = CollectionUtils.newArrayList(); + final ArrayList<SuggestedWordInfo> puncuationsList = new ArrayList<>(); for (final String puncSpec : punctuationSpecs) { puncuationsList.add(newHardCodedWordInfo(puncSpec)); } diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index 2c54e10aa..e7c163606 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -542,7 +542,7 @@ public final class RichInputConnection { final SpacingAndPunctuations spacingAndPunctuations, final int n) { mIC = mParent.getCurrentInputConnection(); if (null == mIC) { - return new PrevWordsInfo(null); + return PrevWordsInfo.EMPTY_PREV_WORDS_INFO; } final CharSequence prev = getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0); if (DEBUG_PREVIOUS_TEXT && null != prev) { @@ -588,30 +588,30 @@ public final class RichInputConnection { // (n = 2) "abc. def|" -> beginning-of-sentence public static PrevWordsInfo getPrevWordsInfoFromNthPreviousWord(final CharSequence prev, final SpacingAndPunctuations spacingAndPunctuations, final int n) { - if (prev == null) return new PrevWordsInfo(null); + if (prev == null) return PrevWordsInfo.EMPTY_PREV_WORDS_INFO; final String[] w = spaceRegex.split(prev); // If we can't find n words, or we found an empty word, the context is // beginning-of-sentence. if (w.length < n) { - return new PrevWordsInfo(); + return PrevWordsInfo.BEGINNING_OF_SENTENCE; } final String nthPrevWord = w[w.length - n]; final int length = nthPrevWord.length(); if (length <= 0) { - return new PrevWordsInfo(); + return PrevWordsInfo.BEGINNING_OF_SENTENCE; } // If ends in a sentence separator, the context is beginning-of-sentence. final char lastChar = nthPrevWord.charAt(length - 1); if (spacingAndPunctuations.isSentenceSeparator(lastChar)) { - new PrevWordsInfo(); + return PrevWordsInfo.BEGINNING_OF_SENTENCE; } // If ends in a word separator or connector, the context is unclear. // TODO: Return meaningful context for this case. if (spacingAndPunctuations.isWordSeparator(lastChar) || spacingAndPunctuations.isWordConnector(lastChar)) { - return new PrevWordsInfo(null); + return PrevWordsInfo.EMPTY_PREV_WORDS_INFO; } return new PrevWordsInfo(nthPrevWord); } diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java index 64cc562c8..cbdc4b9eb 100644 --- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java +++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java @@ -31,7 +31,6 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.Collections; @@ -53,9 +52,9 @@ public final class RichInputMethodManager { private InputMethodManagerCompatWrapper mImmWrapper; private InputMethodInfoCache mInputMethodInfoCache; final HashMap<InputMethodInfo, List<InputMethodSubtype>> - mSubtypeListCacheWithImplicitlySelectedSubtypes = CollectionUtils.newHashMap(); + mSubtypeListCacheWithImplicitlySelectedSubtypes = new HashMap<>(); final HashMap<InputMethodInfo, List<InputMethodSubtype>> - mSubtypeListCacheWithoutImplicitlySelectedSubtypes = CollectionUtils.newHashMap(); + mSubtypeListCacheWithoutImplicitlySelectedSubtypes = new HashMap<>(); private static final int INDEX_NOT_FOUND = -1; diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index c8a2fb2f9..a3d09565c 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -255,8 +255,7 @@ public final class SubtypeSwitcher { public boolean isSystemLocaleSameAsLocaleOfAllEnabledSubtypesOfEnabledImes() { final Locale systemLocale = mResources.getConfiguration().locale; - final Set<InputMethodSubtype> enabledSubtypesOfEnabledImes = - new HashSet<InputMethodSubtype>(); + final Set<InputMethodSubtype> enabledSubtypesOfEnabledImes = new HashSet<>(); final InputMethodManager inputMethodManager = mRichImm.getInputMethodManager(); final List<InputMethodInfo> enabledInputMethodInfoList = inputMethodManager.getEnabledInputMethodList(); diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 43daee4d2..63928e31f 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -18,12 +18,12 @@ package com.android.inputmethod.latin; import android.text.TextUtils; +import com.android.inputmethod.event.Event; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.utils.AutoCorrectionUtils; import com.android.inputmethod.latin.utils.BinaryDictionaryUtils; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.StringUtils; import com.android.inputmethod.latin.utils.SuggestionResults; @@ -52,11 +52,14 @@ public final class Suggest { private static final int SUPPRESS_SUGGEST_THRESHOLD = -2000000000; private static final boolean DBG = LatinImeLogger.sDBG; - public final DictionaryFacilitatorForSuggest mDictionaryFacilitator = - new DictionaryFacilitatorForSuggest(); + private final DictionaryFacilitator mDictionaryFacilitator; private float mAutoCorrectionThreshold; + public Suggest(final DictionaryFacilitator dictionaryFacilitator) { + mDictionaryFacilitator = dictionaryFacilitator; + } + public Locale getLocale() { return mDictionaryFacilitator.getLocale(); } @@ -102,7 +105,7 @@ public final class Suggest { final ArrayList<SuggestedWordInfo> rawSuggestions; if (ProductionFlag.INCLUDE_RAW_SUGGESTIONS) { - rawSuggestions = CollectionUtils.newArrayList(); + rawSuggestions = new ArrayList<>(); } else { rawSuggestions = null; } @@ -124,7 +127,7 @@ public final class Suggest { suggestionResults.first(), suggestionResults.mLocale, isAllUpperCase, isFirstCharCapitalized, trailingSingleQuotesCount); firstSuggestion = firstSuggestedWordInfo.mWord; - if (SuggestedWordInfo.KIND_WHITELIST != firstSuggestedWordInfo.mKind) { + if (!firstSuggestedWordInfo.isKindOf(SuggestedWordInfo.KIND_WHITELIST)) { whitelistedWord = null; } else { whitelistedWord = firstSuggestion; @@ -155,7 +158,7 @@ public final class Suggest { || suggestionResults.isEmpty() || wordComposer.hasDigits() || wordComposer.isMostlyCaps() || wordComposer.isResumed() || !mDictionaryFacilitator.hasInitializedMainDictionary() - || SuggestedWordInfo.KIND_SHORTCUT == suggestionResults.first().mKind) { + || suggestionResults.first().isKindOf(SuggestedWordInfo.KIND_SHORTCUT)) { // If we don't have a main dictionary, we never want to auto-correct. The reason for // this is, the user may have a contact whose name happens to match a valid word in // their language, and it will unexpectedly auto-correct. For example, if the user @@ -171,7 +174,7 @@ public final class Suggest { } final ArrayList<SuggestedWordInfo> suggestionsContainer = - CollectionUtils.newArrayList(suggestionResults); + new ArrayList<>(suggestionResults); final int suggestionsCount = suggestionsContainer.size(); if (isFirstCharCapitalized || isAllUpperCase || 0 != trailingSingleQuotesCount) { for (int i = 0; i < suggestionsCount; ++i) { @@ -223,7 +226,7 @@ public final class Suggest { final OnGetSuggestedWordsCallback callback) { final ArrayList<SuggestedWordInfo> rawSuggestions; if (ProductionFlag.INCLUDE_RAW_SUGGESTIONS) { - rawSuggestions = CollectionUtils.newArrayList(); + rawSuggestions = new ArrayList<>(); } else { rawSuggestions = null; } @@ -235,7 +238,7 @@ public final class Suggest { } final ArrayList<SuggestedWordInfo> suggestionsContainer = - CollectionUtils.newArrayList(suggestionResults); + new ArrayList<>(suggestionResults); final int suggestionsCount = suggestionsContainer.size(); final boolean isFirstCharCapitalized = wordComposer.wasShiftedNoLock(); final boolean isAllUpperCase = wordComposer.isAllUpperCase(); @@ -278,8 +281,7 @@ public final class Suggest { final SuggestedWordInfo typedWordInfo = suggestions.get(0); typedWordInfo.setDebugString("+"); final int suggestionsSize = suggestions.size(); - final ArrayList<SuggestedWordInfo> suggestionsList = - CollectionUtils.newArrayList(suggestionsSize); + final ArrayList<SuggestedWordInfo> suggestionsList = new ArrayList<>(suggestionsSize); suggestionsList.add(typedWordInfo); // Note: i here is the index in mScores[], but the index in mSuggestions is one more // than i because we added the typed word to mSuggestions without touching mScores. diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index dc2c9fd0e..62da0f992 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -19,7 +19,6 @@ package com.android.inputmethod.latin; import android.text.TextUtils; import android.view.inputmethod.CompletionInfo; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.StringUtils; import java.util.ArrayList; @@ -34,8 +33,7 @@ public class SuggestedWords { // The maximum number of suggestions available. public static final int MAX_SUGGESTIONS = 18; - private static final ArrayList<SuggestedWordInfo> EMPTY_WORD_INFO_LIST = - CollectionUtils.newArrayList(0); + private static final ArrayList<SuggestedWordInfo> EMPTY_WORD_INFO_LIST = new ArrayList<>(0); public static final SuggestedWords EMPTY = new SuggestedWords( EMPTY_WORD_INFO_LIST, null /* rawSuggestions */, false, false, false, false); @@ -165,7 +163,7 @@ public class SuggestedWords { public static ArrayList<SuggestedWordInfo> getFromApplicationSpecifiedCompletions( final CompletionInfo[] infos) { - final ArrayList<SuggestedWordInfo> result = CollectionUtils.newArrayList(); + final ArrayList<SuggestedWordInfo> result = new ArrayList<>(); for (final CompletionInfo info : infos) { if (null == info || null == info.getText()) { continue; @@ -179,8 +177,8 @@ public class SuggestedWords { // and replace it with what the user currently typed. public static ArrayList<SuggestedWordInfo> getTypedWordAndPreviousSuggestions( final String typedWord, final SuggestedWords previousSuggestions) { - final ArrayList<SuggestedWordInfo> suggestionsList = CollectionUtils.newArrayList(); - final HashSet<String> alreadySeen = CollectionUtils.newHashSet(); + final ArrayList<SuggestedWordInfo> suggestionsList = new ArrayList<>(); + final HashSet<String> alreadySeen = new HashSet<>(); suggestionsList.add(new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, @@ -209,6 +207,8 @@ public class SuggestedWords { public static final int NOT_AN_INDEX = -1; public static final int NOT_A_CONFIDENCE = -1; public static final int MAX_SCORE = Integer.MAX_VALUE; + + // TODO: Make KIND_MASK_KIND private. public static final int KIND_MASK_KIND = 0xFF; // Mask to get only the kind public static final int KIND_TYPED = 0; // What user typed public static final int KIND_CORRECTION = 1; // Simple correction/suggestion @@ -224,16 +224,19 @@ public class SuggestedWords { public static final int KIND_RESUMED = 9; public static final int KIND_OOV_CORRECTION = 10; // Most probable string correction + // TODO: Make KIND_MASK_FLAGS private. public static final int KIND_MASK_FLAGS = 0xFFFFFF00; // Mask to get the flags public static final int KIND_FLAG_POSSIBLY_OFFENSIVE = 0x80000000; public static final int KIND_FLAG_EXACT_MATCH = 0x40000000; + public static final int KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION = 0x20000000; public final String mWord; // The completion info from the application. Null for suggestions that don't come from // the application (including keyboard-computed ones, so this is almost always null) public final CompletionInfo mApplicationSpecifiedCompletionInfo; public final int mScore; - public final int mKind; // one of the KIND_* constants above + // TODO: Rename to mKindAndFlags and make this private. + public final int mKind; // kind and kind flags public final int mCodePointCount; public final Dictionary mSourceDict; // For auto-commit. This keeps track of the index inside the touch coordinates array @@ -249,7 +252,7 @@ public class SuggestedWords { * Create a new suggested word info. * @param word The string to suggest. * @param score A measure of how likely this suggestion is. - * @param kind The kind of suggestion, as one of the above KIND_* constants. + * @param kind The kind of suggestion, as one of the above KIND_* constants with flags. * @param sourceDict What instance of Dictionary produced this suggestion. * @param indexOfTouchPointOfSecondWord See mIndexOfTouchPointOfSecondWord. * @param autoCommitFirstWordConfidence See mAutoCommitFirstWordConfidence. @@ -284,9 +287,15 @@ public class SuggestedWords { } public boolean isEligibleForAutoCommit() { - return (KIND_CORRECTION == mKind && NOT_AN_INDEX != mIndexOfTouchPointOfSecondWord); + return (isKindOf(KIND_CORRECTION) && NOT_AN_INDEX != mIndexOfTouchPointOfSecondWord); + } + + public boolean isKindOf(final int kind) { + return (mKind & KIND_MASK_KIND) == kind; } + // TODO: Add predicate methods for each flag. + public void setDebugString(final String str) { if (null == str) throw new NullPointerException("Debug info is null"); mDebugString = str; @@ -337,11 +346,11 @@ public class SuggestedWords { // SuggestedWords is an immutable object, as much as possible. We must not just remove // words from the member ArrayList as some other parties may expect the object to never change. public SuggestedWords getSuggestedWordsExcludingTypedWord() { - final ArrayList<SuggestedWordInfo> newSuggestions = CollectionUtils.newArrayList(); + final ArrayList<SuggestedWordInfo> newSuggestions = new ArrayList<>(); String typedWord = null; for (int i = 0; i < mSuggestedWordInfoList.size(); ++i) { final SuggestedWordInfo info = mSuggestedWordInfoList.get(i); - if (SuggestedWordInfo.KIND_TYPED != info.mKind) { + if (!info.isKindOf(SuggestedWordInfo.KIND_TYPED)) { newSuggestions.add(info); } else { assert(null == typedWord); @@ -361,7 +370,7 @@ public class SuggestedWords { // we should only suggest replacements for this last word. // TODO: make this work with languages without spaces. public SuggestedWords getSuggestedWordsForLastWordOfPhraseGesture() { - final ArrayList<SuggestedWordInfo> newSuggestions = CollectionUtils.newArrayList(); + final ArrayList<SuggestedWordInfo> newSuggestions = new ArrayList<>(); for (int i = 0; i < mSuggestedWordInfoList.size(); ++i) { final SuggestedWordInfo info = mSuggestedWordInfoList.get(i); final int indexOfLastSpace = info.mWord.lastIndexOf(Constants.CODE_SPACE) + 1; diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index 6ecb37346..864942d04 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -18,7 +18,6 @@ package com.android.inputmethod.latin; import com.android.inputmethod.event.CombinerChain; import com.android.inputmethod.event.Event; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CoordinateUtils; import com.android.inputmethod.latin.utils.StringUtils; @@ -79,13 +78,13 @@ public final class WordComposer { public WordComposer() { mCombinerChain = new CombinerChain(""); - mEvents = CollectionUtils.newArrayList(); + mEvents = new ArrayList<>(); mAutoCorrection = null; mIsResumed = false; mIsBatchMode = false; mCursorPositionWithinWord = 0; mRejectedBatchModeSuggestion = null; - mPrevWordsInfo = new PrevWordsInfo(null); + mPrevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; refreshTypedWordCache(); } @@ -117,7 +116,7 @@ public final class WordComposer { mIsBatchMode = false; mCursorPositionWithinWord = 0; mRejectedBatchModeSuggestion = null; - mPrevWordsInfo = new PrevWordsInfo(null); + mPrevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; refreshTypedWordCache(); } @@ -445,7 +444,7 @@ public final class WordComposer { // when the user inputs a separator that's not whitespace (including the case of the // double-space-to-period feature). public void discardPreviousWordForSuggestion() { - mPrevWordsInfo = new PrevWordsInfo(null); + mPrevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; } public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord, diff --git a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java index 139e73aa4..7071d8689 100644 --- a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java +++ b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java @@ -27,7 +27,6 @@ import com.android.inputmethod.latin.BinaryDictionaryFileDumper; import com.android.inputmethod.latin.BinaryDictionaryGetter; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.makedict.DictionaryHeader; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.DialogUtils; import com.android.inputmethod.latin.utils.DictionaryInfoUtils; import com.android.inputmethod.latin.utils.LocaleUtils; @@ -50,7 +49,7 @@ public class ExternalDictionaryGetterForDebug { private static String[] findDictionariesInTheDownloadedFolder() { final File[] files = new File(SOURCE_FOLDER).listFiles(); - final ArrayList<String> eligibleList = CollectionUtils.newArrayList(); + final ArrayList<String> eligibleList = new ArrayList<>(); for (File f : files) { final DictionaryHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(f); if (null == header) continue; diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index 7536ff94c..2318dae2d 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -32,7 +32,7 @@ import com.android.inputmethod.event.InputTransaction; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Dictionary; -import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest; +import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.InputPointers; import com.android.inputmethod.latin.LastComposedWord; import com.android.inputmethod.latin.LatinIME; @@ -49,7 +49,6 @@ import com.android.inputmethod.latin.settings.SettingsValues; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.suggestions.SuggestionStripViewAccessor; import com.android.inputmethod.latin.utils.AsyncResultHolder; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.InputTypeUtils; import com.android.inputmethod.latin.utils.LatinImeLoggerUtils; import com.android.inputmethod.latin.utils.RecapitalizeStatus; @@ -79,7 +78,8 @@ public final class InputLogic { private int mSpaceState; // Never null public SuggestedWords mSuggestedWords = SuggestedWords.EMPTY; - public final Suggest mSuggest = new Suggest(); + public final Suggest mSuggest; + private final DictionaryFacilitator mDictionaryFacilitator; public LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; public final WordComposer mWordComposer; @@ -88,7 +88,7 @@ public final class InputLogic { private int mDeleteCount; private long mLastKeyTime; - public final TreeSet<Long> mCurrentlyPressedHardwareKeys = CollectionUtils.newTreeSet(); + public final TreeSet<Long> mCurrentlyPressedHardwareKeys = new TreeSet<>(); // Keeps track of most recently inserted text (multi-character key) for reverting private String mEnteredText; @@ -102,14 +102,19 @@ public final class InputLogic { * Create a new instance of the input logic. * @param latinIME the instance of the parent LatinIME. We should remove this when we can. * @param suggestionStripViewAccessor an object to access the suggestion strip view. + * @param dictionaryFacilitator facilitator for getting suggestions and updating user history + * dictionary. */ public InputLogic(final LatinIME latinIME, - final SuggestionStripViewAccessor suggestionStripViewAccessor) { + final SuggestionStripViewAccessor suggestionStripViewAccessor, + final DictionaryFacilitator dictionaryFacilitator) { mLatinIME = latinIME; mSuggestionStripViewAccessor = suggestionStripViewAccessor; mWordComposer = new WordComposer(); mConnection = new RichInputConnection(latinIME); mInputLogicHandler = InputLogicHandler.NULL_HANDLER; + mSuggest = new Suggest(dictionaryFacilitator); + mDictionaryFacilitator = dictionaryFacilitator; } /** @@ -173,7 +178,7 @@ public final class InputLogic { final InputLogicHandler inputLogicHandler = mInputLogicHandler; mInputLogicHandler = InputLogicHandler.NULL_HANDLER; inputLogicHandler.destroy(); - mSuggest.mDictionaryFacilitator.closeDictionaries(); + mDictionaryFacilitator.closeDictionaries(); } /** @@ -265,7 +270,7 @@ public final class InputLogic { // code path as for other kinds, use commitChosenWord, and do everything normally. We will // however need to reset the suggestion strip right away, because we know we can't take // the risk of calling commitCompletion twice because we don't know how the app will react. - if (SuggestedWordInfo.KIND_APP_DEFINED == suggestionInfo.mKind) { + if (suggestionInfo.isKindOf(SuggestedWordInfo.KIND_APP_DEFINED)) { mSuggestedWords = SuggestedWords.EMPTY; mSuggestionStripViewAccessor.setNeutralSuggestionStrip(); inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); @@ -295,18 +300,16 @@ public final class InputLogic { // We should show the "Touch again to save" hint if the user pressed the first entry // AND it's in none of our current dictionaries (main, user or otherwise). - final DictionaryFacilitatorForSuggest dictionaryFacilitator = - mSuggest.mDictionaryFacilitator; final boolean showingAddToDictionaryHint = (SuggestedWordInfo.KIND_TYPED == suggestionInfo.mKind || SuggestedWordInfo.KIND_OOV_CORRECTION == suggestionInfo.mKind) - && !dictionaryFacilitator.isValidWord(suggestion, true /* ignoreCase */); + && !mDictionaryFacilitator.isValidWord(suggestion, true /* ignoreCase */); if (settingsValues.mIsInternal) { LatinImeLoggerUtils.onSeparator((char)Constants.CODE_SPACE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); } - if (showingAddToDictionaryHint && dictionaryFacilitator.isUserDictionaryEnabled()) { + if (showingAddToDictionaryHint && mDictionaryFacilitator.isUserDictionaryEnabled()) { mSuggestionStripViewAccessor.showAddToDictionaryHint(suggestion); } else { // If we're not showing the "Touch again to save", then update the suggestion strip. @@ -805,11 +808,10 @@ public final class InputLogic { final int codePoint = inputTransaction.mEvent.mCodePoint; final SettingsValues settingsValues = inputTransaction.mSettingsValues; boolean didAutoCorrect = false; - final boolean wasComposingWord = mWordComposer.isComposingWord(); // We avoid sending spaces in languages without spaces if we were composing. final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == codePoint && !settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces - && wasComposingWord; + && mWordComposer.isComposingWord(); if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) { // If we are in the middle of a recorrection, we need to commit the recorrection // first so that we can insert the separator at the current cursor position. @@ -853,7 +855,7 @@ public final class InputLogic { promotePhantomSpace(settingsValues); } if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { - ResearchLogger.latinIME_handleSeparator(codePoint, wasComposingWord); + ResearchLogger.latinIME_handleSeparator(codePoint, mWordComposer.isComposingWord()); } if (!shouldAvoidSendingCode) { @@ -869,9 +871,7 @@ public final class InputLogic { } startDoubleSpacePeriodCountdown(inputTransaction); - if (wasComposingWord) { - inputTransaction.setRequiresUpdateSuggestions(); - } + inputTransaction.setRequiresUpdateSuggestions(); } else { if (swapWeakSpace) { swapSwapperAndSpace(inputTransaction); @@ -1050,7 +1050,8 @@ public final class InputLogic { } } } - if (inputTransaction.mSettingsValues.isSuggestionStripVisible() + if (inputTransaction.mSettingsValues + .isCurrentOrientationAllowingSuggestionsPerUserSettings() && inputTransaction.mSettingsValues.mSpacingAndPunctuations .mCurrentLanguageHasSpaces && !mConnection.isCursorFollowedByWordCharacter( @@ -1250,7 +1251,7 @@ public final class InputLogic { mWordComposer.wasAutoCapitalized() && !mWordComposer.isMostlyCaps(); final int timeStampInSeconds = (int)TimeUnit.MILLISECONDS.toSeconds( System.currentTimeMillis()); - mSuggest.mDictionaryFacilitator.addToUserHistory(suggestion, wasAutoCapitalized, + mDictionaryFacilitator.addToUserHistory(suggestion, wasAutoCapitalized, prevWordsInfo, timeStampInSeconds, settingsValues.mBlockPotentiallyOffensive); } @@ -1269,7 +1270,7 @@ public final class InputLogic { return; } - final AsyncResultHolder<SuggestedWords> holder = new AsyncResultHolder<SuggestedWords>(); + final AsyncResultHolder<SuggestedWords> holder = new AsyncResultHolder<>(); mInputLogicHandler.getSuggestedWords(Suggest.SESSION_TYPING, SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() { @Override @@ -1349,7 +1350,7 @@ public final class InputLogic { // we just do not resume because it's safer. final int numberOfCharsInWordBeforeCursor = range.getNumberOfCharsInWordBeforeCursor(); if (numberOfCharsInWordBeforeCursor > expectedCursorPosition) return; - final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList(); + final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<>(); final String typedWord = range.mWord.toString(); if (includeResumedWordInSuggestions) { suggestions.add(new SuggestedWordInfo(typedWord, @@ -1462,8 +1463,7 @@ public final class InputLogic { } mConnection.deleteSurroundingText(deleteLength, 0); if (!TextUtils.isEmpty(prevWordsInfo.mPrevWord) && !TextUtils.isEmpty(committedWord)) { - mSuggest.mDictionaryFacilitator.cancelAddingUserHistory( - prevWordsInfo, committedWordString); + mDictionaryFacilitator.cancelAddingUserHistory(prevWordsInfo, committedWordString); } final String stringToCommit = originallyTypedWord + mLastComposedWord.mSeparatorString; final SpannableString textToCommit = new SpannableString(stringToCommit); @@ -1473,7 +1473,7 @@ public final class InputLogic { committedWord.length(), Object.class); final int lastCharIndex = textToCommit.length() - 1; // We will collect all suggestions in the following array. - final ArrayList<String> suggestions = CollectionUtils.newArrayList(); + final ArrayList<String> suggestions = new ArrayList<>(); // First, add the committed word to the list of suggestions. suggestions.add(committedWordString); for (final Object span : spans) { @@ -1609,8 +1609,9 @@ public final class InputLogic { return mConnection.getPrevWordsInfoFromNthPreviousWord( spacingAndPunctuations, nthPreviousWord); } else { - return LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ? new PrevWordsInfo() - : new PrevWordsInfo(mLastComposedWord.mCommittedWord.toString()); + return LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ? + PrevWordsInfo.BEGINNING_OF_SENTENCE : + new PrevWordsInfo(mLastComposedWord.mCommittedWord.toString()); } } diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java index f5f072b7a..a2ae74b20 100644 --- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java +++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java @@ -192,8 +192,9 @@ public final class FormatSpec { public static final int VERSION2 = 2; // Dictionary version used for testing. public static final int VERSION4_ONLY_FOR_TESTING = 399; - public static final int VERSION4 = 401; - public static final int VERSION4_DEV = 402; + public static final int VERSION401 = 401; + public static final int VERSION4 = 402; + public static final int VERSION4_DEV = 403; static final int MINIMUM_SUPPORTED_VERSION = VERSION2; static final int MAXIMUM_SUPPORTED_VERSION = VERSION4_DEV; diff --git a/java/src/com/android/inputmethod/latin/makedict/WordProperty.java b/java/src/com/android/inputmethod/latin/makedict/WordProperty.java index 853392200..31cb59756 100644 --- a/java/src/com/android/inputmethod/latin/makedict/WordProperty.java +++ b/java/src/com/android/inputmethod/latin/makedict/WordProperty.java @@ -18,7 +18,6 @@ package com.android.inputmethod.latin.makedict; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.BinaryDictionary; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CombinedFormatUtils; import com.android.inputmethod.latin.utils.StringUtils; @@ -35,6 +34,8 @@ public final class WordProperty implements Comparable<WordProperty> { public final ProbabilityInfo mProbabilityInfo; public final ArrayList<WeightedString> mShortcutTargets; public final ArrayList<WeightedString> mBigrams; + // TODO: Support mIsBeginningOfSentence. + public final boolean mIsBeginningOfSentence; public final boolean mIsNotAWord; public final boolean mIsBlacklistEntry; public final boolean mHasShortcuts; @@ -51,6 +52,7 @@ public final class WordProperty implements Comparable<WordProperty> { mProbabilityInfo = probabilityInfo; mShortcutTargets = shortcutTargets; mBigrams = bigrams; + mIsBeginningOfSentence = false; mIsNotAWord = isNotAWord; mIsBlacklistEntry = isBlacklistEntry; mHasBigrams = bigrams != null && !bigrams.isEmpty(); @@ -75,8 +77,9 @@ public final class WordProperty implements Comparable<WordProperty> { final ArrayList<Integer> shortcutProbabilities) { mWord = StringUtils.getStringFromNullTerminatedCodePointArray(codePoints); mProbabilityInfo = createProbabilityInfoFromArray(probabilityInfo); - mShortcutTargets = CollectionUtils.newArrayList(); - mBigrams = CollectionUtils.newArrayList(); + mShortcutTargets = new ArrayList<>(); + mBigrams = new ArrayList<>(); + mIsBeginningOfSentence = false; mIsNotAWord = isNotAWord; mIsBlacklistEntry = isBlacklisted; mHasShortcuts = hasShortcuts; diff --git a/java/src/com/android/inputmethod/latin/personalization/AccountUtils.java b/java/src/com/android/inputmethod/latin/personalization/AccountUtils.java index a446672cb..ab3ef964e 100644 --- a/java/src/com/android/inputmethod/latin/personalization/AccountUtils.java +++ b/java/src/com/android/inputmethod/latin/personalization/AccountUtils.java @@ -35,7 +35,7 @@ public class AccountUtils { } public static List<String> getDeviceAccountsEmailAddresses(final Context context) { - final ArrayList<String> retval = new ArrayList<String>(); + final ArrayList<String> retval = new ArrayList<>(); for (final Account account : getAccounts(context)) { final String name = account.name; if (Patterns.EMAIL_ADDRESS.matcher(name).matches()) { @@ -54,7 +54,7 @@ public class AccountUtils { */ public static List<String> getDeviceAccountsWithDomain( final Context context, final String domain) { - final ArrayList<String> retval = new ArrayList<String>(); + final ArrayList<String> retval = new ArrayList<>(); final String atDomain = "@" + domain.toLowerCase(Locale.ROOT); for (final Account account : getAccounts(context)) { if (account.name.toLowerCase(Locale.ROOT).endsWith(atDomain)) { diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java index 06bdba054..be658ceff 100644 --- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java +++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java @@ -31,7 +31,6 @@ import java.util.Map; * model. */ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableBinaryDictionary { - private static final String TAG = DecayingExpandableBinaryDictionaryBase.class.getSimpleName(); private static final boolean DBG_DUMP_ON_CLOSE = false; /** Any pair being typed or picked */ diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.java new file mode 100644 index 000000000..9d72de8c5 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.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.latin.personalization; + +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +public class PersonalizationDataChunk { + public final boolean mInputByUser; + public final List<String> mTokens; + public final int mTimestampInSeconds; + public final String mPackageName; + public final Locale mlocale = null; + + public PersonalizationDataChunk(boolean inputByUser, final List<String> tokens, + final int timestampInSeconds, final String packageName) { + mInputByUser = inputByUser; + mTokens = Collections.unmodifiableList(tokens); + mTimestampInSeconds = timestampInSeconds; + mPackageName = packageName; + } +} diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegistrar.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegistrar.java index 9bef7a198..450644032 100644 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegistrar.java +++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegistrar.java @@ -19,18 +19,15 @@ package com.android.inputmethod.latin.personalization; import android.content.Context; import android.content.res.Configuration; -import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest; -import com.android.inputmethod.latin.utils.DistracterFilter; +import com.android.inputmethod.latin.DictionaryFacilitator; public class PersonalizationDictionarySessionRegistrar { public static void init(final Context context, - final DictionaryFacilitatorForSuggest dictionaryFacilitator, - final DistracterFilter distracterFilter) { + final DictionaryFacilitator dictionaryFacilitator) { } public static void onConfigurationChanged(final Context context, final Configuration conf, - final DictionaryFacilitatorForSuggest dictionaryFacilitator, - final DistracterFilter distracterFilter) { + final DictionaryFacilitator dictionaryFacilitator) { } public static void onUpdateData(final Context context, final String type) { diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java index 6ef505e76..aac40940b 100644 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java +++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java @@ -16,12 +16,11 @@ package com.android.inputmethod.latin.personalization; -import com.android.inputmethod.latin.utils.CollectionUtils; -import com.android.inputmethod.latin.utils.FileUtils; - import android.content.Context; import android.util.Log; +import com.android.inputmethod.latin.utils.FileUtils; + import java.io.File; import java.io.FilenameFilter; import java.lang.ref.SoftReference; @@ -33,9 +32,9 @@ public class PersonalizationHelper { private static final String TAG = PersonalizationHelper.class.getSimpleName(); private static final boolean DEBUG = false; private static final ConcurrentHashMap<String, SoftReference<UserHistoryDictionary>> - sLangUserHistoryDictCache = CollectionUtils.newConcurrentHashMap(); + sLangUserHistoryDictCache = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<String, SoftReference<PersonalizationDictionary>> - sLangPersonalizationDictCache = CollectionUtils.newConcurrentHashMap(); + sLangPersonalizationDictCache = new ConcurrentHashMap<>(); public static UserHistoryDictionary getUserHistoryDictionary( final Context context, final Locale locale) { @@ -54,8 +53,7 @@ public class PersonalizationHelper { } } final UserHistoryDictionary dict = new UserHistoryDictionary(context, locale); - sLangUserHistoryDictCache.put(localeStr, - new SoftReference<UserHistoryDictionary>(dict)); + sLangUserHistoryDictCache.put(localeStr, new SoftReference<>(dict)); return dict; } } @@ -108,8 +106,7 @@ public class PersonalizationHelper { } } final PersonalizationDictionary dict = new PersonalizationDictionary(context, locale); - sLangPersonalizationDictCache.put( - localeStr, new SoftReference<PersonalizationDictionary>(dict)); + sLangPersonalizationDictCache.put(localeStr, new SoftReference<>(dict)); return dict; } } diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java index f89caf921..67ad54fb7 100644 --- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java +++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java @@ -23,6 +23,7 @@ import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.ExpandableBinaryDictionary; import com.android.inputmethod.latin.PrevWordsInfo; +import com.android.inputmethod.latin.utils.DistracterFilter; import java.io.File; import java.util.Locale; @@ -60,10 +61,11 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas * @param word the word the user inputted * @param isValid whether the word is valid or not * @param timestamp the timestamp when the word has been inputted + * @param distracterFilter the filter to check whether the word is a distracter */ public static void addToDictionary(final ExpandableBinaryDictionary userHistoryDictionary, final PrevWordsInfo prevWordsInfo, final String word, final boolean isValid, - final int timestamp) { + final int timestamp, final DistracterFilter distracterFilter) { final String prevWord = prevWordsInfo.mPrevWord; if (word.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH || (prevWord != null && prevWord.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH)) { @@ -71,8 +73,9 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas } final int frequency = isValid ? FREQUENCY_FOR_WORDS_IN_DICTS : FREQUENCY_FOR_WORDS_NOT_IN_DICTS; - userHistoryDictionary.addUnigramEntry(word, frequency, null /* shortcutTarget */, - 0 /* shortcutFreq */, false /* isNotAWord */, false /* isBlacklisted */, timestamp); + userHistoryDictionary.addUnigramEntryWithCheckingDistracter(word, frequency, + null /* shortcutTarget */, 0 /* shortcutFreq */, false /* isNotAWord */, + false /* isBlacklisted */, timestamp, distracterFilter); // Do not insert a word as a bigram of itself if (word.equals(prevWord)) { return; diff --git a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java index 39977e76f..31fa86774 100644 --- a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java +++ b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java @@ -47,7 +47,6 @@ import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.RichInputMethodManager; import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.DialogUtils; import com.android.inputmethod.latin.utils.IntentUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; @@ -101,7 +100,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { super(context, android.R.layout.simple_spinner_item); setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - final TreeSet<SubtypeLocaleItem> items = CollectionUtils.newTreeSet(); + final TreeSet<SubtypeLocaleItem> items = new TreeSet<>(); final InputMethodInfo imi = RichInputMethodManager.getInstance() .getInputMethodInfoOfThisIme(); final int count = imi.getSubtypeCount(); @@ -369,7 +368,6 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { mSubtype = (InputMethodSubtype)source.readParcelable(null); } - @SuppressWarnings("hiding") public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() { @Override @@ -516,8 +514,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { localeString, keyboardLayoutSetName); } - private AlertDialog createDialog( - @SuppressWarnings("unused") final SubtypePreference subtypePref) { + private AlertDialog createDialog(final SubtypePreference subtypePref) { final AlertDialog.Builder builder = new AlertDialog.Builder( DialogUtils.getPlatformDialogThemeContext(getActivity())); builder.setTitle(R.string.custom_input_styles_title) @@ -555,7 +552,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { private InputMethodSubtype[] getSubtypes() { final PreferenceGroup group = getPreferenceScreen(); - final ArrayList<InputMethodSubtype> subtypes = CollectionUtils.newArrayList(); + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>(); final int count = group.getPreferenceCount(); for (int i = 0; i < count; i++) { final Preference pref = group.getPreference(i); diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java index d4f6bcd10..48219f60a 100644 --- a/java/src/com/android/inputmethod/latin/settings/Settings.java +++ b/java/src/com/android/inputmethod/latin/settings/Settings.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.res.Resources; +import android.os.Build; import android.preference.PreferenceManager; import android.util.Log; @@ -60,6 +61,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang "pref_key_use_double_space_period"; public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE = "pref_key_block_potentially_offensive"; + public static final boolean ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS = + (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) + || (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT + && Build.VERSION.CODENAME.equals("REL")); public static final String PREF_SHOW_LANGUAGE_SWITCH_KEY = "pref_show_language_switch_key"; public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST = diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java index e1d38e7c4..302ae4390 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java @@ -59,7 +59,7 @@ public final class SettingsFragment extends InputMethodSettingsFragment private static final boolean DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS = false; private static final boolean USE_INTERNAL_PERSONAL_DICTIONARY_SETTIGS = DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS - || Build.VERSION.SDK_INT <= 18 /* Build.VERSION.JELLY_BEAN_MR2 */; + || Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2; private void setPreferenceEnabled(final String preferenceKey, final boolean enabled) { final Preference preference = findPreference(preferenceKey); @@ -169,6 +169,13 @@ public final class SettingsFragment extends InputMethodSettingsFragment removePreference(Settings.PREF_VIBRATE_ON, generalSettings); removePreference(Settings.PREF_VIBRATION_DURATION_SETTINGS, advancedSettings); } + if (!Settings.ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS) { + removePreference( + Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY, advancedSettings); + removePreference( + Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, advancedSettings); + } + // TODO: consolidate key preview dismiss delay with the key preview animation parameters. if (!Settings.readFromBuildConfigIfToShowKeyPreviewPopupOption(res)) { @@ -199,9 +206,6 @@ public final class SettingsFragment extends InputMethodSettingsFragment removePreference(Settings.PREF_SHOW_SETUP_WIZARD_ICON, advancedSettings); } - setPreferenceEnabled(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, - Settings.readShowsLanguageSwitchKey(prefs)); - final PreferenceGroup textCorrectionGroup = (PreferenceGroup) findPreference(Settings.PREF_CORRECTION_SETTINGS); final PreferenceScreen dictionaryLink = @@ -299,9 +303,6 @@ public final class SettingsFragment extends InputMethodSettingsFragment if (key.equals(Settings.PREF_POPUP_ON)) { setPreferenceEnabled(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY, Settings.readKeyPreviewPopupEnabled(prefs, res)); - } else if (key.equals(Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY)) { - setPreferenceEnabled(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, - Settings.readShowsLanguageSwitchKey(prefs)); } else if (key.equals(Settings.PREF_SHOW_SETUP_WIZARD_ICON)) { LauncherIconVisibilityManager.updateSetupWizardIconVisibility(getActivity()); } diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java index 16fd05877..6c6e79e0f 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java @@ -125,9 +125,11 @@ public final class SettingsValues { final String autoCorrectionThresholdRawValue = prefs.getString( Settings.PREF_AUTO_CORRECTION_THRESHOLD, res.getString(R.string.auto_correction_threshold_mode_index_modest)); - mIncludesOtherImesInLanguageSwitchList = prefs.getBoolean( - Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, false); - mShowsLanguageSwitchKey = Settings.readShowsLanguageSwitchKey(prefs); + mIncludesOtherImesInLanguageSwitchList = Settings.ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS + ? prefs.getBoolean(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, false) + : true /* forcibly */; + mShowsLanguageSwitchKey = Settings.ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS + ? Settings.readShowsLanguageSwitchKey(prefs) : true /* forcibly */; mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true); mUsePersonalizedDicts = prefs.getBoolean(Settings.PREF_KEY_USE_PERSONALIZED_DICTS, true); mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true); @@ -171,7 +173,7 @@ public final class SettingsValues { ResourceUtils.getFloatFromFraction( res, R.fraction.config_key_preview_dismiss_end_scale)); mDisplayOrientation = res.getConfiguration().orientation; - mAppWorkarounds = new AsyncResultHolder<AppWorkaroundsUtils>(); + mAppWorkarounds = new AsyncResultHolder<>(); final PackageInfo packageInfo = TargetPackageInfoGetterTask.getCachedPackageInfo( mInputAttributes.mTargetApplicationPackageName); if (null != packageInfo) { @@ -188,10 +190,11 @@ public final class SettingsValues { public boolean isSuggestionsRequested() { return mInputAttributes.mIsSettingsSuggestionStripOn - && (mCorrectionEnabled || isSuggestionStripVisible()); + && (mCorrectionEnabled + || isCurrentOrientationAllowingSuggestionsPerUserSettings()); } - public boolean isSuggestionStripVisible() { + public boolean isCurrentOrientationAllowingSuggestionsPerUserSettings() { return (mSuggestionVisibility == SUGGESTION_VISIBILITY_SHOW_VALUE) || (mSuggestionVisibility == SUGGESTION_VISIBILITY_SHOW_ONLY_PORTRAIT_VALUE && mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT); diff --git a/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java b/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java index 974dfddd3..73d25f6aa 100644 --- a/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java +++ b/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java @@ -21,13 +21,13 @@ import android.content.res.ColorStateList; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; +import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; -import com.android.inputmethod.compat.ViewCompatUtils; import com.android.inputmethod.latin.R; public final class SetupStartIndicatorView extends LinearLayout { @@ -96,13 +96,13 @@ public final class SetupStartIndicatorView extends LinearLayout { @Override protected void onDraw(final Canvas canvas) { super.onDraw(canvas); - final int layoutDirection = ViewCompatUtils.getLayoutDirection(this); + final int layoutDirection = ViewCompat.getLayoutDirection(this); final int width = getWidth(); final int height = getHeight(); final float halfHeight = height / 2.0f; final Path path = mIndicatorPath; path.rewind(); - if (layoutDirection == ViewCompatUtils.LAYOUT_DIRECTION_RTL) { + if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL) { // Left arrow path.moveTo(width, 0.0f); path.lineTo(0.0f, halfHeight); diff --git a/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java b/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java index c909507c6..6734e61b8 100644 --- a/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java +++ b/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java @@ -20,10 +20,10 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; +import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.view.View; -import com.android.inputmethod.compat.ViewCompatUtils; import com.android.inputmethod.latin.R; public final class SetupStepIndicatorView extends View { @@ -38,12 +38,12 @@ public final class SetupStepIndicatorView extends View { } public void setIndicatorPosition(final int stepPos, final int totalStepNum) { - final int layoutDirection = ViewCompatUtils.getLayoutDirection(this); + final int layoutDirection = ViewCompat.getLayoutDirection(this); // The indicator position is the center of the partition that is equally divided into // the total step number. final float partionWidth = 1.0f / totalStepNum; final float pos = stepPos * partionWidth + partionWidth / 2.0f; - mXRatio = (layoutDirection == ViewCompatUtils.LAYOUT_DIRECTION_RTL) ? 1.0f - pos : pos; + mXRatio = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL) ? 1.0f - pos : pos; invalidate(); } diff --git a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java index 5072fabd6..bcac05a6a 100644 --- a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java +++ b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java @@ -37,7 +37,6 @@ import com.android.inputmethod.compat.TextViewCompatUtils; import com.android.inputmethod.compat.ViewCompatUtils; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.settings.SettingsActivity; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper; import java.util.ArrayList; @@ -482,7 +481,7 @@ public final class SetupWizardActivity extends Activity implements View.OnClickL static final class SetupStepGroup { private final SetupStepIndicatorView mIndicatorView; - private final ArrayList<SetupStep> mGroup = CollectionUtils.newArrayList(); + private final ArrayList<SetupStep> mGroup = new ArrayList<>(); public SetupStepGroup(final SetupStepIndicatorView indicatorView) { mIndicatorView = indicatorView; diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index 65ebcf5f1..8d495646d 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -27,7 +27,6 @@ import android.view.inputmethod.InputMethodSubtype; import android.view.textservice.SuggestionsInfo; import com.android.inputmethod.keyboard.KeyboardLayoutSet; -import com.android.inputmethod.latin.BinaryDictionary; import com.android.inputmethod.latin.ContactsBinaryDictionary; import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.DictionaryCollection; @@ -77,7 +76,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService private final Object mUseContactsLock = new Object(); private final HashSet<WeakReference<DictionaryCollection>> mDictionaryCollectionsList = - CollectionUtils.newHashSet(); + new HashSet<>(); public static final int SCRIPT_LATIN = 0; public static final int SCRIPT_CYRILLIC = 1; @@ -94,7 +93,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService // proximity to pass to the dictionary descent algorithm. // IMPORTANT: this only contains languages - do not write countries in there. // Only the language is searched from the map. - mLanguageToScript = CollectionUtils.newTreeMap(); + mLanguageToScript = new TreeMap<>(); mLanguageToScript.put("cs", SCRIPT_LATIN); mLanguageToScript.put("da", SCRIPT_LATIN); mLanguageToScript.put("de", SCRIPT_LATIN); @@ -255,7 +254,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService mOriginalText = originalText; mRecommendedThreshold = recommendedThreshold; mMaxLength = maxLength; - mSuggestions = CollectionUtils.newArrayList(maxLength + 1); + mSuggestions = new ArrayList<>(maxLength + 1); mScores = new int[mMaxLength]; } @@ -441,8 +440,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService } } dictionaryCollection.addDictionary(mContactsDictionary); - mDictionaryCollectionsList.add( - new WeakReference<DictionaryCollection>(dictionaryCollection)); + mDictionaryCollectionsList.add(new WeakReference<>(dictionaryCollection)); } return new DictAndKeyboard(dictionaryCollection, keyboardLayoutSet); } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java index e951f5a89..cc80e6f21 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java @@ -24,7 +24,6 @@ import android.view.textservice.SuggestionsInfo; import android.view.textservice.TextInfo; import com.android.inputmethod.latin.PrevWordsInfo; -import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.ArrayList; @@ -44,10 +43,9 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck return null; } final int N = ssi.getSuggestionsCount(); - final ArrayList<Integer> additionalOffsets = CollectionUtils.newArrayList(); - final ArrayList<Integer> additionalLengths = CollectionUtils.newArrayList(); - final ArrayList<SuggestionsInfo> additionalSuggestionsInfos = - CollectionUtils.newArrayList(); + final ArrayList<Integer> additionalOffsets = new ArrayList<>(); + final ArrayList<Integer> additionalLengths = new ArrayList<>(); + final ArrayList<SuggestionsInfo> additionalSuggestionsInfos = new ArrayList<>(); String currentWord = null; for (int i = 0; i < N; ++i) { final SuggestionsInfo si = ssi.getSuggestionsInfoAt(i); diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java index cf26000d5..d7953e6e7 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java @@ -28,7 +28,6 @@ import android.view.textservice.SuggestionsInfo; import android.view.textservice.TextInfo; import com.android.inputmethod.compat.SuggestionsInfoCompatUtils; -import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.PrevWordsInfo; @@ -69,7 +68,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { private static final char CHAR_DELIMITER = '\uFFFC'; private static final int MAX_CACHE_SIZE = 50; private final LruCache<String, SuggestionsParams> mUnigramSuggestionsInfoCache = - new LruCache<String, SuggestionsParams>(MAX_CACHE_SIZE); + new LruCache<>(MAX_CACHE_SIZE); // TODO: Support n-gram input private static String generateKey(final String query, final PrevWordsInfo prevWordsInfo) { diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java b/java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java index 1ffe50681..b33739fc1 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java @@ -16,11 +16,11 @@ package com.android.inputmethod.latin.spellcheck; -import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.KeyboardLayoutSet; import com.android.inputmethod.keyboard.ProximityInfo; +import com.android.inputmethod.latin.Dictionary; /** * A container for a Dictionary and a Keyboard. @@ -28,19 +28,15 @@ import com.android.inputmethod.keyboard.ProximityInfo; public final class DictAndKeyboard { public final Dictionary mDictionary; public final Keyboard mKeyboard; - private final Keyboard mManualShiftedKeyboard; public DictAndKeyboard( final Dictionary dictionary, final KeyboardLayoutSet keyboardLayoutSet) { mDictionary = dictionary; if (keyboardLayoutSet == null) { mKeyboard = null; - mManualShiftedKeyboard = null; return; } mKeyboard = keyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET); - mManualShiftedKeyboard = - keyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED); } public ProximityInfo getProximityInfo() { diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java index ba2e0c309..1331d52d5 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java @@ -23,7 +23,6 @@ import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.WordComposer; -import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.ArrayList; import java.util.Locale; @@ -47,7 +46,7 @@ public final class DictionaryPool extends LinkedBlockingQueue<DictAndKeyboard> { private final Locale mLocale; private int mSize; private volatile boolean mClosed; - final static ArrayList<SuggestedWordInfo> noSuggestions = CollectionUtils.newArrayList(); + final static ArrayList<SuggestedWordInfo> noSuggestions = new ArrayList<>(); private final static DictAndKeyboard dummyDict = new DictAndKeyboard( new Dictionary(Dictionary.TYPE_MAIN) { // TODO: this dummy dictionary should be a singleton in the Dictionary class. diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java index e90b15ca5..346aea34a 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java +++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java @@ -23,23 +23,17 @@ import android.graphics.drawable.Drawable; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; -import com.android.inputmethod.keyboard.KeyboardActionListener; import com.android.inputmethod.keyboard.internal.KeyboardBuilder; import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; import com.android.inputmethod.keyboard.internal.KeyboardParams; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SuggestedWords; -import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.utils.TypefaceUtils; public final class MoreSuggestions extends Keyboard { public final SuggestedWords mSuggestedWords; - public static abstract class MoreSuggestionsListener extends KeyboardActionListener.Adapter { - public abstract void onSuggestionSelected(final int index, final SuggestedWordInfo info); - } - MoreSuggestions(final MoreSuggestionsParam params, final SuggestedWords suggestedWords) { super(params); mSuggestedWords = suggestedWords; diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java index 7fd64c4bf..aa59db678 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java @@ -22,11 +22,12 @@ import android.util.Log; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.keyboard.KeyboardActionListener; import com.android.inputmethod.keyboard.MoreKeysKeyboardView; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SuggestedWords; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestionKey; -import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestionsListener; /** * A view that renders a virtual {@link MoreSuggestions}. It handles rendering of keys and detecting @@ -35,6 +36,10 @@ import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestions public final class MoreSuggestionsView extends MoreKeysKeyboardView { private static final String TAG = MoreSuggestionsView.class.getSimpleName(); + public static abstract class MoreSuggestionsListener extends KeyboardActionListener.Adapter { + public abstract void onSuggestionSelected(final int index, final SuggestedWordInfo info); + } + public MoreSuggestionsView(final Context context, final AttributeSet attrs) { this(context, attrs, R.attr.moreKeysKeyboardViewStyle); } diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java index 619804afa..c400f66c8 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java @@ -49,8 +49,7 @@ import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.settings.Settings; -import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestionsListener; -import com.android.inputmethod.latin.utils.CollectionUtils; +import com.android.inputmethod.latin.suggestions.MoreSuggestionsView.MoreSuggestionsListener; import com.android.inputmethod.latin.utils.ImportantNoticeUtils; import com.android.inputmethod.research.ResearchLogger; @@ -78,9 +77,9 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick private final MoreSuggestionsView mMoreSuggestionsView; private final MoreSuggestions.Builder mMoreSuggestionsBuilder; - private final ArrayList<TextView> mWordViews = CollectionUtils.newArrayList(); - private final ArrayList<TextView> mDebugInfoViews = CollectionUtils.newArrayList(); - private final ArrayList<View> mDividerViews = CollectionUtils.newArrayList(); + private final ArrayList<TextView> mWordViews = new ArrayList<>(); + private final ArrayList<TextView> mDebugInfoViews = new ArrayList<>(); + private final ArrayList<View> mDividerViews = new ArrayList<>(); Listener mListener; private SuggestedWords mSuggestedWords = SuggestedWords.EMPTY; @@ -90,13 +89,16 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick private final StripVisibilityGroup mStripVisibilityGroup; private static class StripVisibilityGroup { + private final View mSuggestionStripView; private final View mSuggestionsStrip; private final View mVoiceKey; private final View mAddToDictionaryStrip; private final View mImportantNoticeStrip; - public StripVisibilityGroup(final View suggestionsStrip, final View voiceKey, - final View addToDictionaryStrip, final View importantNoticeStrip) { + public StripVisibilityGroup(final View suggestionStripView, + final ViewGroup suggestionsStrip, final ImageButton voiceKey, + final ViewGroup addToDictionaryStrip, final View importantNoticeStrip) { + mSuggestionStripView = suggestionStripView; mSuggestionsStrip = suggestionsStrip; mVoiceKey = voiceKey; mAddToDictionaryStrip = addToDictionaryStrip; @@ -104,7 +106,10 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick showSuggestionsStrip(false /* voiceKeyEnabled */); } - public void setLayoutDirection(final int layoutDirection) { + public void setLayoutDirection(final boolean isRtlLanguage) { + final int layoutDirection = isRtlLanguage ? ViewCompat.LAYOUT_DIRECTION_RTL + : ViewCompat.LAYOUT_DIRECTION_LTR; + ViewCompat.setLayoutDirection(mSuggestionStripView, layoutDirection); ViewCompat.setLayoutDirection(mSuggestionsStrip, layoutDirection); ViewCompat.setLayoutDirection(mAddToDictionaryStrip, layoutDirection); ViewCompat.setLayoutDirection(mImportantNoticeStrip, layoutDirection); @@ -156,7 +161,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick mVoiceKey = (ImageButton)findViewById(R.id.suggestions_strip_voice_key); mAddToDictionaryStrip = (ViewGroup)findViewById(R.id.add_to_dictionary_strip); mImportantNoticeStrip = findViewById(R.id.important_notice_strip); - mStripVisibilityGroup = new StripVisibilityGroup(mSuggestionsStrip, mVoiceKey, + mStripVisibilityGroup = new StripVisibilityGroup(this, mSuggestionsStrip, mVoiceKey, mAddToDictionaryStrip, mImportantNoticeStrip); for (int pos = 0; pos < SuggestedWords.MAX_SUGGESTIONS; pos++) { @@ -217,10 +222,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick public void setSuggestions(final SuggestedWords suggestedWords, final boolean isRtlLanguage) { clear(); - final int layoutDirection = isRtlLanguage ? ViewCompat.LAYOUT_DIRECTION_RTL - : ViewCompat.LAYOUT_DIRECTION_LTR; - setLayoutDirection(layoutDirection); - mStripVisibilityGroup.setLayoutDirection(layoutDirection); + mStripVisibilityGroup.setLayoutDirection(isRtlLanguage); mSuggestedWords = suggestedWords; mSuggestionsCountInStrip = mLayoutHelper.layoutAndReturnSuggestionCountInStrip( mSuggestedWords, mSuggestionsStrip, this); diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java index 21426d1eb..80d4cc44f 100644 --- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java +++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java @@ -256,7 +256,7 @@ public class UserDictionaryAddWordContents { // The system locale should be inside. We want it at the 2nd spot. locales.remove(systemLocale); // system locale may not be null locales.remove(""); // Remove the empty string if it's there - final ArrayList<LocaleRenderer> localesList = new ArrayList<LocaleRenderer>(); + final ArrayList<LocaleRenderer> localesList = new ArrayList<>(); // Add the passed locale, then the system locale at the top of the list. Add an // "all languages" entry at the bottom of the list. addLocaleDisplayNameToList(activity, localesList, mLocale); diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java index 4fc132f68..163443036 100644 --- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java +++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java @@ -134,8 +134,8 @@ public class UserDictionaryAddWordFragment extends Fragment final Spinner localeSpinner = (Spinner)mRootView.findViewById(R.id.user_dictionary_add_locale); - final ArrayAdapter<LocaleRenderer> adapter = new ArrayAdapter<LocaleRenderer>(getActivity(), - android.R.layout.simple_spinner_item, localesList); + final ArrayAdapter<LocaleRenderer> adapter = new ArrayAdapter<>( + getActivity(), android.R.layout.simple_spinner_item, localesList); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); localeSpinner.setAdapter(adapter); localeSpinner.setOnItemSelectedListener(this); diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java index 97a924d7b..624783a70 100644 --- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java +++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java @@ -56,7 +56,7 @@ public class UserDictionaryList extends PreferenceFragment { final Cursor cursor = activity.getContentResolver().query(UserDictionary.Words.CONTENT_URI, new String[] { UserDictionary.Words.LOCALE }, null, null, null); - final TreeSet<String> localeSet = new TreeSet<String>(); + final TreeSet<String> localeSet = new TreeSet<>(); if (null == cursor) { // The user dictionary service is not present or disabled. Return null. return null; diff --git a/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java index 2bb30a2ba..3ca7c7e1c 100644 --- a/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java @@ -95,8 +95,7 @@ public final class AdditionalSubtypeUtils { return EMPTY_SUBTYPE_ARRAY; } final String[] prefSubtypeArray = prefSubtypes.split(PREF_SUBTYPE_SEPARATOR); - final ArrayList<InputMethodSubtype> subtypesList = - CollectionUtils.newArrayList(prefSubtypeArray.length); + final ArrayList<InputMethodSubtype> subtypesList = new ArrayList<>(prefSubtypeArray.length); for (final String prefSubtype : prefSubtypeArray) { final String elems[] = prefSubtype.split(LOCALE_AND_LAYOUT_SEPARATOR); if (elems.length != LENGTH_WITHOUT_EXTRA_VALUE diff --git a/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java b/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java index 22b9b77d2..857d0b0da 100644 --- a/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java @@ -16,12 +16,11 @@ package com.android.inputmethod.latin.utils; -import com.android.inputmethod.latin.BinaryDictionary; +import android.util.Log; + import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; -import android.util.Log; - public final class AutoCorrectionUtils { private static final boolean DBG = LatinImeLogger.sDBG; private static final String TAG = AutoCorrectionUtils.class.getSimpleName(); diff --git a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java index 702688f93..936219332 100644 --- a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java @@ -62,6 +62,22 @@ public final class CapsModeUtils { } /** + * Helper method to find out if a code point is starting punctuation. + * + * This include the Unicode START_PUNCTUATION category, but also some other symbols that are + * starting, like the inverted question mark or the double quote. + * + * @param codePoint the code point + * @return true if it's starting punctuation, false otherwise. + */ + private static boolean isStartPunctuation(final int codePoint) { + return (codePoint == Constants.CODE_DOUBLE_QUOTE || codePoint == Constants.CODE_SINGLE_QUOTE + || codePoint == Constants.CODE_INVERTED_QUESTION_MARK + || codePoint == Constants.CODE_INVERTED_EXCLAMATION_MARK + || Character.getType(codePoint) == Character.START_PUNCTUATION); + } + + /** * Determine what caps mode should be in effect at the current offset in * the text. Only the mode bits set in <var>reqModes</var> will be * checked. Note that the caps mode flags here are explicitly defined @@ -115,8 +131,7 @@ public final class CapsModeUtils { } else { for (i = cs.length(); i > 0; i--) { final char c = cs.charAt(i - 1); - if (c != Constants.CODE_DOUBLE_QUOTE && c != Constants.CODE_SINGLE_QUOTE - && Character.getType(c) != Character.START_PUNCTUATION) { + if (!isStartPunctuation(c)) { break; } } @@ -210,11 +225,14 @@ public final class CapsModeUtils { // We found out that we have a period. We need to determine if this is a full stop or // otherwise sentence-ending period, or an abbreviation like "e.g.". An abbreviation - // looks like (\w\.){2,} + // looks like (\w\.){2,}. Moreover, in German, you put periods after digits for dates + // and some other things, and in German specifically we need to not go into autocaps after + // a whitespace-digits-period sequence. // To find out, we will have a simple state machine with the following states : - // START, WORD, PERIOD, ABBREVIATION + // START, WORD, PERIOD, ABBREVIATION, NUMBER // On START : (just before the first period) // letter => WORD + // digit => NUMBER if German; end with caps otherwise // whitespace => end with no caps (it was a stand-alone period) // otherwise => end with caps (several periods/symbols in a row) // On WORD : (within the word just before the first period) @@ -228,6 +246,11 @@ public final class CapsModeUtils { // letter => LETTER // period => PERIOD // otherwise => end with no caps (it was an abbreviation) + // On NUMBER : (period immediately preceded by one or more digits) + // digit => NUMBER + // letter => LETTER (promote to word) + // otherwise => end with no caps (it was a whitespace-digits-period sequence, + // or a punctuation-digits-period sequence like "11.11.") // "Not an abbreviation" in the above chart essentially covers cases like "...yes.". This // should capitalize. @@ -235,6 +258,7 @@ public final class CapsModeUtils { final int WORD = 1; final int PERIOD = 2; final int LETTER = 3; + final int NUMBER = 4; final int caps = (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS | TextUtils.CAP_MODE_SENTENCES) & reqModes; final int noCaps = (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS) & reqModes; @@ -247,6 +271,8 @@ public final class CapsModeUtils { state = WORD; } else if (Character.isWhitespace(c)) { return noCaps; + } else if (Character.isDigit(c) && spacingAndPunctuations.mUsesGermanRules) { + state = NUMBER; } else { return caps; } @@ -275,6 +301,15 @@ public final class CapsModeUtils { } else { return noCaps; } + break; + case NUMBER: + if (Character.isLetter(c)) { + state = WORD; + } else if (Character.isDigit(c)) { + state = NUMBER; + } else { + return noCaps; + } } } // Here we arrived at the start of the line. This should behave exactly like whitespace. diff --git a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java index bbfa0f091..e3aef29ba 100644 --- a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java @@ -16,93 +16,21 @@ package com.android.inputmethod.latin.utils; -import android.util.SparseArray; - -import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; import java.util.Map; import java.util.TreeMap; -import java.util.TreeSet; -import java.util.WeakHashMap; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; public final class CollectionUtils { private CollectionUtils() { // This utility class is not publicly instantiable. } - public static <K,V> HashMap<K,V> newHashMap() { - return new HashMap<K,V>(); - } - - public static <K, V> WeakHashMap<K, V> newWeakHashMap() { - return new WeakHashMap<K, V>(); - } - - public static <K,V> TreeMap<K,V> newTreeMap() { - return new TreeMap<K,V>(); - } - public static <K, V> Map<K,V> newSynchronizedTreeMap() { - final TreeMap<K,V> treeMap = newTreeMap(); + final TreeMap<K,V> treeMap = new TreeMap<>(); return Collections.synchronizedMap(treeMap); } - public static <K,V> ConcurrentHashMap<K,V> newConcurrentHashMap() { - return new ConcurrentHashMap<K,V>(); - } - - public static <E> HashSet<E> newHashSet() { - return new HashSet<E>(); - } - - public static <E> TreeSet<E> newTreeSet() { - return new TreeSet<E>(); - } - - public static <E> ArrayList<E> newArrayList() { - return new ArrayList<E>(); - } - - public static <E> ArrayList<E> newArrayList(final int initialCapacity) { - return new ArrayList<E>(initialCapacity); - } - - public static <E> ArrayList<E> newArrayList(final Collection<E> collection) { - return new ArrayList<E>(collection); - } - - public static <E> LinkedList<E> newLinkedList() { - return new LinkedList<E>(); - } - - public static <E> CopyOnWriteArrayList<E> newCopyOnWriteArrayList() { - return new CopyOnWriteArrayList<E>(); - } - - public static <E> CopyOnWriteArrayList<E> newCopyOnWriteArrayList( - final Collection<E> collection) { - return new CopyOnWriteArrayList<E>(collection); - } - - public static <E> CopyOnWriteArrayList<E> newCopyOnWriteArrayList(final E[] array) { - return new CopyOnWriteArrayList<E>(array); - } - - public static <E> ArrayDeque<E> newArrayDeque() { - return new ArrayDeque<E>(); - } - - public static <E> SparseArray<E> newSparseArray() { - return new SparseArray<E>(); - } - public static <E> ArrayList<E> arrayAsList(final E[] array, final int start, final int end) { if (array == null) { throw new NullPointerException(); @@ -111,7 +39,7 @@ public final class CollectionUtils { throw new IllegalArgumentException(); } - final ArrayList<E> list = newArrayList(end - start); + final ArrayList<E> list = new ArrayList<>(end - start); for (int i = start; i < end; i++) { list.add(array[i]); } diff --git a/java/src/com/android/inputmethod/latin/utils/CsvUtils.java b/java/src/com/android/inputmethod/latin/utils/CsvUtils.java index b18a1d83b..a21a1373b 100644 --- a/java/src/com/android/inputmethod/latin/utils/CsvUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/CsvUtils.java @@ -209,7 +209,7 @@ public final class CsvUtils { @UsedForTesting public static String[] split(final int splitFlags, final String line) throws CsvParseException { final boolean trimSpaces = (splitFlags & SPLIT_FLAGS_TRIM_SPACES) != 0; - final ArrayList<String> fields = CollectionUtils.newArrayList(); + final ArrayList<String> fields = new ArrayList<>(); final int length = line.length(); int start = 0; do { diff --git a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java index 315913e2f..d76ea10c0 100644 --- a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java @@ -336,7 +336,7 @@ public class DictionaryInfoUtils { public static ArrayList<DictionaryInfo> getCurrentDictionaryFileNameAndVersionInfo( final Context context) { - final ArrayList<DictionaryInfo> dictList = CollectionUtils.newArrayList(); + final ArrayList<DictionaryInfo> dictList = new ArrayList<>(); // Retrieve downloaded dictionaries final File[] directoryList = getCachedDirectoryList(context); diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java index f1057da0b..787e4a59d 100644 --- a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java +++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java @@ -16,129 +16,14 @@ package com.android.inputmethod.latin.utils; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Locale; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import android.content.Context; -import android.content.res.Resources; -import android.text.InputType; -import android.util.Log; -import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodSubtype; -import com.android.inputmethod.keyboard.Keyboard; -import com.android.inputmethod.keyboard.KeyboardId; -import com.android.inputmethod.keyboard.KeyboardLayoutSet; -import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.PrevWordsInfo; -import com.android.inputmethod.latin.Suggest; -import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback; -import com.android.inputmethod.latin.SuggestedWords; -import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; -import com.android.inputmethod.latin.WordComposer; - -/** - * This class is used to prevent distracters being added to personalization - * or user history dictionaries - */ -public class DistracterFilter { - private static final String TAG = DistracterFilter.class.getSimpleName(); - - private static final long TIMEOUT_TO_WAIT_LOADING_DICTIONARIES_IN_SECONDS = 120; - - private final Context mContext; - private final Map<Locale, InputMethodSubtype> mLocaleToSubtypeMap; - private final Map<Locale, Keyboard> mLocaleToKeyboardMap; - private final Suggest mSuggest; - private Keyboard mKeyboard; - - // If the score of the top suggestion exceeds this value, the tested word (e.g., - // an OOV, a misspelling, or an in-vocabulary word) would be considered as a distracter to - // words in dictionary. The greater the threshold is, the less likely the tested word would - // become a distracter, which means the tested word will be more likely to be added to - // the dictionary. - private static final float DISTRACTER_WORD_SCORE_THRESHOLD = 2.0f; - - // Create empty distracter filter. - public DistracterFilter() { - this(null, new ArrayList<InputMethodSubtype>()); - } - - /** - * Create a DistracterFilter instance. - * - * @param context the context. - * @param enabledSubtypes the enabled subtypes. - */ - public DistracterFilter(final Context context, final List<InputMethodSubtype> enabledSubtypes) { - mContext = context; - mLocaleToSubtypeMap = new HashMap<>(); - if (enabledSubtypes != null) { - for (final InputMethodSubtype subtype : enabledSubtypes) { - final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype); - if (mLocaleToSubtypeMap.containsKey(locale)) { - // Multiple subtypes are enabled for one locale. - // TODO: Investigate what we should do for this case. - continue; - } - mLocaleToSubtypeMap.put(locale, subtype); - } - } - mLocaleToKeyboardMap = new HashMap<>(); - mSuggest = new Suggest(); - mKeyboard = null; - } - - private static boolean suggestionExceedsDistracterThreshold( - final SuggestedWordInfo suggestion, final String consideredWord, - final float distracterThreshold) { - if (null != suggestion) { - final int suggestionScore = suggestion.mScore; - final float normalizedScore = BinaryDictionaryUtils.calcNormalizedScore( - consideredWord, suggestion.mWord, suggestionScore); - if (normalizedScore > distracterThreshold) { - return true; - } - } - return false; - } - - private void loadKeyboardForLocale(final Locale newLocale) { - final Keyboard cachedKeyboard = mLocaleToKeyboardMap.get(newLocale); - if (cachedKeyboard != null) { - mKeyboard = cachedKeyboard; - return; - } - final InputMethodSubtype subtype = mLocaleToSubtypeMap.get(newLocale); - if (subtype == null) { - return; - } - final EditorInfo editorInfo = new EditorInfo(); - editorInfo.inputType = InputType.TYPE_CLASS_TEXT; - final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder( - mContext, editorInfo); - final Resources res = mContext.getResources(); - final int keyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res); - final int keyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res); - builder.setKeyboardGeometry(keyboardWidth, keyboardHeight); - builder.setSubtype(subtype); - builder.setIsSpellChecker(false /* isSpellChecker */); - final KeyboardLayoutSet layoutSet = builder.build(); - mKeyboard = layoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET); - } - - private void loadDictionariesForLocale(final Locale newlocale) throws InterruptedException { - mSuggest.mDictionaryFacilitator.resetDictionaries(mContext, newlocale, - false /* useContactsDict */, false /* usePersonalizedDicts */, - false /* forceReloadMainDictionary */, null /* listener */); - mSuggest.mDictionaryFacilitator.waitForLoadingMainDictionary( - TIMEOUT_TO_WAIT_LOADING_DICTIONARIES_IN_SECONDS, TimeUnit.SECONDS); - } +public interface DistracterFilter { /** * Determine whether a word is a distracter to words in dictionaries. * @@ -149,56 +34,25 @@ public class DistracterFilter { * @return true if testedWord is a distracter, otherwise false. */ public boolean isDistracterToWordsInDictionaries(final PrevWordsInfo prevWordsInfo, - final String testedWord, final Locale locale) { - if (locale == null) { - return false; - } - if (!locale.equals(mSuggest.mDictionaryFacilitator.getLocale())) { - if (!mLocaleToSubtypeMap.containsKey(locale)) { - Log.e(TAG, "Locale " + locale + " is not enabled."); - // TODO: Investigate what we should do for disabled locales. - return false; - } - loadKeyboardForLocale(locale); - // Reset dictionaries for the locale. - try { - loadDictionariesForLocale(locale); - } catch (final InterruptedException e) { - Log.e(TAG, "Interrupted while waiting for loading dicts in DistracterFilter", e); - return false; - } - } - if (mKeyboard == null) { + final String testedWord, final Locale locale); + + public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes); + + public void close(); + + public static final DistracterFilter EMPTY_DISTRACTER_FILTER = new DistracterFilter() { + @Override + public boolean isDistracterToWordsInDictionaries(PrevWordsInfo prevWordsInfo, + String testedWord, Locale locale) { return false; } - final WordComposer composer = new WordComposer(); - final int[] codePoints = StringUtils.toCodePointArray(testedWord); - final int[] coordinates = mKeyboard.getCoordinates(codePoints); - composer.setComposingWord(codePoints, coordinates, prevWordsInfo); - final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(testedWord); - final String consideredWord = trailingSingleQuotesCount > 0 ? - testedWord.substring(0, testedWord.length() - trailingSingleQuotesCount) : - testedWord; - final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>(); - final OnGetSuggestedWordsCallback callback = new OnGetSuggestedWordsCallback() { - @Override - public void onGetSuggestedWords(final SuggestedWords suggestedWords) { - if (suggestedWords != null && suggestedWords.size() > 1) { - // The suggestedWordInfo at 0 is the typed word. The 1st suggestion from - // the decoder is at index 1. - final SuggestedWordInfo firstSuggestion = suggestedWords.getInfo(1); - final boolean hasStrongDistractor = suggestionExceedsDistracterThreshold( - firstSuggestion, consideredWord, DISTRACTER_WORD_SCORE_THRESHOLD); - holder.set(hasStrongDistractor); - } - } - }; - mSuggest.getSuggestedWords(composer, prevWordsInfo, mKeyboard.getProximityInfo(), - true /* blockOffensiveWords */, true /* isCorrectionEnbaled */, - null /* additionalFeaturesOptions */, 0 /* sessionId */, - SuggestedWords.NOT_A_SEQUENCE_NUMBER, callback); + @Override + public void close() { + } - return holder.get(false /* defaultValue */, Constants.GET_SUGGESTED_WORDS_TIMEOUT); - } + @Override + public void updateEnabledSubtypes(List<InputMethodSubtype> enabledSubtypes) { + } + }; } diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterUsingSuggestion.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterUsingSuggestion.java new file mode 100644 index 000000000..ac0ab28bf --- /dev/null +++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterUsingSuggestion.java @@ -0,0 +1,244 @@ +/* + * 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.latin.utils; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import android.content.Context; +import android.content.res.Resources; +import android.text.InputType; +import android.util.Log; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.KeyboardLayoutSet; +import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.Dictionary; +import com.android.inputmethod.latin.DictionaryFacilitator; +import com.android.inputmethod.latin.PrevWordsInfo; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; +import com.android.inputmethod.latin.WordComposer; + +/** + * This class is used to prevent distracters being added to personalization + * or user history dictionaries + */ +public class DistracterFilterUsingSuggestion implements DistracterFilter { + private static final String TAG = DistracterFilterUsingSuggestion.class.getSimpleName(); + private static final boolean DEBUG = false; + + private static final long TIMEOUT_TO_WAIT_LOADING_DICTIONARIES_IN_SECONDS = 120; + + private final Context mContext; + private final Map<Locale, InputMethodSubtype> mLocaleToSubtypeMap; + private final Map<Locale, Keyboard> mLocaleToKeyboardMap; + private final DictionaryFacilitator mDictionaryFacilitator; + private Keyboard mKeyboard; + private final Object mLock = new Object(); + + /** + * Create a DistracterFilter instance. + * + * @param context the context. + */ + public DistracterFilterUsingSuggestion(final Context context) { + mContext = context; + mLocaleToSubtypeMap = new HashMap<>(); + mLocaleToKeyboardMap = new HashMap<>(); + mDictionaryFacilitator = new DictionaryFacilitator(); + mKeyboard = null; + } + + @Override + public void close() { + mDictionaryFacilitator.closeDictionaries(); + } + + @Override + public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes) { + final Map<Locale, InputMethodSubtype> newLocaleToSubtypeMap = new HashMap<>(); + if (enabledSubtypes != null) { + for (final InputMethodSubtype subtype : enabledSubtypes) { + final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype); + if (newLocaleToSubtypeMap.containsKey(locale)) { + // Multiple subtypes are enabled for one locale. + // TODO: Investigate what we should do for this case. + continue; + } + newLocaleToSubtypeMap.put(locale, subtype); + } + } + if (mLocaleToSubtypeMap.equals(newLocaleToSubtypeMap)) { + // Enabled subtypes have not been changed. + return; + } + synchronized (mLock) { + mLocaleToSubtypeMap.clear(); + mLocaleToSubtypeMap.putAll(newLocaleToSubtypeMap); + mLocaleToKeyboardMap.clear(); + } + } + + private boolean isDistracter( + final SuggestionResults suggestionResults, final String consideredWord) { + int perfectMatchProbability = Dictionary.NOT_A_PROBABILITY; + for (final SuggestedWordInfo suggestedWordInfo : suggestionResults) { + if (suggestedWordInfo.mWord.equals(consideredWord)) { + perfectMatchProbability = mDictionaryFacilitator.getFrequency(consideredWord); + continue; + } + // Exact match can include case errors, accent errors, digraph conversions. + final boolean isExactMatch = + (suggestedWordInfo.mKind & SuggestedWordInfo.KIND_FLAG_EXACT_MATCH) != 0; + final boolean isExactMatchWithIntentionalOmission = (suggestedWordInfo.mKind + & SuggestedWordInfo.KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION) != 0; + + if (DEBUG) { + final float normalizedScore = BinaryDictionaryUtils.calcNormalizedScore( + consideredWord, suggestedWordInfo.mWord, suggestedWordInfo.mScore); + Log.d(TAG, "consideredWord: " + consideredWord); + Log.d(TAG, "top suggestion: " + suggestedWordInfo.mWord); + Log.d(TAG, "suggestionScore: " + suggestedWordInfo.mScore); + Log.d(TAG, "normalizedScore: " + normalizedScore); + Log.d(TAG, "isExactMatch: " + isExactMatch); + Log.d(TAG, "isExactMatchWithIntentionalOmission: " + + isExactMatchWithIntentionalOmission); + } + if (perfectMatchProbability != Dictionary.NOT_A_PROBABILITY) { + final int topNonPerfectProbability = mDictionaryFacilitator.getFrequency( + suggestedWordInfo.mWord); + if (DEBUG) { + Log.d(TAG, "perfectMatchProbability: " + perfectMatchProbability); + Log.d(TAG, "topNonPerfectProbability: " + topNonPerfectProbability); + } + if (perfectMatchProbability > topNonPerfectProbability) { + return false; + } + } + return isExactMatch || isExactMatchWithIntentionalOmission; + } + return false; + } + + private void loadKeyboardForLocale(final Locale newLocale) { + final Keyboard cachedKeyboard = mLocaleToKeyboardMap.get(newLocale); + if (cachedKeyboard != null) { + mKeyboard = cachedKeyboard; + return; + } + final InputMethodSubtype subtype; + synchronized (mLock) { + subtype = mLocaleToSubtypeMap.get(newLocale); + } + if (subtype == null) { + return; + } + final EditorInfo editorInfo = new EditorInfo(); + editorInfo.inputType = InputType.TYPE_CLASS_TEXT; + final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder( + mContext, editorInfo); + final Resources res = mContext.getResources(); + final int keyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res); + final int keyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res); + builder.setKeyboardGeometry(keyboardWidth, keyboardHeight); + builder.setSubtype(subtype); + builder.setIsSpellChecker(false /* isSpellChecker */); + final KeyboardLayoutSet layoutSet = builder.build(); + mKeyboard = layoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET); + } + + private void loadDictionariesForLocale(final Locale newlocale) throws InterruptedException { + mDictionaryFacilitator.resetDictionaries(mContext, newlocale, + false /* useContactsDict */, false /* usePersonalizedDicts */, + false /* forceReloadMainDictionary */, null /* listener */); + mDictionaryFacilitator.waitForLoadingMainDictionary( + TIMEOUT_TO_WAIT_LOADING_DICTIONARIES_IN_SECONDS, TimeUnit.SECONDS); + } + + /** + * Determine whether a word is a distracter to words in dictionaries. + * + * @param prevWordsInfo the information of previous words. Not used for now. + * @param testedWord the word that will be tested to see whether it is a distracter to words + * in dictionaries. + * @param locale the locale of word. + * @return true if testedWord is a distracter, otherwise false. + */ + @Override + public boolean isDistracterToWordsInDictionaries(final PrevWordsInfo prevWordsInfo, + final String testedWord, final Locale locale) { + if (locale == null) { + return false; + } + if (!locale.equals(mDictionaryFacilitator.getLocale())) { + synchronized (mLock) { + if (!mLocaleToSubtypeMap.containsKey(locale)) { + Log.e(TAG, "Locale " + locale + " is not enabled."); + // TODO: Investigate what we should do for disabled locales. + return false; + } + loadKeyboardForLocale(locale); + // Reset dictionaries for the locale. + try { + loadDictionariesForLocale(locale); + } catch (final InterruptedException e) { + Log.e(TAG, "Interrupted while waiting for loading dicts in DistracterFilter", + e); + return false; + } + } + } + if (mKeyboard == null) { + return false; + } + final WordComposer composer = new WordComposer(); + final int[] codePoints = StringUtils.toCodePointArray(testedWord); + final int[] coordinates = mKeyboard.getCoordinates(codePoints); + composer.setComposingWord(codePoints, coordinates, PrevWordsInfo.EMPTY_PREV_WORDS_INFO); + + final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(testedWord); + final String consideredWord = trailingSingleQuotesCount > 0 ? + testedWord.substring(0, testedWord.length() - trailingSingleQuotesCount) : + testedWord; + final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<>(); + ExecutorUtils.getExecutor("check distracters").execute(new Runnable() { + @Override + public void run() { + final SuggestionResults suggestionResults = + mDictionaryFacilitator.getSuggestionResults( + composer, PrevWordsInfo.EMPTY_PREV_WORDS_INFO, + mKeyboard.getProximityInfo(), true /* blockOffensiveWords */, + null /* additionalFeaturesOptions */, 0 /* sessionId */, + null /* rawSuggestions */); + if (suggestionResults.isEmpty()) { + holder.set(false); + return; + } + holder.set(isDistracter(suggestionResults, consideredWord)); + } + }); + // It's OK to block the distracter filtering, but the dictionary lookup should be done + // sequentially using ExecutorUtils. + return holder.get(false /* defaultValue */, Constants.GET_SUGGESTED_WORDS_TIMEOUT); + } +} diff --git a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java index ed502ed3d..c08697c4b 100644 --- a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java @@ -24,17 +24,18 @@ import java.util.concurrent.ConcurrentHashMap; * Utilities to manage executors. */ public class ExecutorUtils { - private static final ConcurrentHashMap<String, PrioritizedSerialExecutor> - sExecutorMap = CollectionUtils.newConcurrentHashMap(); + private static final ConcurrentHashMap<String, PrioritizedSerialExecutor> sExecutorMap = + new ConcurrentHashMap<>(); + /** - * Gets the executor for the given dictionary name. + * Gets the executor for the given id. */ - public static PrioritizedSerialExecutor getExecutor(final String dictName) { - PrioritizedSerialExecutor executor = sExecutorMap.get(dictName); + public static PrioritizedSerialExecutor getExecutor(final String id) { + PrioritizedSerialExecutor executor = sExecutorMap.get(id); if (executor == null) { synchronized(sExecutorMap) { - executor = new PrioritizedSerialExecutor(); - sExecutorMap.put(dictName, executor); + executor = new PrioritizedSerialExecutor(id); + sExecutorMap.put(id, executor); } } return executor; diff --git a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java index ee2b97b2a..149fbb31a 100644 --- a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java @@ -31,7 +31,7 @@ import com.android.inputmethod.research.FeedbackFragment; import java.util.HashSet; public class FragmentUtils { - private static final HashSet<String> sLatinImeFragments = new HashSet<String>(); + private static final HashSet<String> sLatinImeFragments = new HashSet<>(); static { sLatinImeFragments.add(DictionarySettingsFragment.class.getName()); sLatinImeFragments.add(AboutPreferences.class.getName()); diff --git a/java/src/com/android/inputmethod/latin/utils/JsonUtils.java b/java/src/com/android/inputmethod/latin/utils/JsonUtils.java index 764ef72ce..6dd8d9711 100644 --- a/java/src/com/android/inputmethod/latin/utils/JsonUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/JsonUtils.java @@ -37,7 +37,7 @@ public final class JsonUtils { private static final String EMPTY_STRING = ""; public static List<Object> jsonStrToList(final String s) { - final ArrayList<Object> list = CollectionUtils.newArrayList(); + final ArrayList<Object> list = new ArrayList<>(); final JsonReader reader = new JsonReader(new StringReader(s)); try { reader.beginArray(); diff --git a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java index aaf4a4064..4248bebf6 100644 --- a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java +++ b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java @@ -19,11 +19,12 @@ package com.android.inputmethod.latin.utils; import android.util.Log; import com.android.inputmethod.latin.Dictionary; -import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest; +import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import java.util.ArrayList; +import java.util.List; import java.util.Locale; // Note: this class is used as a parameter type of a native method. You should be careful when you @@ -79,14 +80,13 @@ public final class LanguageModelParam { // Process a list of words and return a list of {@link LanguageModelParam} objects. public static ArrayList<LanguageModelParam> createLanguageModelParamsFrom( - final ArrayList<String> tokens, final int timestamp, - final DictionaryFacilitatorForSuggest dictionaryFacilitator, + final List<String> tokens, final int timestamp, + final DictionaryFacilitator dictionaryFacilitator, final SpacingAndPunctuations spacingAndPunctuations, final DistracterFilter distracterFilter) { - final ArrayList<LanguageModelParam> languageModelParams = - CollectionUtils.newArrayList(); + final ArrayList<LanguageModelParam> languageModelParams = new ArrayList<>(); final int N = tokens.size(); - PrevWordsInfo prevWordsInfo = new PrevWordsInfo(null); + PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; for (int i = 0; i < N; ++i) { final String tempWord = tokens.get(i); if (StringUtils.isEmptyStringOrWhiteSpaces(tempWord)) { @@ -103,7 +103,7 @@ public final class LanguageModelParam { + tempWord + "\""); } // Sentence terminator found. Split. - prevWordsInfo = new PrevWordsInfo(null); + prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; continue; } if (DEBUG_TOKEN) { @@ -124,43 +124,33 @@ public final class LanguageModelParam { private static LanguageModelParam detectWhetherVaildWordOrNotAndGetLanguageModelParam( final PrevWordsInfo prevWordsInfo, final String targetWord, final int timestamp, - final DictionaryFacilitatorForSuggest dictionaryFacilitator, + final DictionaryFacilitator dictionaryFacilitator, final DistracterFilter distracterFilter) { final Locale locale = dictionaryFacilitator.getLocale(); if (locale == null) { return null; } - // TODO: Though targetWord is an IV (in-vocabulary) word, we should still apply - // distracterFilter in the following code. If targetWord is a distracter, - // it should be filtered out. if (dictionaryFacilitator.isValidWord(targetWord, false /* ignoreCase */)) { return createAndGetLanguageModelParamOfWord(prevWordsInfo, targetWord, timestamp, - true /* isValidWord */, locale); + true /* isValidWord */, locale, distracterFilter); } final String lowerCaseTargetWord = targetWord.toLowerCase(locale); if (dictionaryFacilitator.isValidWord(lowerCaseTargetWord, false /* ignoreCase */)) { // Add the lower-cased word. return createAndGetLanguageModelParamOfWord(prevWordsInfo, lowerCaseTargetWord, - timestamp, true /* isValidWord */, locale); + timestamp, true /* isValidWord */, locale, distracterFilter); } - // Treat the word as an OOV word. The following statement checks whether this OOV - // is a distracter to words in dictionaries. Being a distracter means the OOV word is - // too close to a common word in dictionaries (e.g., the OOV "mot" is very close to "not"). - // Adding such a word to dictonaries would interfere with entering in-dictionary words. For - // example, adding "mot" to dictionaries might interfere with entering "not". - // This kind of OOV should be filtered out. - if (distracterFilter.isDistracterToWordsInDictionaries(prevWordsInfo, targetWord, locale)) { - return null; - } + // Treat the word as an OOV word. return createAndGetLanguageModelParamOfWord(prevWordsInfo, targetWord, timestamp, - false /* isValidWord */, locale); + false /* isValidWord */, locale, distracterFilter); } private static LanguageModelParam createAndGetLanguageModelParamOfWord( final PrevWordsInfo prevWordsInfo, final String targetWord, final int timestamp, - final boolean isValidWord, final Locale locale) { + final boolean isValidWord, final Locale locale, + final DistracterFilter distracterFilter) { final String word; if (StringUtils.getCapitalizationType(targetWord) == StringUtils.CAPITALIZE_FIRST && prevWordsInfo.mPrevWord == null && !isValidWord) { @@ -168,6 +158,13 @@ public final class LanguageModelParam { } else { word = targetWord; } + // Check whether the word is a distracter to words in the dictionaries. + if (distracterFilter.isDistracterToWordsInDictionaries(prevWordsInfo, word, locale)) { + if (DEBUG) { + Log.d(TAG, "The word (" + word + ") is a distracter. Skip this word."); + } + return null; + } final int unigramProbability = isValidWord ? UNIGRAM_PROBABILITY_FOR_VALID_WORD : UNIGRAM_PROBABILITY_FOR_OOV_WORD; if (prevWordsInfo.mPrevWord == null) { diff --git a/java/src/com/android/inputmethod/latin/utils/LeakGuardHandlerWrapper.java b/java/src/com/android/inputmethod/latin/utils/LeakGuardHandlerWrapper.java index 8469c87b0..dd6fac671 100644 --- a/java/src/com/android/inputmethod/latin/utils/LeakGuardHandlerWrapper.java +++ b/java/src/com/android/inputmethod/latin/utils/LeakGuardHandlerWrapper.java @@ -33,7 +33,7 @@ public class LeakGuardHandlerWrapper<T> extends Handler { if (ownerInstance == null) { throw new NullPointerException("ownerInstance is null"); } - mOwnerInstanceRef = new WeakReference<T>(ownerInstance); + mOwnerInstanceRef = new WeakReference<>(ownerInstance); } public T getOwnerInstance() { diff --git a/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java index 0c55484b4..c519a0de6 100644 --- a/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java @@ -159,7 +159,7 @@ public final class LocaleUtils { return LOCALE_MATCH <= level; } - private static final HashMap<String, Locale> sLocaleCache = CollectionUtils.newHashMap(); + private static final HashMap<String, Locale> sLocaleCache = new HashMap<>(); /** * Creates a locale from a string specification. diff --git a/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java b/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java index bf38abc95..21949ffbd 100644 --- a/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java +++ b/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java @@ -21,6 +21,7 @@ import com.android.inputmethod.annotations.UsedForTesting; import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -40,12 +41,26 @@ public class PrioritizedSerialExecutor { // The task which is running now. private Runnable mActive; - public PrioritizedSerialExecutor() { - mTasks = new ConcurrentLinkedQueue<Runnable>(); - mPrioritizedTasks = new ConcurrentLinkedQueue<Runnable>(); + private static class ThreadFactoryWithId implements ThreadFactory { + private final String mId; + + public ThreadFactoryWithId(final String id) { + mId = id; + } + + @Override + public Thread newThread(final Runnable r) { + return new Thread(r, TAG + " - " + mId); + } + } + + public PrioritizedSerialExecutor(final String id) { + mTasks = new ConcurrentLinkedQueue<>(); + mPrioritizedTasks = new ConcurrentLinkedQueue<>(); mIsShutdown = false; mThreadPoolExecutor = new ThreadPoolExecutor(1 /* corePoolSize */, 1 /* maximumPoolSize */, - 0 /* keepAliveTime */, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1)); + 0 /* keepAliveTime */, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), + new ThreadFactoryWithId(id)); } /** diff --git a/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java b/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java index 49f4929b4..093c5a6c1 100644 --- a/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java @@ -41,8 +41,7 @@ public final class ResourceUtils { // This utility class is not publicly instantiable. } - private static final HashMap<String, String> sDeviceOverrideValueMap = - CollectionUtils.newHashMap(); + private static final HashMap<String, String> sDeviceOverrideValueMap = new HashMap<>(); private static final String[] BUILD_KEYS_AND_VALUES = { "HARDWARE", Build.HARDWARE, @@ -54,8 +53,8 @@ public final class ResourceUtils { private static final String sBuildKeyValuesDebugString; static { - sBuildKeyValues = CollectionUtils.newHashMap(); - final ArrayList<String> keyValuePairs = CollectionUtils.newArrayList(); + sBuildKeyValues = new HashMap<>(); + final ArrayList<String> keyValuePairs = new ArrayList<>(); final int keyCount = BUILD_KEYS_AND_VALUES.length / 2; for (int i = 0; i < keyCount; i++) { final int index = i * 2; diff --git a/java/src/com/android/inputmethod/latin/utils/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java index 73ac9a573..4ed0f0a94 100644 --- a/java/src/com/android/inputmethod/latin/utils/StringUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java @@ -28,7 +28,6 @@ import java.util.Arrays; import java.util.Locale; public final class StringUtils { - private static final String TAG = StringUtils.class.getSimpleName(); public static final int CAPITALIZE_NONE = 0; // No caps, or mixed case public static final int CAPITALIZE_FIRST = 1; // First only public static final int CAPITALIZE_ALL = 2; // All caps @@ -110,7 +109,7 @@ public final class StringUtils { if (!containsInArray(text, elements)) { return extraValues; } - final ArrayList<String> result = CollectionUtils.newArrayList(elements.length - 1); + final ArrayList<String> result = new ArrayList<>(elements.length - 1); for (final String element : elements) { if (!text.equals(element)) { result.add(element); diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java index 938d27122..351d01400 100644 --- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java @@ -49,17 +49,14 @@ public final class SubtypeLocaleUtils { private static Resources sResources; private static String[] sPredefinedKeyboardLayoutSet; // Keyboard layout to its display name map. - private static final HashMap<String, String> sKeyboardLayoutToDisplayNameMap = - CollectionUtils.newHashMap(); + private static final HashMap<String, String> sKeyboardLayoutToDisplayNameMap = new HashMap<>(); // Keyboard layout to subtype name resource id map. - private static final HashMap<String, Integer> sKeyboardLayoutToNameIdsMap = - CollectionUtils.newHashMap(); + private static final HashMap<String, Integer> sKeyboardLayoutToNameIdsMap = new HashMap<>(); // Exceptional locale to subtype name resource id map. - private static final HashMap<String, Integer> sExceptionalLocaleToNameIdsMap = - CollectionUtils.newHashMap(); + private static final HashMap<String, Integer> sExceptionalLocaleToNameIdsMap = new HashMap<>(); // Exceptional locale to subtype name with layout resource id map. private static final HashMap<String, Integer> sExceptionalLocaleToWithLayoutNameIdsMap = - CollectionUtils.newHashMap(); + new HashMap<>(); private static final String SUBTYPE_NAME_RESOURCE_PREFIX = "string/subtype_"; private static final String SUBTYPE_NAME_RESOURCE_GENERIC_PREFIX = @@ -71,7 +68,7 @@ public final class SubtypeLocaleUtils { // Keyboard layout set name for the subtypes that don't have a keyboardLayoutSet extra value. // This is for compatibility to keep the same subtype ids as pre-JellyBean. private static final HashMap<String, String> sLocaleAndExtraValueToKeyboardLayoutSetMap = - CollectionUtils.newHashMap(); + new HashMap<>(); private SubtypeLocaleUtils() { // Intentional empty constructor for utility class. diff --git a/java/src/com/android/inputmethod/latin/utils/TargetPackageInfoGetterTask.java b/java/src/com/android/inputmethod/latin/utils/TargetPackageInfoGetterTask.java index 42ea3c959..ab2b00e36 100644 --- a/java/src/com/android/inputmethod/latin/utils/TargetPackageInfoGetterTask.java +++ b/java/src/com/android/inputmethod/latin/utils/TargetPackageInfoGetterTask.java @@ -27,8 +27,7 @@ import com.android.inputmethod.compat.AppWorkaroundsUtils; public final class TargetPackageInfoGetterTask extends AsyncTask<String, Void, PackageInfo> { private static final int MAX_CACHE_ENTRIES = 64; // arbitrary - private static final LruCache<String, PackageInfo> sCache = - new LruCache<String, PackageInfo>(MAX_CACHE_ENTRIES); + private static final LruCache<String, PackageInfo> sCache = new LruCache<>(MAX_CACHE_ENTRIES); public static PackageInfo getCachedPackageInfo(final String packageName) { if (null == packageName) return null; diff --git a/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java b/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java index 087a7f255..fafba79c2 100644 --- a/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java @@ -30,7 +30,7 @@ public final class TypefaceUtils { } // This sparse array caches key label text height in pixel indexed by key label text size. - private static final SparseArray<Float> sTextHeightCache = CollectionUtils.newSparseArray(); + private static final SparseArray<Float> sTextHeightCache = new SparseArray<>(); // Working variable for the following method. private static final Rect sTextHeightBounds = new Rect(); @@ -50,7 +50,7 @@ public final class TypefaceUtils { } // This sparse array caches key label text width in pixel indexed by key label text size. - private static final SparseArray<Float> sTextWidthCache = CollectionUtils.newSparseArray(); + private static final SparseArray<Float> sTextWidthCache = new SparseArray<>(); // Working variable for the following method. private static final Rect sTextWidthBounds = new Rect(); diff --git a/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java b/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java index a75d353c9..cf0ce0d2f 100644 --- a/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java +++ b/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java @@ -66,7 +66,7 @@ public final class UserLogRingCharBuffer { return; } if (LatinImeLogger.sUsabilityStudy) { - UsabilityStudyLogUtils.getInstance().writeChar(c, x, y); + UsabilityStudyLogUtils.writeChar(c, x, y); } mCharBuf[mEnd] = c; mXBuf[mEnd] = x; diff --git a/java/src/com/android/inputmethod/research/FixedLogBuffer.java b/java/src/com/android/inputmethod/research/FixedLogBuffer.java index 8b64de8ae..210015643 100644 --- a/java/src/com/android/inputmethod/research/FixedLogBuffer.java +++ b/java/src/com/android/inputmethod/research/FixedLogBuffer.java @@ -163,7 +163,7 @@ public class FixedLogBuffer extends LogBuffer { // Allocate space for n*2 logUnits. There will be at least n, one for each word, and // there may be additional for punctuation, between-word commands, etc. This should be // enough that reallocation won't be necessary. - final ArrayList<LogUnit> resultList = new ArrayList<LogUnit>(n * 2); + final ArrayList<LogUnit> resultList = new ArrayList<>(n * 2); for (final LogUnit logUnit : logUnits) { n -= logUnit.getNumWords(); if (n < 0) break; diff --git a/java/src/com/android/inputmethod/research/LogBuffer.java b/java/src/com/android/inputmethod/research/LogBuffer.java index b07b761f0..0d9c357da 100644 --- a/java/src/com/android/inputmethod/research/LogBuffer.java +++ b/java/src/com/android/inputmethod/research/LogBuffer.java @@ -31,7 +31,7 @@ public class LogBuffer { private final LinkedList<LogUnit> mLogUnits; public LogBuffer() { - mLogUnits = new LinkedList<LogUnit>(); + mLogUnits = new LinkedList<>(); } protected LinkedList<LogUnit> getLogUnits() { diff --git a/java/src/com/android/inputmethod/research/LogUnit.java b/java/src/com/android/inputmethod/research/LogUnit.java index 3366df12a..1750751a7 100644 --- a/java/src/com/android/inputmethod/research/LogUnit.java +++ b/java/src/com/android/inputmethod/research/LogUnit.java @@ -93,9 +93,9 @@ public class LogUnit { private SuggestedWords mSuggestedWords; public LogUnit() { - mLogStatementList = new ArrayList<LogStatement>(); - mValuesList = new ArrayList<Object[]>(); - mTimeList = new ArrayList<Long>(); + mLogStatementList = new ArrayList<>(); + mValuesList = new ArrayList<>(); + mTimeList = new ArrayList<>(); mIsPartOfMegaword = false; mCorrectionType = CORRECTIONTYPE_NO_CORRECTION; mSuggestedWords = null; @@ -311,9 +311,9 @@ public class LogUnit { // Create the LogUnit containing the later logStatements and associated data. final LogUnit newLogUnit = new LogUnit( - new ArrayList<LogStatement>(laterLogStatements), - new ArrayList<Object[]>(laterValues), - new ArrayList<Long>(laterTimes), + new ArrayList<>(laterLogStatements), + new ArrayList<>(laterValues), + new ArrayList<>(laterTimes), true /* isPartOfMegaword */); newLogUnit.mWords = null; newLogUnit.mMayContainDigit = mMayContainDigit; diff --git a/java/src/com/android/inputmethod/research/MainLogBuffer.java b/java/src/com/android/inputmethod/research/MainLogBuffer.java index ffdb43c15..3806ac755 100644 --- a/java/src/com/android/inputmethod/research/MainLogBuffer.java +++ b/java/src/com/android/inputmethod/research/MainLogBuffer.java @@ -20,7 +20,7 @@ import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.Dictionary; -import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest; +import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.define.ProductionFlag; import java.io.IOException; @@ -75,7 +75,7 @@ public abstract class MainLogBuffer extends FixedLogBuffer { // The size of the n-grams logged. E.g. N_GRAM_SIZE = 2 means to sample bigrams. public static final int N_GRAM_SIZE = 2; - private final DictionaryFacilitatorForSuggest mDictionaryFacilitator; + private final DictionaryFacilitator mDictionaryFacilitator; @UsedForTesting private Dictionary mDictionaryForTesting; private boolean mIsStopping = false; @@ -87,7 +87,7 @@ public abstract class MainLogBuffer extends FixedLogBuffer { /* package for test */ int mNumWordsUntilSafeToSample; public MainLogBuffer(final int wordsBetweenSamples, final int numInitialWordsToIgnore, - final DictionaryFacilitatorForSuggest dictionaryFacilitator) { + final DictionaryFacilitator dictionaryFacilitator) { super(N_GRAM_SIZE + wordsBetweenSamples); mNumWordsBetweenNGrams = wordsBetweenSamples; mNumWordsUntilSafeToSample = DEBUG ? 0 : numInitialWordsToIgnore; diff --git a/java/src/com/android/inputmethod/research/MotionEventReader.java b/java/src/com/android/inputmethod/research/MotionEventReader.java index 3388645b7..f6b7352e7 100644 --- a/java/src/com/android/inputmethod/research/MotionEventReader.java +++ b/java/src/com/android/inputmethod/research/MotionEventReader.java @@ -67,11 +67,10 @@ public class MotionEventReader { @UsedForTesting static class ReplayData { - final ArrayList<Integer> mActions = new ArrayList<Integer>(); - final ArrayList<PointerProperties[]> mPointerPropertiesArrays - = new ArrayList<PointerProperties[]>(); - final ArrayList<PointerCoords[]> mPointerCoordsArrays = new ArrayList<PointerCoords[]>(); - final ArrayList<Long> mTimes = new ArrayList<Long>(); + final ArrayList<Integer> mActions = new ArrayList<>(); + final ArrayList<PointerProperties[]> mPointerPropertiesArrays = new ArrayList<>(); + final ArrayList<PointerCoords[]> mPointerCoordsArrays = new ArrayList<>(); + final ArrayList<Long> mTimes = new ArrayList<>(); } /** @@ -228,8 +227,7 @@ public class MotionEventReader { private PointerProperties[] readPointerProperties(final JsonReader jsonReader) throws IOException { - final ArrayList<PointerProperties> pointerPropertiesArrayList = - new ArrayList<PointerProperties>(); + final ArrayList<PointerProperties> pointerPropertiesArrayList = new ArrayList<>(); jsonReader.beginArray(); while (jsonReader.hasNext()) { final PointerProperties pointerProperties = new PointerProperties(); @@ -254,7 +252,7 @@ public class MotionEventReader { jsonReader.beginArray(); while (jsonReader.hasNext()) { // Array of historical data jsonReader.beginObject(); - final ArrayList<PointerCoords> pointerCoordsArrayList = new ArrayList<PointerCoords>(); + final ArrayList<PointerCoords> pointerCoordsArrayList = new ArrayList<>(); while (jsonReader.hasNext()) { // Time/data object final String name = jsonReader.nextName(); if (name.equals("t")) { diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java index d907dd1b0..d73f9c41c 100644 --- a/java/src/com/android/inputmethod/research/ResearchLogger.java +++ b/java/src/com/android/inputmethod/research/ResearchLogger.java @@ -52,7 +52,7 @@ import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.KeyboardView; import com.android.inputmethod.keyboard.MainKeyboardView; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest; +import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.RichInputConnection; @@ -167,7 +167,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang protected static final int SUSPEND_DURATION_IN_MINUTES = 1; // used to check whether words are not unique - private DictionaryFacilitatorForSuggest mDictionaryFacilitator; + private DictionaryFacilitator mDictionaryFacilitator; private MainKeyboardView mMainKeyboardView; // TODO: Check whether a superclass can be used instead of LatinIME. /* package for test */ LatinIME mLatinIME; @@ -656,7 +656,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang mInFeedbackDialog = false; } - public void initDictionary(final DictionaryFacilitatorForSuggest dictionaryFacilitator) { + public void initDictionary(final DictionaryFacilitator dictionaryFacilitator) { mDictionaryFacilitator = dictionaryFacilitator; // MainLogBuffer now has an out-of-date Suggest object. Close down MainLogBuffer and create // a new one. |