From 12d80ebead6a1d7f704a5a3af3b6fe3313ceab05 Mon Sep 17 00:00:00 2001 From: Dan Zivkovic Date: Tue, 10 Feb 2015 14:54:38 -0800 Subject: [PATCH] Remove shortcut support from LatinIME. Note this change does not affect the native decoder interface. Change-Id: I73b7dc008a5acaf75a31a36a2d332b5afabd82d0 --- .../inputmethod/latin/common/Constants.java | 9 ++ .../user_dictionary_add_word_fullscreen.xml | 20 --- .../accessibility/AccessibilityUtils.java | 3 +- .../compat/InputMethodSubtypeCompatUtils.java | 5 +- .../compat/NotificationCompatUtils.java | 5 +- .../compat/UserDictionaryCompatUtils.java | 48 ------ .../keyboard/KeyboardSwitcher.java | 13 +- .../keyboard/MainKeyboardView.java | 16 +- .../inputmethod/latin/BinaryDictionary.java | 21 +-- .../latin/ContactsBinaryDictionary.java | 7 +- .../latin/ExpandableBinaryDictionary.java | 53 ++----- .../android/inputmethod/latin/LatinIME.java | 5 - .../latin/RichInputConnection.java | 2 +- .../latin/RichInputMethodManager.java | 31 +--- .../latin/UserBinaryDictionary.java | 42 +---- .../latin/makedict/WordProperty.java | 28 +--- .../settings/PreferencesSettingsFragment.java | 9 +- .../latin/settings/SettingsValues.java | 3 +- .../UserDictionaryAddWordContents.java | 77 ++------- .../userdictionary/UserDictionaryList.java | 3 +- .../UserDictionarySettings.java | 103 ++---------- .../latin/utils/CombinedFormatUtils.java | 10 -- .../latin/utils/NetworkConnectivityUtils.java | 101 ------------ .../compat/LocaleSpanCompatUtilsTests.java | 5 +- .../layout/DevanagariLetterConstants.java | 5 +- .../latin/BinaryDictionaryDecayingTests.java | 3 +- .../latin/BinaryDictionaryTests.java | 146 +----------------- .../latin/FusionDictionaryTests.java | 8 +- .../BinaryDictDecoderEncoderTests.java | 102 +++--------- .../makedict/BinaryDictEncoderUtils.java | 81 +--------- .../latin/makedict/FusionDictionary.java | 103 +++--------- .../latin/makedict/Ver2DictDecoder.java | 2 +- .../latin/makedict/Ver2DictEncoder.java | 33 ---- .../latin/makedict/Ver2DictEncoderTests.java | 15 +- .../latin/makedict/Ver4DictDecoder.java | 2 +- .../latin/makedict/Ver4DictEncoder.java | 24 +-- 36 files changed, 176 insertions(+), 967 deletions(-) delete mode 100644 java/src/com/android/inputmethod/compat/UserDictionaryCompatUtils.java delete mode 100644 java/src/com/android/inputmethod/latin/utils/NetworkConnectivityUtils.java diff --git a/common/src/com/android/inputmethod/latin/common/Constants.java b/common/src/com/android/inputmethod/latin/common/Constants.java index baa859268..a2d21a826 100644 --- a/common/src/com/android/inputmethod/latin/common/Constants.java +++ b/common/src/com/android/inputmethod/latin/common/Constants.java @@ -16,11 +16,20 @@ package com.android.inputmethod.latin.common; +import android.os.Build; + import com.android.inputmethod.annotations.UsedForTesting; import javax.annotation.Nonnull; public final class Constants { + + public static final boolean JELLY_BEAN_OR_HIGHER = + Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN; + + public static final boolean JELLY_BEAN_MR1_OR_HIGHER = + Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1; + public static final class Color { /** * The alpha value for fully opaque. diff --git a/java/res/layout/user_dictionary_add_word_fullscreen.xml b/java/res/layout/user_dictionary_add_word_fullscreen.xml index 9bcb189b4..cbdfba67d 100644 --- a/java/res/layout/user_dictionary_add_word_fullscreen.xml +++ b/java/res/layout/user_dictionary_add_word_fullscreen.xml @@ -43,26 +43,6 @@ android:layout_marginStart="8dip" android:columnCount="2" > - - - - = Build.VERSION_CODES.JELLY_BEAN) { + if (Constants.JELLY_BEAN_OR_HIGHER) { event.setEventType(AccessibilityEventCompat.TYPE_ANNOUNCEMENT); } else { event.setEventType(AccessibilityEvent.TYPE_VIEW_FOCUSED); diff --git a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatUtils.java b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatUtils.java index 58ad4bd4c..853830808 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatUtils.java +++ b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatUtils.java @@ -38,7 +38,7 @@ public final class InputMethodSubtypeCompatUtils { int.class, int.class, String.class, String.class, String.class, boolean.class, boolean.class, int.class); static { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + if (Constants.JELLY_BEAN_MR1_OR_HIGHER) { if (CONSTRUCTOR_INPUT_METHOD_SUBTYPE == null) { android.util.Log.w(TAG, "Warning!!! Constructor is not defined."); } @@ -59,8 +59,7 @@ public final class InputMethodSubtypeCompatUtils { public static InputMethodSubtype newInputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue, boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype, int id) { - if (CONSTRUCTOR_INPUT_METHOD_SUBTYPE == null - || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { + if (CONSTRUCTOR_INPUT_METHOD_SUBTYPE == null || !Constants.JELLY_BEAN_MR1_OR_HIGHER) { return new InputMethodSubtype(nameId, iconId, locale, mode, extraValue, isAuxiliary, overridesImplicitlyEnabledSubtype); } diff --git a/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java b/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java index 70ab972c5..0646558e4 100644 --- a/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java +++ b/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java @@ -17,7 +17,8 @@ package com.android.inputmethod.compat; import android.app.Notification; -import android.os.Build; + +import com.android.inputmethod.latin.common.Constants; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -73,7 +74,7 @@ public class NotificationCompatUtils { @SuppressWarnings("deprecation") public static Notification build(final Notification.Builder builder) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + if (Constants.JELLY_BEAN_OR_HIGHER) { // #build was added in API level 16, JELLY_BEAN return (Notification) CompatUtils.invoke(builder, null, METHOD_build); } diff --git a/java/src/com/android/inputmethod/compat/UserDictionaryCompatUtils.java b/java/src/com/android/inputmethod/compat/UserDictionaryCompatUtils.java deleted file mode 100644 index b78c357ab..000000000 --- a/java/src/com/android/inputmethod/compat/UserDictionaryCompatUtils.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2013 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.compat; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build; -import android.provider.UserDictionary; - -import java.util.Locale; - -public final class UserDictionaryCompatUtils { - @SuppressWarnings("deprecation") - public static void addWord(final Context context, final String word, - final int freq, final String shortcut, final Locale locale) { - if (BuildCompatUtils.EFFECTIVE_SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - addWordWithShortcut(context, word, freq, shortcut, locale); - return; - } - // Fall back to the pre-JellyBean method. - final Locale currentLocale = context.getResources().getConfiguration().locale; - final int localeType = currentLocale.equals(locale) - ? UserDictionary.Words.LOCALE_TYPE_CURRENT : UserDictionary.Words.LOCALE_TYPE_ALL; - UserDictionary.Words.addWord(context, word, freq, localeType); - } - - // {@link UserDictionary.Words#addWord(Context,String,int,String,Locale)} was introduced - // in API level 16 (Build.VERSION_CODES.JELLY_BEAN). - @TargetApi(Build.VERSION_CODES.JELLY_BEAN) - private static void addWordWithShortcut(final Context context, final String word, - final int freq, final String shortcut, final Locale locale) { - UserDictionary.Words.addWord(context, word, freq, shortcut, locale); - } -} diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 46476e29e..fca5ecbc0 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -40,13 +40,11 @@ import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.settings.SettingsValues; import com.android.inputmethod.latin.utils.CapsModeUtils; import com.android.inputmethod.latin.utils.LanguageOnSpacebarUtils; -import com.android.inputmethod.latin.utils.NetworkConnectivityUtils; import com.android.inputmethod.latin.utils.RecapitalizeStatus; import com.android.inputmethod.latin.utils.ResourceUtils; import com.android.inputmethod.latin.utils.ScriptUtils; -public final class KeyboardSwitcher implements KeyboardState.SwitchActions, - NetworkConnectivityUtils.NetworkStateChangeListener { +public final class KeyboardSwitcher implements KeyboardState.SwitchActions { private static final String TAG = KeyboardSwitcher.class.getSimpleName(); private InputView mCurrentInputView; @@ -412,15 +410,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions, return mCurrentInputView; } - // {@link NetworkConnectivityUtils.NetworkStateChangeListener#onNetworkStateChanged(boolean)}. - @Override - public void onNetworkStateChanged() { - if (mKeyboardView == null) { - return; - } - mKeyboardView.updateShortcutKey(mRichImm.isShortcutImeReady()); - } - public int getKeyboardShiftMode() { final Keyboard keyboard = getKeyboard(); if (keyboard == null) { diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index ab8b7515d..ce4bb7454 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -694,25 +694,25 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy } @Override - public boolean onTouchEvent(final MotionEvent me) { + public boolean onTouchEvent(final MotionEvent event) { if (getKeyboard() == null) { return false; } if (mNonDistinctMultitouchHelper != null) { - if (me.getPointerCount() > 1 && mTimerHandler.isInKeyRepeat()) { + if (event.getPointerCount() > 1 && mTimerHandler.isInKeyRepeat()) { // Key repeating timer will be canceled if 2 or more keys are in action. mTimerHandler.cancelKeyRepeatTimers(); } // Non distinct multitouch screen support - mNonDistinctMultitouchHelper.processMotionEvent(me, mKeyDetector); + mNonDistinctMultitouchHelper.processMotionEvent(event, mKeyDetector); return true; } - return processMotionEvent(me); + return processMotionEvent(event); } - public boolean processMotionEvent(final MotionEvent me) { - final int index = me.getActionIndex(); - final int id = me.getPointerId(index); + public boolean processMotionEvent(final MotionEvent event) { + final int index = event.getActionIndex(); + final int id = event.getPointerId(index); final PointerTracker tracker = PointerTracker.getPointerTracker(id); // When a more keys panel is showing, we should ignore other fingers' single touch events // other than the finger that is showing the more keys panel. @@ -720,7 +720,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy && PointerTracker.getActivePointerTrackerCount() == 1) { return true; } - tracker.processMotionEvent(me, mKeyDetector); + tracker.processMotionEvent(event, mKeyDetector); return true; } diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 7e4d66583..7ec964d83 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -74,7 +74,7 @@ public final class BinaryDictionary extends Dictionary { private static final int FORMAT_WORD_PROPERTY_IS_NOT_A_WORD_INDEX = 0; private static final int FORMAT_WORD_PROPERTY_IS_POSSIBLY_OFFENSIVE_INDEX = 1; private static final int FORMAT_WORD_PROPERTY_HAS_NGRAMS_INDEX = 2; - private static final int FORMAT_WORD_PROPERTY_HAS_SHORTCUTS_INDEX = 3; + private static final int FORMAT_WORD_PROPERTY_HAS_SHORTCUTS_INDEX = 3; // DEPRECATED private static final int FORMAT_WORD_PROPERTY_IS_BEGINNING_OF_SENTENCE_INDEX = 4; // Format to get probability and historical info from native side via getWordPropertyNative(). @@ -410,11 +410,9 @@ public final class BinaryDictionary extends Dictionary { outFlags[FORMAT_WORD_PROPERTY_IS_NOT_A_WORD_INDEX], outFlags[FORMAT_WORD_PROPERTY_IS_POSSIBLY_OFFENSIVE_INDEX], outFlags[FORMAT_WORD_PROPERTY_HAS_NGRAMS_INDEX], - outFlags[FORMAT_WORD_PROPERTY_HAS_SHORTCUTS_INDEX], outFlags[FORMAT_WORD_PROPERTY_IS_BEGINNING_OF_SENTENCE_INDEX], outProbabilityInfo, outNgramPrevWordsArray, outNgramPrevWordIsBeginningOfSentenceArray, - outNgramTargets, outNgramProbabilityInfo, outShortcutTargets, - outShortcutProbabilities); + outNgramTargets, outNgramProbabilityInfo); } public static class GetNextWordPropertyResult { @@ -442,19 +440,16 @@ public final class BinaryDictionary extends Dictionary { } // Add a unigram entry to binary dictionary with unigram attributes in native code. - public boolean addUnigramEntry(final String word, final int probability, - final String shortcutTarget, final int shortcutProbability, - final boolean isBeginningOfSentence, final boolean isNotAWord, - final boolean isPossiblyOffensive, final int timestamp) { + public boolean addUnigramEntry( + final String word, final int probability, final boolean isBeginningOfSentence, + final boolean isNotAWord, final boolean isPossiblyOffensive, final int timestamp) { if (word == null || (word.isEmpty() && !isBeginningOfSentence)) { return false; } final int[] codePoints = StringUtils.toCodePointArray(word); - final int[] shortcutTargetCodePoints = (shortcutTarget != null) ? - StringUtils.toCodePointArray(shortcutTarget) : null; - if (!addUnigramEntryNative(mNativeDict, codePoints, probability, shortcutTargetCodePoints, - shortcutProbability, isBeginningOfSentence, isNotAWord, isPossiblyOffensive, - timestamp)) { + if (!addUnigramEntryNative(mNativeDict, codePoints, probability, + null /* shortcutTargetCodePoints */, 0 /* shortcutProbability */, + isBeginningOfSentence, isNotAWord, isPossiblyOffensive, timestamp)) { return false; } mHasUpdated = true; diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java index 22fd90795..66a21ecef 100644 --- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java @@ -139,8 +139,8 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { Log.d(TAG, "loadAccountVocabulary: " + word); } runGCIfRequiredLocked(true /* mindsBlockByGC */); - addUnigramLocked(word, FREQUENCY_FOR_CONTACTS, null /* shortcut */, - 0 /* shortcutFreq */, false /* isNotAWord */, false /* isPossiblyOffensive */, + addUnigramLocked(word, FREQUENCY_FOR_CONTACTS, + false /* isNotAWord */, false /* isPossiblyOffensive */, BinaryDictionary.NOT_A_VALID_TIMESTAMP); } } @@ -239,8 +239,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { Log.d(TAG, "addName " + name + ", " + word + ", " + ngramContext); } runGCIfRequiredLocked(true /* mindsBlockByGC */); - addUnigramLocked(word, FREQUENCY_FOR_CONTACTS, - null /* shortcut */, 0 /* shortcutFreq */, false /* isNotAWord */, + addUnigramLocked(word, FREQUENCY_FOR_CONTACTS, false /* isNotAWord */, false /* isPossiblyOffensive */, BinaryDictionary.NOT_A_VALID_TIMESTAMP); if (!ngramContext.isValid() && mUseFirstLastBigrams) { diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index 413c5b8a1..8c780027b 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -297,21 +297,18 @@ 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, - final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord, - final boolean isPossiblyOffensive, final int timestamp) { + final boolean isNotAWord, final boolean isPossiblyOffensive, final int timestamp) { updateDictionaryWithWriteLock(new Runnable() { @Override public void run() { - addUnigramLocked(word, frequency, shortcutTarget, shortcutFreq, - isNotAWord, isPossiblyOffensive, timestamp); + addUnigramLocked(word, frequency, isNotAWord, isPossiblyOffensive, timestamp); } }); } protected void addUnigramLocked(final String word, final int frequency, - final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord, - final boolean isPossiblyOffensive, final int timestamp) { - if (!mBinaryDictionary.addUnigramEntry(word, frequency, shortcutTarget, shortcutFreq, + final boolean isNotAWord, final boolean isPossiblyOffensive, final int timestamp) { + if (!mBinaryDictionary.addUnigramEntry(word, frequency, false /* isBeginningOfSentence */, isNotAWord, isPossiblyOffensive, timestamp)) { Log.e(TAG, "Cannot add unigram entry. word: " + word); } @@ -367,31 +364,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } } - /** - * Dynamically remove the n-gram entry in the dictionary. - */ - @UsedForTesting - public void removeNgramDynamically(@Nonnull final NgramContext ngramContext, - final String word) { - reloadDictionaryIfRequired(); - asyncExecuteTaskWithWriteLock(new Runnable() { - @Override - public void run() { - final BinaryDictionary binaryDictionary = getBinaryDictionary(); - if (binaryDictionary == null) { - return; - } - runGCIfRequiredLocked(true /* mindsBlockByGC */); - if (!binaryDictionary.removeNgramEntry(ngramContext, word)) { - if (DEBUG) { - Log.i(TAG, "Cannot remove n-gram entry."); - Log.i(TAG, " NgramContext: " + ngramContext + ", word: " + word); - } - } - } - }); - } - /** * Update dictionary for the word with the ngramContext. */ @@ -408,20 +380,29 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { isValidWord, count, timestamp)) { if (DEBUG) { Log.e(TAG, "Cannot update counter. word: " + word - + " context: "+ ngramContext.toString()); + + " context: " + ngramContext.toString()); } } } }); } + /** + * Used by Sketch. + * {@see https://cs.corp.google.com/#android/vendor/unbundled_google/packages/LatinIMEGoogle/tools/sketch/ime-simulator/src/com/android/inputmethod/sketch/imesimulator/ImeSimulator.java&q=updateEntriesForInputEventsCallback&l=286} + */ + @UsedForTesting public interface UpdateEntriesForInputEventsCallback { public void onFinished(); } /** * Dynamically update entries according to input events. + * + * Used by Sketch. + * {@see https://cs.corp.google.com/#android/vendor/unbundled_google/packages/LatinIMEGoogle/tools/sketch/ime-simulator/src/com/android/inputmethod/sketch/imesimulator/ImeSimulator.java&q=updateEntriesForInputEventsCallback&l=286} */ + @UsedForTesting public void updateEntriesForInputEvents( @Nonnull final ArrayList inputEvents, final UpdateEntriesForInputEventsCallback callback) { @@ -533,11 +514,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } - protected boolean isValidNgramLocked(final NgramContext ngramContext, final String word) { - if (mBinaryDictionary == null) return false; - return mBinaryDictionary.isValidNgram(ngramContext, word); - } - /** * Loads the current binary dictionary from internal storage. Assumes the dictionary file * exists. @@ -551,6 +527,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { Thread.sleep(15000); Log.w(TAG, "End stress in loading"); } catch (InterruptedException e) { + Log.w("Interrupted while loading: " + mDictName, e); } } final BinaryDictionary oldBinaryDictionary = mBinaryDictionary; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index c118e4aeb..a1ab5c090 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -87,7 +87,6 @@ import com.android.inputmethod.latin.utils.ImportantNoticeUtils; import com.android.inputmethod.latin.utils.IntentUtils; import com.android.inputmethod.latin.utils.JniUtils; import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper; -import com.android.inputmethod.latin.utils.NetworkConnectivityUtils; import com.android.inputmethod.latin.utils.StatsUtils; import com.android.inputmethod.latin.utils.StatsUtilsManager; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; @@ -565,8 +564,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen loadSettings(); resetDictionaryFacilitatorIfNecessary(); - NetworkConnectivityUtils.onCreate(this /* context */, mKeyboardSwitcher /* listener */); - // Register to receive ringer mode change. final IntentFilter filter = new IntentFilter(); filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); @@ -703,7 +700,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void onDestroy() { mDictionaryFacilitator.closeDictionaries(); mSettings.onDestroy(); - NetworkConnectivityUtils.onDestroy(this /* context */); unregisterReceiver(mRingerModeChangeReceiver); unregisterReceiver(mDictionaryPackInstallReceiver); unregisterReceiver(mDictionaryDumpBroadcastReceiver); @@ -717,7 +713,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen unregisterReceiver(mDictionaryPackInstallReceiver); unregisterReceiver(mDictionaryDumpBroadcastReceiver); unregisterReceiver(mRingerModeChangeReceiver); - NetworkConnectivityUtils.onDestroy(this /* context */); mInputLogic.recycle(); } diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index 0210d7e18..f020c25eb 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -899,7 +899,7 @@ public final class RichInputConnection implements PrivateCommandPerformer { * On platforms on which this method is not present, this is a no-op. */ public void maybeMoveTheCursorAroundAndRestoreToWorkaroundABug() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + if (!Constants.JELLY_BEAN_OR_HIGHER) { if (mExpectedSelStart > 0) { mIC.setSelection(mExpectedSelStart - 1, mExpectedSelStart - 1); } else { diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java index 64a7cf347..c8e0b93bf 100644 --- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java +++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java @@ -17,7 +17,6 @@ package com.android.inputmethod.latin; import static com.android.inputmethod.latin.common.Constants.Subtype.KEYBOARD_MODE; -import static com.android.inputmethod.latin.common.Constants.Subtype.ExtraValue.REQ_NETWORK_CONNECTIVITY; import android.content.Context; import android.content.SharedPreferences; @@ -36,7 +35,6 @@ 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.LanguageOnSpacebarUtils; -import com.android.inputmethod.latin.utils.NetworkConnectivityUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.Collections; @@ -288,24 +286,20 @@ public class RichInputMethodManager { } public boolean checkIfSubtypeBelongsToThisImeAndEnabled(final InputMethodSubtype subtype) { - return checkIfSubtypeBelongsToImeAndEnabled(getInputMethodInfoOfThisIme(), subtype); + return checkIfSubtypeBelongsToList(subtype, + getEnabledInputMethodSubtypeList( + getInputMethodInfoOfThisIme(), + true /* allowsImplicitlySelectedSubtypes */)); } public boolean checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled( final InputMethodSubtype subtype) { final boolean subtypeEnabled = checkIfSubtypeBelongsToThisImeAndEnabled(subtype); - final boolean subtypeExplicitlyEnabled = checkIfSubtypeBelongsToList( - subtype, getMyEnabledInputMethodSubtypeList( - false /* allowsImplicitlySelectedSubtypes */)); + final boolean subtypeExplicitlyEnabled = checkIfSubtypeBelongsToList(subtype, + getMyEnabledInputMethodSubtypeList(false /* allowsImplicitlySelectedSubtypes */)); return subtypeEnabled && !subtypeExplicitlyEnabled; } - public boolean checkIfSubtypeBelongsToImeAndEnabled(final InputMethodInfo imi, - final InputMethodSubtype subtype) { - return checkIfSubtypeBelongsToList(subtype, getEnabledInputMethodSubtypeList(imi, - true /* allowsImplicitlySelectedSubtypes */)); - } - private static boolean checkIfSubtypeBelongsToList(final InputMethodSubtype subtype, final List subtypes) { return getSubtypeIndexInList(subtype, subtypes) != INDEX_NOT_FOUND; @@ -564,16 +558,6 @@ public class RichInputMethodManager { }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } - public boolean isShortcutImeEnabled() { - if (mShortcutInputMethodInfo == null) { - return false; - } - if (mShortcutSubtype == null) { - return true; - } - return checkIfSubtypeBelongsToImeAndEnabled(mShortcutInputMethodInfo, mShortcutSubtype); - } - public boolean isShortcutImeReady() { if (mShortcutInputMethodInfo == null) { return false; @@ -581,9 +565,6 @@ public class RichInputMethodManager { if (mShortcutSubtype == null) { return true; } - if (mShortcutSubtype.containsExtraValueKey(REQ_NETWORK_CONNECTIVITY)) { - return NetworkConnectivityUtils.isNetworkConnected(); - } return true; } } diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java index 1ed210377..fe24ccfc2 100644 --- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java @@ -22,7 +22,6 @@ import android.database.ContentObserver; import android.database.Cursor; import android.database.sqlite.SQLiteException; import android.net.Uri; -import android.os.Build; import android.provider.UserDictionary.Words; import android.text.TextUtils; import android.util.Log; @@ -47,19 +46,8 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { private static final String USER_DICTIONARY_ALL_LANGUAGES = ""; private static final int HISTORICAL_DEFAULT_USER_DICTIONARY_FREQUENCY = 250; private static final int LATINIME_DEFAULT_USER_DICTIONARY_FREQUENCY = 160; - // Shortcut frequency is 0~15, with 15 = whitelist. We don't want user dictionary entries - // to auto-correct, so we set this to the highest frequency that won't, i.e. 14. - private static final int USER_DICT_SHORTCUT_FREQUENCY = 14; - private static final String[] PROJECTION_QUERY_WITH_SHORTCUT = new String[] { - Words.WORD, - Words.SHORTCUT, - Words.FREQUENCY, - }; - private static final String[] PROJECTION_QUERY_WITHOUT_SHORTCUT = new String[] { - Words.WORD, - Words.FREQUENCY, - }; + private static final String[] PROJECTION_QUERY = new String[] {Words.WORD, Words.FREQUENCY}; private static final String NAME = "userunigram"; @@ -171,20 +159,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { requestArguments = localeElements; } final String requestString = request.toString(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - try { - addWordsFromProjectionLocked(PROJECTION_QUERY_WITH_SHORTCUT, requestString, - requestArguments); - } catch (IllegalArgumentException e) { - // This may happen on some non-compliant devices where the declared API is JB+ but - // the SHORTCUT column is not present for some reason. - addWordsFromProjectionLocked(PROJECTION_QUERY_WITHOUT_SHORTCUT, requestString, - requestArguments); - } - } else { - addWordsFromProjectionLocked(PROJECTION_QUERY_WITHOUT_SHORTCUT, requestString, - requestArguments); - } + addWordsFromProjectionLocked(PROJECTION_QUERY, requestString, requestArguments); } private void addWordsFromProjectionLocked(final String[] query, String request, @@ -219,31 +194,20 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { } private void addWordsLocked(final Cursor cursor) { - final boolean hasShortcutColumn = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN; if (cursor == null) return; if (cursor.moveToFirst()) { final int indexWord = cursor.getColumnIndex(Words.WORD); - final int indexShortcut = hasShortcutColumn ? cursor.getColumnIndex(Words.SHORTCUT) : 0; final int indexFrequency = cursor.getColumnIndex(Words.FREQUENCY); while (!cursor.isAfterLast()) { final String word = cursor.getString(indexWord); - final String shortcut = hasShortcutColumn ? cursor.getString(indexShortcut) : null; final int frequency = cursor.getInt(indexFrequency); final int adjustedFrequency = scaleFrequencyFromDefaultToLatinIme(frequency); // Safeguard against adding really long words. if (word.length() <= MAX_WORD_LENGTH) { runGCIfRequiredLocked(true /* mindsBlockByGC */); - addUnigramLocked(word, adjustedFrequency, null /* shortcutTarget */, - 0 /* shortcutFreq */, false /* isNotAWord */, + addUnigramLocked(word, adjustedFrequency, false /* isNotAWord */, false /* isPossiblyOffensive */, BinaryDictionary.NOT_A_VALID_TIMESTAMP); - if (null != shortcut && shortcut.length() <= MAX_WORD_LENGTH) { - runGCIfRequiredLocked(true /* mindsBlockByGC */); - addUnigramLocked(shortcut, adjustedFrequency, word, - USER_DICT_SHORTCUT_FREQUENCY, true /* isNotAWord */, - false /* isPossiblyOffensive */, - BinaryDictionary.NOT_A_VALID_TIMESTAMP); - } } cursor.moveToNext(); } diff --git a/java/src/com/android/inputmethod/latin/makedict/WordProperty.java b/java/src/com/android/inputmethod/latin/makedict/WordProperty.java index 388d57816..264e75710 100644 --- a/java/src/com/android/inputmethod/latin/makedict/WordProperty.java +++ b/java/src/com/android/inputmethod/latin/makedict/WordProperty.java @@ -37,13 +37,11 @@ import javax.annotation.Nullable; public final class WordProperty implements Comparable { public final String mWord; public final ProbabilityInfo mProbabilityInfo; - public final ArrayList mShortcutTargets; public final ArrayList mNgrams; // TODO: Support mIsBeginningOfSentence. public final boolean mIsBeginningOfSentence; public final boolean mIsNotAWord; public final boolean mIsPossiblyOffensive; - public final boolean mHasShortcuts; public final boolean mHasNgrams; private int mHashCode = 0; @@ -51,12 +49,10 @@ public final class WordProperty implements Comparable { // TODO: Support n-gram. @UsedForTesting public WordProperty(final String word, final ProbabilityInfo probabilityInfo, - final ArrayList shortcutTargets, @Nullable final ArrayList bigrams, final boolean isNotAWord, final boolean isPossiblyOffensive) { mWord = word; mProbabilityInfo = probabilityInfo; - mShortcutTargets = shortcutTargets; if (null == bigrams) { mNgrams = null; } else { @@ -70,7 +66,6 @@ public final class WordProperty implements Comparable { mIsNotAWord = isNotAWord; mIsPossiblyOffensive = isPossiblyOffensive; mHasNgrams = bigrams != null && !bigrams.isEmpty(); - mHasShortcuts = shortcutTargets != null && !shortcutTargets.isEmpty(); } private static ProbabilityInfo createProbabilityInfoFromArray(final int[] probabilityInfo) { @@ -84,21 +79,17 @@ public final class WordProperty implements Comparable { // Construct word property using information from native code. // This represents invalid word when the probability is BinaryDictionary.NOT_A_PROBABILITY. public WordProperty(final int[] codePoints, final boolean isNotAWord, - final boolean isPossiblyOffensive, final boolean hasBigram, final boolean hasShortcuts, + final boolean isPossiblyOffensive, final boolean hasBigram, final boolean isBeginningOfSentence, final int[] probabilityInfo, final ArrayList ngramPrevWordsArray, final ArrayList ngramPrevWordIsBeginningOfSentenceArray, - final ArrayList ngramTargets, final ArrayList ngramProbabilityInfo, - final ArrayList shortcutTargets, - final ArrayList shortcutProbabilities) { + final ArrayList ngramTargets, final ArrayList ngramProbabilityInfo) { mWord = StringUtils.getStringFromNullTerminatedCodePointArray(codePoints); mProbabilityInfo = createProbabilityInfoFromArray(probabilityInfo); - mShortcutTargets = new ArrayList<>(); final ArrayList ngrams = new ArrayList<>(); mIsBeginningOfSentence = isBeginningOfSentence; mIsNotAWord = isNotAWord; mIsPossiblyOffensive = isPossiblyOffensive; - mHasShortcuts = hasShortcuts; mHasNgrams = hasBigram; final int relatedNgramCount = ngramTargets.size(); @@ -121,14 +112,6 @@ public final class WordProperty implements Comparable { ngrams.add(new NgramProperty(ngramTarget, ngramContext)); } mNgrams = ngrams.isEmpty() ? null : ngrams; - - final int shortcutTargetCount = shortcutTargets.size(); - for (int i = 0; i < shortcutTargetCount; i++) { - final String shortcutTargetString = - StringUtils.getStringFromNullTerminatedCodePointArray(shortcutTargets.get(i)); - mShortcutTargets.add( - new WeightedString(shortcutTargetString, shortcutProbabilities.get(i))); - } } // TODO: Remove @@ -154,7 +137,6 @@ public final class WordProperty implements Comparable { return Arrays.hashCode(new Object[] { word.mWord, word.mProbabilityInfo, - word.mShortcutTargets, word.mNgrams, word.mIsNotAWord, word.mIsPossiblyOffensive @@ -185,10 +167,10 @@ public final class WordProperty implements Comparable { if (o == this) return true; if (!(o instanceof WordProperty)) return false; WordProperty w = (WordProperty)o; - return mProbabilityInfo.equals(w.mProbabilityInfo) && mWord.equals(w.mWord) - && mShortcutTargets.equals(w.mShortcutTargets) && equals(mNgrams, w.mNgrams) + return mProbabilityInfo.equals(w.mProbabilityInfo) + && mWord.equals(w.mWord) && equals(mNgrams, w.mNgrams) && mIsNotAWord == w.mIsNotAWord && mIsPossiblyOffensive == w.mIsPossiblyOffensive - && mHasNgrams == w.mHasNgrams && mHasShortcuts && w.mHasNgrams; + && mHasNgrams == w.mHasNgrams; } // TDOO: Have a utility method like java.util.Objects.equals. diff --git a/java/src/com/android/inputmethod/latin/settings/PreferencesSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/PreferencesSettingsFragment.java index 975396d2d..c5e80f249 100644 --- a/java/src/com/android/inputmethod/latin/settings/PreferencesSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/PreferencesSettingsFragment.java @@ -25,6 +25,7 @@ import android.preference.Preference; import com.android.inputmethod.latin.AudioAndHapticFeedbackManager; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.RichInputMethodManager; +import com.android.inputmethod.latin.common.Constants; /** * "Preferences" settings sub screen. @@ -72,11 +73,9 @@ public final class PreferencesSettingsFragment extends SubScreenFragment { final Preference voiceInputKeyOption = findPreference(Settings.PREF_VOICE_INPUT_KEY); if (voiceInputKeyOption != null) { RichInputMethodManager.getInstance().refreshSubtypeCaches(); - final boolean isShortcutImeEnabled = RichInputMethodManager.getInstance() - .isShortcutImeEnabled(); - voiceInputKeyOption.setEnabled(isShortcutImeEnabled); - voiceInputKeyOption.setSummary( - isShortcutImeEnabled ? null : getText(R.string.voice_input_disabled_summary)); + voiceInputKeyOption.setEnabled(Constants.JELLY_BEAN_OR_HIGHER); + voiceInputKeyOption.setSummary(Constants.JELLY_BEAN_OR_HIGHER + ? null : getText(R.string.voice_input_disabled_summary)); } } diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java index 9a1bb7784..e523246f3 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java @@ -28,6 +28,7 @@ import com.android.inputmethod.compat.AppWorkaroundsUtils; import com.android.inputmethod.latin.InputAttributes; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.RichInputMethodManager; +import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.utils.AsyncResultHolder; import com.android.inputmethod.latin.utils.ResourceUtils; import com.android.inputmethod.latin.utils.TargetPackageInfoGetterTask; @@ -136,7 +137,7 @@ public class SettingsValues { DebugSettings.PREF_SLIDING_KEY_INPUT_PREVIEW, true); mShowsVoiceInputKey = needsToShowVoiceInputKey(prefs, res) && mInputAttributes.mShouldShowVoiceInputKey - && RichInputMethodManager.getInstance().isShortcutImeEnabled(); + && Constants.JELLY_BEAN_OR_HIGHER; final String autoCorrectionThresholdRawValue = prefs.getString( Settings.PREF_AUTO_CORRECTION_THRESHOLD, res.getString(R.string.auto_correction_threshold_mode_index_modest)); diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java index 69029c51e..cb615f3af 100644 --- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java +++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java @@ -26,7 +26,6 @@ import android.text.TextUtils; import android.view.View; import android.widget.EditText; -import com.android.inputmethod.compat.UserDictionaryCompatUtils; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.common.LocaleUtils; @@ -47,10 +46,7 @@ import javax.annotation.Nullable; public class UserDictionaryAddWordContents { public static final String EXTRA_MODE = "mode"; public static final String EXTRA_WORD = "word"; - public static final String EXTRA_SHORTCUT = "shortcut"; public static final String EXTRA_LOCALE = "locale"; - public static final String EXTRA_ORIGINAL_WORD = "originalWord"; - public static final String EXTRA_ORIGINAL_SHORTCUT = "originalShortcut"; public static final int MODE_EDIT = 0; public static final int MODE_INSERT = 1; @@ -63,20 +59,12 @@ public class UserDictionaryAddWordContents { private final int mMode; // Either MODE_EDIT or MODE_INSERT private final EditText mWordEditText; - private final EditText mShortcutEditText; private String mLocale; private final String mOldWord; - private final String mOldShortcut; private String mSavedWord; - private String mSavedShortcut; /* package */ UserDictionaryAddWordContents(final View view, final Bundle args) { mWordEditText = (EditText)view.findViewById(R.id.user_dictionary_add_word_text); - mShortcutEditText = (EditText)view.findViewById(R.id.user_dictionary_add_shortcut); - if (!UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) { - mShortcutEditText.setVisibility(View.GONE); - view.findViewById(R.id.user_dictionary_add_shortcut_label).setVisibility(View.GONE); - } final String word = args.getString(EXTRA_WORD); if (null != word) { mWordEditText.setText(word); @@ -84,17 +72,6 @@ public class UserDictionaryAddWordContents { // it's too long to be edited. mWordEditText.setSelection(mWordEditText.getText().length()); } - final String shortcut; - if (UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) { - shortcut = args.getString(EXTRA_SHORTCUT); - if (null != shortcut && null != mShortcutEditText) { - mShortcutEditText.setText(shortcut); - } - mOldShortcut = args.getString(EXTRA_SHORTCUT); - } else { - shortcut = null; - mOldShortcut = null; - } mMode = args.getInt(EXTRA_MODE); // default return value for #getInt() is 0 = MODE_EDIT mOldWord = args.getString(EXTRA_WORD); updateLocale(args.getString(EXTRA_LOCALE)); @@ -103,10 +80,8 @@ public class UserDictionaryAddWordContents { /* package */ UserDictionaryAddWordContents(final View view, final UserDictionaryAddWordContents oldInstanceToBeEdited) { mWordEditText = (EditText)view.findViewById(R.id.user_dictionary_add_word_text); - mShortcutEditText = (EditText)view.findViewById(R.id.user_dictionary_add_shortcut); mMode = MODE_EDIT; mOldWord = oldInstanceToBeEdited.mSavedWord; - mOldShortcut = oldInstanceToBeEdited.mSavedShortcut; updateLocale(mLocale); } @@ -118,13 +93,6 @@ public class UserDictionaryAddWordContents { /* package */ void saveStateIntoBundle(final Bundle outState) { outState.putString(EXTRA_WORD, mWordEditText.getText().toString()); - outState.putString(EXTRA_ORIGINAL_WORD, mOldWord); - if (null != mShortcutEditText) { - outState.putString(EXTRA_SHORTCUT, mShortcutEditText.getText().toString()); - } - if (null != mOldShortcut) { - outState.putString(EXTRA_ORIGINAL_SHORTCUT, mOldShortcut); - } outState.putString(EXTRA_LOCALE, mLocale); } @@ -132,7 +100,7 @@ public class UserDictionaryAddWordContents { if (MODE_EDIT == mMode && !TextUtils.isEmpty(mOldWord)) { // Mode edit: remove the old entry. final ContentResolver resolver = context.getContentResolver(); - UserDictionarySettings.deleteWord(mOldWord, mOldShortcut, resolver); + UserDictionarySettings.deleteWord(mOldWord, resolver); } // If we are in add mode, nothing was added, so we don't need to do anything. } @@ -143,50 +111,31 @@ public class UserDictionaryAddWordContents { final ContentResolver resolver = context.getContentResolver(); if (MODE_EDIT == mMode && !TextUtils.isEmpty(mOldWord)) { // Mode edit: remove the old entry. - UserDictionarySettings.deleteWord(mOldWord, mOldShortcut, resolver); + UserDictionarySettings.deleteWord(mOldWord, resolver); } final String newWord = mWordEditText.getText().toString(); - final String newShortcut; - if (!UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) { - newShortcut = null; - } else if (null == mShortcutEditText) { - newShortcut = null; - } else { - final String tmpShortcut = mShortcutEditText.getText().toString(); - if (TextUtils.isEmpty(tmpShortcut)) { - newShortcut = null; - } else { - newShortcut = tmpShortcut; - } - } if (TextUtils.isEmpty(newWord)) { // If the word is somehow empty, don't insert it. return CODE_CANCEL; } mSavedWord = newWord; - mSavedShortcut = newShortcut; - // If there is no shortcut, and the word already exists in the database, then we - // should not insert, because either A. the word exists with no shortcut, in which - // case the exact same thing we want to insert is already there, or B. the word - // exists with at least one shortcut, in which case it has priority on our word. - if (TextUtils.isEmpty(newShortcut) && hasWord(newWord, context)) { + // If the word already exists in the database, then we should not insert. + if (hasWord(newWord, context)) { return CODE_ALREADY_PRESENT; } - // Disallow duplicates. If the same word with no shortcut is defined, remove it; if - // the same word with the same shortcut is defined, remove it; but we don't mind if - // there is the same word with a different, non-empty shortcut. - UserDictionarySettings.deleteWord(newWord, null, resolver); - if (!TextUtils.isEmpty(newShortcut)) { - // If newShortcut is empty we just deleted this, no need to do it again - UserDictionarySettings.deleteWord(newWord, newShortcut, resolver); - } + // Disallow duplicates. If the same word is defined, remove it. + UserDictionarySettings.deleteWord(newWord, resolver); // In this class we use the empty string to represent 'all locales' and mLocale cannot // be null. However the addWord method takes null to mean 'all locales'. - UserDictionaryCompatUtils.addWord(context, newWord.toString(), - FREQUENCY_FOR_USER_DICTIONARY_ADDS, newShortcut, TextUtils.isEmpty(mLocale) ? - null : LocaleUtils.constructLocaleFromString(mLocale)); + final Locale locale = TextUtils.isEmpty(mLocale) ? + null : LocaleUtils.constructLocaleFromString(mLocale); + final Locale currentLocale = context.getResources().getConfiguration().locale; + final boolean useCurrentLocale = currentLocale.equals(locale); + UserDictionary.Words.addWord(context, newWord.toString(), + FREQUENCY_FOR_USER_DICTIONARY_ADDS, null /* shortcut */, + useCurrentLocale ? Locale.getDefault() : null); return CODE_WORD_ADDED; } diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java index 6254b54ff..c43463ce7 100644 --- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java +++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java @@ -31,6 +31,7 @@ import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.common.LocaleUtils; import java.util.List; @@ -74,7 +75,7 @@ public class UserDictionaryList extends PreferenceFragment { } finally { cursor.close(); } - if (!UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) { + if (!Constants.JELLY_BEAN_OR_HIGHER) { // For ICS, we need to show "For all languages" in case that the keyboard locale // is different from the system locale localeSet.add(""); diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionarySettings.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionarySettings.java index fabd49f46..3ccd1b3e6 100644 --- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionarySettings.java +++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionarySettings.java @@ -48,42 +48,18 @@ import java.util.Locale; public class UserDictionarySettings extends ListFragment { - public static final boolean IS_SHORTCUT_API_SUPPORTED = - Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN; - - private static final String[] QUERY_PROJECTION_SHORTCUT_UNSUPPORTED = - { UserDictionary.Words._ID, UserDictionary.Words.WORD}; - private static final String[] QUERY_PROJECTION_SHORTCUT_SUPPORTED = - { UserDictionary.Words._ID, UserDictionary.Words.WORD, UserDictionary.Words.SHORTCUT}; - private static final String[] QUERY_PROJECTION = - IS_SHORTCUT_API_SUPPORTED ? - QUERY_PROJECTION_SHORTCUT_SUPPORTED : QUERY_PROJECTION_SHORTCUT_UNSUPPORTED; - - // The index of the shortcut in the above array. - private static final int INDEX_SHORTCUT = 2; - - private static final String[] ADAPTER_FROM_SHORTCUT_UNSUPPORTED = { - UserDictionary.Words.WORD, + private static final String[] QUERY_PROJECTION = { + UserDictionary.Words._ID, UserDictionary.Words.WORD }; - private static final String[] ADAPTER_FROM_SHORTCUT_SUPPORTED = { - UserDictionary.Words.WORD, UserDictionary.Words.SHORTCUT + private static final String[] ADAPTER_FROM = { + UserDictionary.Words.WORD, UserDictionary.Words.SHORTCUT }; - private static final String[] ADAPTER_FROM = IS_SHORTCUT_API_SUPPORTED ? - ADAPTER_FROM_SHORTCUT_SUPPORTED : ADAPTER_FROM_SHORTCUT_UNSUPPORTED; - - private static final int[] ADAPTER_TO_SHORTCUT_UNSUPPORTED = { + private static final int[] ADAPTER_TO = { android.R.id.text1, }; - private static final int[] ADAPTER_TO_SHORTCUT_SUPPORTED = { - android.R.id.text1, android.R.id.text2 - }; - - private static final int[] ADAPTER_TO = IS_SHORTCUT_API_SUPPORTED ? - ADAPTER_TO_SHORTCUT_SUPPORTED : ADAPTER_TO_SHORTCUT_UNSUPPORTED; - // Either the locale is empty (means the word is applicable to all locales) // or the word equals our current locale private static final String QUERY_SELECTION = @@ -91,13 +67,7 @@ public class UserDictionarySettings extends ListFragment { private static final String QUERY_SELECTION_ALL_LOCALES = UserDictionary.Words.LOCALE + " is null"; - private static final String DELETE_SELECTION_WITH_SHORTCUT = UserDictionary.Words.WORD - + "=? AND " + UserDictionary.Words.SHORTCUT + "=?"; - private static final String DELETE_SELECTION_WITHOUT_SHORTCUT = UserDictionary.Words.WORD - + "=? AND " + UserDictionary.Words.SHORTCUT + " is null OR " - + UserDictionary.Words.SHORTCUT + "=''"; - private static final String DELETE_SELECTION_SHORTCUT_UNSUPPORTED = - UserDictionary.Words.WORD + "=?"; + private static final String DELETE_SELECTION = UserDictionary.Words.WORD + "=?"; private static final int OPTIONS_MENU_ADD = Menu.FIRST; @@ -192,20 +162,18 @@ public class UserDictionarySettings extends ListFragment { @Override public void onListItemClick(ListView l, View v, int position, long id) { final String word = getWord(position); - final String shortcut = getShortcut(position); if (word != null) { - showAddOrEditDialog(word, shortcut); + showAddOrEditDialog(word); } } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - if (!UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { final Locale systemLocale = getResources().getConfiguration().locale; if (!TextUtils.isEmpty(mLocale) && !mLocale.equals(systemLocale.toString())) { // Hide the add button for ICS because it doesn't support specifying a locale - // for an entry. This new "locale"-aware API has been added in conjunction - // with the shortcut API. + // for an entry. return; } } @@ -219,7 +187,7 @@ public class UserDictionarySettings extends ListFragment { @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == OPTIONS_MENU_ADD) { - showAddOrEditDialog(null, null); + showAddOrEditDialog(null); return true; } return false; @@ -228,18 +196,15 @@ public class UserDictionarySettings extends ListFragment { /** * Add or edit a word. If editingWord is null, it's an add; otherwise, it's an edit. * @param editingWord the word to edit, or null if it's an add. - * @param editingShortcut the shortcut for this entry, or null if none. */ - private void showAddOrEditDialog(final String editingWord, final String editingShortcut) { + private void showAddOrEditDialog(final String editingWord) { final Bundle args = new Bundle(); args.putInt(UserDictionaryAddWordContents.EXTRA_MODE, null == editingWord ? UserDictionaryAddWordContents.MODE_INSERT : UserDictionaryAddWordContents.MODE_EDIT); args.putString(UserDictionaryAddWordContents.EXTRA_WORD, editingWord); - args.putString(UserDictionaryAddWordContents.EXTRA_SHORTCUT, editingShortcut); args.putString(UserDictionaryAddWordContents.EXTRA_LOCALE, mLocale); - android.preference.PreferenceActivity pa = - (android.preference.PreferenceActivity)getActivity(); + getActivity(); } private String getWord(final int position) { @@ -252,31 +217,8 @@ public class UserDictionarySettings extends ListFragment { mCursor.getColumnIndexOrThrow(UserDictionary.Words.WORD)); } - private String getShortcut(final int position) { - if (!IS_SHORTCUT_API_SUPPORTED) return null; - if (null == mCursor) return null; - mCursor.moveToPosition(position); - // Handle a possible race-condition - if (mCursor.isAfterLast()) return null; - - return mCursor.getString( - mCursor.getColumnIndexOrThrow(UserDictionary.Words.SHORTCUT)); - } - - public static void deleteWord(final String word, final String shortcut, - final ContentResolver resolver) { - if (!IS_SHORTCUT_API_SUPPORTED) { - resolver.delete(UserDictionary.Words.CONTENT_URI, DELETE_SELECTION_SHORTCUT_UNSUPPORTED, - new String[] { word }); - } else if (TextUtils.isEmpty(shortcut)) { - resolver.delete( - UserDictionary.Words.CONTENT_URI, DELETE_SELECTION_WITHOUT_SHORTCUT, - new String[] { word }); - } else { - resolver.delete( - UserDictionary.Words.CONTENT_URI, DELETE_SELECTION_WITH_SHORTCUT, - new String[] { word, shortcut }); - } + public static void deleteWord(final String word, final ContentResolver resolver) { + resolver.delete(UserDictionary.Words.CONTENT_URI, DELETE_SELECTION, new String[] { word }); } private static class MyAdapter extends SimpleCursorAdapter implements SectionIndexer { @@ -286,22 +228,7 @@ public class UserDictionarySettings extends ListFragment { @Override public boolean setViewValue(final View v, final Cursor c, final int columnIndex) { - if (!IS_SHORTCUT_API_SUPPORTED) { - // just let SimpleCursorAdapter set the view values - return false; - } - if (columnIndex == INDEX_SHORTCUT) { - final String shortcut = c.getString(INDEX_SHORTCUT); - if (TextUtils.isEmpty(shortcut)) { - v.setVisibility(View.GONE); - } else { - ((TextView)v).setText(shortcut); - v.setVisibility(View.VISIBLE); - } - v.invalidate(); - return true; - } - + // just let SimpleCursorAdapter set the view values return false; } }; diff --git a/java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java b/java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java index 476c13406..5c0c4328f 100644 --- a/java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java @@ -19,7 +19,6 @@ package com.android.inputmethod.latin.utils; import com.android.inputmethod.latin.makedict.DictionaryHeader; import com.android.inputmethod.latin.makedict.NgramProperty; import com.android.inputmethod.latin.makedict.ProbabilityInfo; -import com.android.inputmethod.latin.makedict.WeightedString; import com.android.inputmethod.latin.makedict.WordProperty; import java.util.HashMap; @@ -29,7 +28,6 @@ public class CombinedFormatUtils { public static final String BIGRAM_TAG = "bigram"; public static final String NGRAM_TAG = "ngram"; public static final String NGRAM_PREV_WORD_TAG = "prev_word"; - public static final String SHORTCUT_TAG = "shortcut"; public static final String PROBABILITY_TAG = "f"; public static final String HISTORICAL_INFO_TAG = "historicalInfo"; public static final String HISTORICAL_INFO_SEPARATOR = ":"; @@ -71,14 +69,6 @@ public class CombinedFormatUtils { builder.append("," + POSSIBLY_OFFENSIVE_TAG + "=" + TRUE_VALUE); } builder.append("\n"); - if (wordProperty.mHasShortcuts) { - for (final WeightedString shortcutTarget : wordProperty.mShortcutTargets) { - builder.append(" " + SHORTCUT_TAG + "=" + shortcutTarget.mWord); - builder.append(","); - builder.append(formatProbabilityInfo(shortcutTarget.mProbabilityInfo)); - builder.append("\n"); - } - } if (wordProperty.mHasNgrams) { for (final NgramProperty ngramProperty : wordProperty.mNgrams) { builder.append(" " + NGRAM_TAG + "=" + ngramProperty.mTargetWord.mWord); diff --git a/java/src/com/android/inputmethod/latin/utils/NetworkConnectivityUtils.java b/java/src/com/android/inputmethod/latin/utils/NetworkConnectivityUtils.java deleted file mode 100644 index 101c55067..000000000 --- a/java/src/com/android/inputmethod/latin/utils/NetworkConnectivityUtils.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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 android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; - -import javax.annotation.Nonnull; - -/** - * This class keeps track of the network connectivity state by receiving the system intent - * {@link ConnectivityManager#CONNECTIVITY_ACTION}, and invokes an registered call back to notify - * changes of the network connectivity state. - */ -public final class NetworkConnectivityUtils { - private static NetworkConnectivityReceiver sNetworkConnectivityReceiver; - - public interface NetworkStateChangeListener { - /** - * Called when the network connectivity state has changed. - */ - public void onNetworkStateChanged(); - } - - private static class NetworkConnectivityReceiver extends BroadcastReceiver { - @Nonnull - private final NetworkStateChangeListener mListener; - private boolean mIsNetworkConnected; - - public NetworkConnectivityReceiver(@Nonnull final NetworkStateChangeListener listener, - final boolean isNetworkConnected) { - mListener = listener; - mIsNetworkConnected = isNetworkConnected; - } - - public synchronized boolean isNetworkConnected() { - return mIsNetworkConnected; - } - - @Override - public void onReceive(final Context context, final Intent intent) { - final String action = intent.getAction(); - if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { - final boolean noConnection = intent.getBooleanExtra( - ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); - synchronized (this) { - mIsNetworkConnected = !noConnection; - } - mListener.onNetworkStateChanged(); - } - } - } - - private NetworkConnectivityUtils() { - // This utility class is not publicly instantiable. - } - - public static void onCreate(@Nonnull final Context context, - @Nonnull final NetworkStateChangeListener listener) { - final ConnectivityManager connectivityManager = - (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - final NetworkInfo info = connectivityManager.getActiveNetworkInfo(); - final boolean isNetworkConnected = (info != null && info.isConnected()); - - // Register {@link BroadcastReceiver} for the network connectivity state change. - final NetworkConnectivityReceiver receiver = new NetworkConnectivityReceiver( - listener, isNetworkConnected); - final IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - context.registerReceiver(receiver, filter); - - sNetworkConnectivityReceiver = receiver; - } - - public static void onDestroy(final Context context) { - context.unregisterReceiver(sNetworkConnectivityReceiver); - } - - public static boolean isNetworkConnected() { - final NetworkConnectivityReceiver receiver = sNetworkConnectivityReceiver; - return receiver != null && receiver.isNetworkConnected(); - } -} diff --git a/tests/src/com/android/inputmethod/compat/LocaleSpanCompatUtilsTests.java b/tests/src/com/android/inputmethod/compat/LocaleSpanCompatUtilsTests.java index 67e76464b..d75e61ad1 100644 --- a/tests/src/com/android/inputmethod/compat/LocaleSpanCompatUtilsTests.java +++ b/tests/src/com/android/inputmethod/compat/LocaleSpanCompatUtilsTests.java @@ -17,19 +17,20 @@ package com.android.inputmethod.compat; import android.graphics.Typeface; -import android.os.Build; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; import android.text.SpannableString; import android.text.Spanned; import android.text.style.StyleSpan; +import com.android.inputmethod.latin.common.Constants; + import java.util.Locale; @SmallTest public class LocaleSpanCompatUtilsTests extends AndroidTestCase { public void testInstantiatable() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { + if (!Constants.JELLY_BEAN_MR1_OR_HIGHER) { // LocaleSpan isn't yet available. return; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/DevanagariLetterConstants.java b/tests/src/com/android/inputmethod/keyboard/layout/DevanagariLetterConstants.java index bcf06f085..557cc214d 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/DevanagariLetterConstants.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/DevanagariLetterConstants.java @@ -16,15 +16,14 @@ package com.android.inputmethod.keyboard.layout; -import android.os.Build; +import com.android.inputmethod.latin.common.Constants; /** * This class offers label strings of Devanagari letters that need the dotted circle to draw * its glyph. */ class DevanagariLetterConstants { - private static final boolean NEEDS_DOTTED_CIRCLE = - Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN; + private static final boolean NEEDS_DOTTED_CIRCLE = !Constants.JELLY_BEAN_OR_HIGHER; // U+25CC: "◌" DOTTED CIRCLE private static final String DOTTED_CIRCLE = NEEDS_DOTTED_CIRCLE ? "\u25CC" : ""; diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java index baac0883e..a51558e43 100644 --- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java +++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java @@ -700,8 +700,7 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); final BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); - binaryDictionary.addUnigramEntry("", DUMMY_PROBABILITY, "" /* shortcutTarget */, - Dictionary.NOT_A_PROBABILITY /* shortcutProbability */, + binaryDictionary.addUnigramEntry("", DUMMY_PROBABILITY, true /* isBeginningOfSentence */, true /* isNotAWord */, false /* isPossiblyOffensive */, mCurrentTime); final NgramContext beginningOfSentenceContext = NgramContext.BEGINNING_OF_SENTENCE; diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java index a8f0d81af..161879841 100644 --- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java +++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java @@ -182,8 +182,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { addUnigramWord(binaryDictionary, validLongWord, probability); addUnigramWord(binaryDictionary, invalidLongWord, probability); // Too long short cut. - binaryDictionary.addUnigramEntry("a", probability, invalidLongWord, - 10 /* shortcutProbability */, false /* isBeginningOfSentence */, + binaryDictionary.addUnigramEntry("a", probability, false /* isBeginningOfSentence */, false /* isNotAWord */, false /* isPossiblyOffensive */, BinaryDictionary.NOT_A_VALID_TIMESTAMP); addUnigramWord(binaryDictionary, "abc", probability); @@ -201,8 +200,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { private static void addUnigramWord(final BinaryDictionary binaryDictionary, final String word, final int probability) { - binaryDictionary.addUnigramEntry(word, probability, "" /* shortcutTarget */, - Dictionary.NOT_A_PROBABILITY /* shortcutProbability */, + binaryDictionary.addUnigramEntry(word, probability, false /* isBeginningOfSentence */, false /* isNotAWord */, false /* isPossiblyOffensive */, BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); @@ -884,7 +882,6 @@ public class BinaryDictionaryTests extends AndroidTestCase { final boolean isPossiblyOffensive = random.nextBoolean(); // TODO: Add tests for historical info. binaryDictionary.addUnigramEntry(word, unigramProbability, - null /* shortcutTarget */, Dictionary.NOT_A_PROBABILITY, false /* isBeginningOfSentence */, isNotAWord, isPossiblyOffensive, BinaryDictionary.NOT_A_VALID_TIMESTAMP); if (binaryDictionary.needsToRunGC(false /* mindsBlockByGC */)) { @@ -899,9 +896,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { assertEquals(isNotAWord, wordProperty.mIsNotAWord); assertEquals(isPossiblyOffensive, wordProperty.mIsPossiblyOffensive); assertEquals(false, wordProperty.mHasNgrams); - assertEquals(false, wordProperty.mHasShortcuts); assertEquals(unigramProbability, wordProperty.mProbabilityInfo.mProbability); - assertTrue(wordProperty.mShortcutTargets.isEmpty()); } for (int i = 0; i < BIGRAM_COUNT; i++) { @@ -1035,137 +1030,10 @@ public class BinaryDictionaryTests extends AndroidTestCase { assertTrue(bigramSet.isEmpty()); } - public void testAddShortcuts() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddShortcuts(formatVersion); - } - } - - private void testAddShortcuts(final int formatVersion) { - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); - - final int unigramProbability = 100; - final int shortcutProbability = 10; - binaryDictionary.addUnigramEntry("aaa", unigramProbability, "zzz", - shortcutProbability, false /* isBeginningOfSentence */, - false /* isNotAWord */, false /* isPossiblyOffensive */, 0 /* timestamp */); - WordProperty wordProperty = binaryDictionary.getWordProperty("aaa", - false /* isBeginningOfSentence */); - assertEquals(1, wordProperty.mShortcutTargets.size()); - assertEquals("zzz", wordProperty.mShortcutTargets.get(0).mWord); - assertEquals(shortcutProbability, wordProperty.mShortcutTargets.get(0).getProbability()); - final int updatedShortcutProbability = 2; - binaryDictionary.addUnigramEntry("aaa", unigramProbability, "zzz", - updatedShortcutProbability, false /* isBeginningOfSentence */, - false /* isNotAWord */, false /* isPossiblyOffensive */, 0 /* timestamp */); - wordProperty = binaryDictionary.getWordProperty("aaa", - false /* isBeginningOfSentence */); - assertEquals(1, wordProperty.mShortcutTargets.size()); - assertEquals("zzz", wordProperty.mShortcutTargets.get(0).mWord); - assertEquals(updatedShortcutProbability, - wordProperty.mShortcutTargets.get(0).getProbability()); - binaryDictionary.addUnigramEntry("aaa", unigramProbability, "yyy", - shortcutProbability, false /* isBeginningOfSentence */, false /* isNotAWord */, - false /* isPossiblyOffensive */, 0 /* timestamp */); - final HashMap shortcutTargets = new HashMap<>(); - shortcutTargets.put("zzz", updatedShortcutProbability); - shortcutTargets.put("yyy", shortcutProbability); - wordProperty = binaryDictionary.getWordProperty("aaa", - false /* isBeginningOfSentence */); - assertEquals(2, wordProperty.mShortcutTargets.size()); - for (WeightedString shortcutTarget : wordProperty.mShortcutTargets) { - assertTrue(shortcutTargets.containsKey(shortcutTarget.mWord)); - assertEquals((int)shortcutTargets.get(shortcutTarget.mWord), - shortcutTarget.getProbability()); - shortcutTargets.remove(shortcutTarget.mWord); - } - shortcutTargets.put("zzz", updatedShortcutProbability); - shortcutTargets.put("yyy", shortcutProbability); - binaryDictionary.flushWithGC(); - wordProperty = binaryDictionary.getWordProperty("aaa", - false /* isBeginningOfSentence */); - assertEquals(2, wordProperty.mShortcutTargets.size()); - for (WeightedString shortcutTarget : wordProperty.mShortcutTargets) { - assertTrue(shortcutTargets.containsKey(shortcutTarget.mWord)); - assertEquals((int)shortcutTargets.get(shortcutTarget.mWord), - shortcutTarget.getProbability()); - shortcutTargets.remove(shortcutTarget.mWord); - } - } - - public void testAddManyShortcuts() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddManyShortcuts(formatVersion); - } - } - - private void testAddManyShortcuts(final int formatVersion) { - final long seed = System.currentTimeMillis(); - final Random random = new Random(seed); - final int UNIGRAM_COUNT = 1000; - final int SHORTCUT_COUNT = 10000; - final int codePointSetSize = 20; - final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); - - final ArrayList words = new ArrayList<>(); - final HashMap unigramProbabilities = new HashMap<>(); - final HashMap> shortcutTargets = new HashMap<>(); - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); - - for (int i = 0; i < UNIGRAM_COUNT; i++) { - final String word = CodePointUtils.generateWord(random, codePointSet); - final int unigramProbability = random.nextInt(0xFF); - addUnigramWord(binaryDictionary, word, unigramProbability); - words.add(word); - unigramProbabilities.put(word, unigramProbability); - if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { - binaryDictionary.flushWithGC(); - } - } - for (int i = 0; i < SHORTCUT_COUNT; i++) { - final String shortcutTarget = CodePointUtils.generateWord(random, codePointSet); - final int shortcutProbability = random.nextInt(0xF); - final String word = words.get(random.nextInt(words.size())); - final int unigramProbability = unigramProbabilities.get(word); - binaryDictionary.addUnigramEntry(word, unigramProbability, shortcutTarget, - shortcutProbability, false /* isBeginningOfSentence */, false /* isNotAWord */, - false /* isPossiblyOffensive */, 0 /* timestamp */); - if (shortcutTargets.containsKey(word)) { - final HashMap shortcutTargetsOfWord = shortcutTargets.get(word); - shortcutTargetsOfWord.put(shortcutTarget, shortcutProbability); - } else { - final HashMap shortcutTargetsOfWord = new HashMap<>(); - shortcutTargetsOfWord.put(shortcutTarget, shortcutProbability); - shortcutTargets.put(word, shortcutTargetsOfWord); - } - if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { - binaryDictionary.flushWithGC(); - } - } - - for (final String word : words) { - final WordProperty wordProperty = binaryDictionary.getWordProperty(word, - false /* isBeginningOfSentence */); - assertEquals((int)unigramProbabilities.get(word), - wordProperty.mProbabilityInfo.mProbability); - if (!shortcutTargets.containsKey(word)) { - // The word does not have shortcut targets. - continue; - } - assertEquals(shortcutTargets.get(word).size(), wordProperty.mShortcutTargets.size()); - for (final WeightedString shortcutTarget : wordProperty.mShortcutTargets) { - final String targetCodePonts = shortcutTarget.mWord; - assertEquals((int)shortcutTargets.get(word).get(targetCodePonts), - shortcutTarget.getProbability()); - } - } - } - public void testPossiblyOffensiveAttributeMaintained() { final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); - binaryDictionary.addUnigramEntry("ddd", 100, null, Dictionary.NOT_A_PROBABILITY, - false, true, true, 0); + binaryDictionary.addUnigramEntry("ddd", 100, false, true, true, 0); WordProperty wordProperty = binaryDictionary.getWordProperty("ddd", false); assertEquals(true, wordProperty.mIsPossiblyOffensive); } @@ -1184,11 +1052,11 @@ public class BinaryDictionaryTests extends AndroidTestCase { final int bigramProbability = 150; addBigramWords(binaryDictionary, "aaa", "bbb", bigramProbability); final int shortcutProbability = 10; - binaryDictionary.addUnigramEntry("ccc", unigramProbability, "xxx", shortcutProbability, + binaryDictionary.addUnigramEntry("ccc", unigramProbability, false /* isBeginningOfSentence */, false /* isNotAWord */, false /* isPossiblyOffensive */, 0 /* timestamp */); - binaryDictionary.addUnigramEntry("ddd", unigramProbability, null /* shortcutTarget */, - Dictionary.NOT_A_PROBABILITY, false /* isBeginningOfSentence */, + binaryDictionary.addUnigramEntry("ddd", unigramProbability, + false /* isBeginningOfSentence */, true /* isNotAWord */, true /* isPossiblyOffensive */, 0 /* timestamp */); binaryDictionary.addNgramEntry(NgramContext.BEGINNING_OF_SENTENCE, "aaa", bigramProbability, 0 /* timestamp */); @@ -1207,8 +1075,6 @@ public class BinaryDictionaryTests extends AndroidTestCase { assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb")); WordProperty wordProperty = binaryDictionary.getWordProperty("ccc", false /* isBeginningOfSentence */); - assertEquals(1, wordProperty.mShortcutTargets.size()); - assertEquals("xxx", wordProperty.mShortcutTargets.get(0).mWord); wordProperty = binaryDictionary.getWordProperty("ddd", false /* isBeginningOfSentence */); assertTrue(wordProperty.mIsPossiblyOffensive); diff --git a/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java b/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java index 07d7c3225..6c6f62872 100644 --- a/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java +++ b/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java @@ -35,19 +35,19 @@ public class FusionDictionaryTests extends AndroidTestCase { FusionDictionary dict = new FusionDictionary(new PtNodeArray(), new DictionaryOptions(new HashMap())); - dict.add("abc", new ProbabilityInfo(10), null, false /* isNotAWord */, + dict.add("abc", new ProbabilityInfo(10), false /* isNotAWord */, false /* isPossiblyOffensive */); assertNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "aaa")); assertNotNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "abc")); - dict.add("aa", new ProbabilityInfo(10), null, false /* isNotAWord */, + dict.add("aa", new ProbabilityInfo(10), false /* isNotAWord */, false /* isPossiblyOffensive */); assertNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "aaa")); assertNotNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "aa")); - dict.add("babcd", new ProbabilityInfo(10), null, false /* isNotAWord */, + dict.add("babcd", new ProbabilityInfo(10), false /* isNotAWord */, false /* isPossiblyOffensive */); - dict.add("bacde", new ProbabilityInfo(10), null, false /* isNotAWord */, + dict.add("bacde", new ProbabilityInfo(10), false /* isNotAWord */, false /* isPossiblyOffensive */); assertNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "ba")); assertNotNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "babcd")); diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java index d833b9736..39da9fcd6 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java @@ -57,15 +57,12 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { private static final int UNIGRAM_FREQ = 10; private static final int BIGRAM_FREQ = 50; private static final int TOLERANCE_OF_BIGRAM_FREQ = 5; - private static final int NUM_OF_NODES_HAVING_SHORTCUTS = 50; - private static final int NUM_OF_SHORTCUTS = 5; private static final ArrayList sWords = new ArrayList<>(); private static final ArrayList sWordsWithVariousCodePoints = new ArrayList<>(); private static final SparseArray> sEmptyBigrams = new SparseArray<>(); private static final SparseArray> sStarBigrams = new SparseArray<>(); private static final SparseArray> sChainBigrams = new SparseArray<>(); - private static final HashMap> sShortcuts = new HashMap<>(); final Random mRandom; @@ -95,16 +92,6 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { for (int i = 1; i < maxBigrams; ++i) { sStarBigrams.get(0).add(i); } - - sShortcuts.clear(); - for (int i = 0; i < NUM_OF_NODES_HAVING_SHORTCUTS; ++i) { - final int from = Math.abs(mRandom.nextInt()) % sWords.size(); - sShortcuts.put(sWords.get(from), new ArrayList()); - for (int j = 0; j < NUM_OF_SHORTCUTS; ++j) { - final int to = Math.abs(mRandom.nextInt()) % sWords.size(); - sShortcuts.get(sWords.get(from)).add(sWords.get(to)); - } - } } @Override @@ -142,17 +129,11 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { * Adds unigrams to the dictionary. */ private static void addUnigrams(final int number, final FusionDictionary dict, - final List words, final HashMap> shortcutMap) { + final List words) { for (int i = 0; i < number; ++i) { final String word = words.get(i); final ArrayList shortcuts = new ArrayList<>(); - if (shortcutMap != null && shortcutMap.containsKey(word)) { - for (final String shortcut : shortcutMap.get(word)) { - shortcuts.add(new WeightedString(shortcut, UNIGRAM_FREQ)); - } - } - dict.add(word, new ProbabilityInfo(UNIGRAM_FREQ), - (shortcutMap == null) ? null : shortcuts, false /* isNotAWord */, + dict.add(word, new ProbabilityInfo(UNIGRAM_FREQ), false /* isNotAWord */, false /* isPossiblyOffensive */); } } @@ -200,8 +181,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { } private static void checkDictionary(final FusionDictionary dict, final List words, - final SparseArray> bigrams, - final HashMap> shortcutMap) { + final SparseArray> bigrams) { assertNotNull(dict); // check unigram @@ -219,19 +199,6 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { assertNotNull(words.get(w1) + "," + words.get(w2), ptNode.getBigram(words.get(w2))); } } - - // check shortcut - if (shortcutMap != null) { - for (final Entry> entry : shortcutMap.entrySet()) { - assertTrue(words.contains(entry.getKey())); - final PtNode ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, - entry.getKey()); - for (final String word : entry.getValue()) { - assertNotNull("shortcut not found: " + entry.getKey() + ", " + word, - ptNode.getShortcut(word)); - } - } - } } private static String outputOptions(final int bufferType, @@ -244,8 +211,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { // Tests for readDictionaryBinary and writeDictionaryBinary private static long timeReadingAndCheckDict(final File file, final List words, - final SparseArray> bigrams, - final HashMap> shortcutMap, final int bufferType) { + final SparseArray> bigrams, final int bufferType) { long now, diff = -1; FusionDictionary dict = null; @@ -261,13 +227,13 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { Log.e(TAG, "Unsupported format", e); } - checkDictionary(dict, words, bigrams, shortcutMap); + checkDictionary(dict, words, bigrams); return diff; } // Tests for readDictionaryBinary and writeDictionaryBinary private String runReadAndWrite(final List words, - final SparseArray> bigrams, final HashMap> shortcuts, + final SparseArray> bigrams, final int bufferType, final FormatSpec.FormatOptions formatOptions, final String message) { @@ -278,12 +244,12 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions)); - addUnigrams(words.size(), dict, words, shortcuts); + addUnigrams(words.size(), dict, words); addBigrams(dict, words, bigrams); - checkDictionary(dict, words, bigrams, shortcuts); + checkDictionary(dict, words, bigrams); final long write = timeWritingDictToFile(file, dict, formatOptions); - final long read = timeReadingAndCheckDict(file, words, bigrams, shortcuts, bufferType); + final long read = timeReadingAndCheckDict(file, words, bigrams, bufferType); return "PROF: read=" + read + "ms, write=" + write + "ms :" + message + " : " + outputOptions(bufferType, formatOptions); @@ -291,20 +257,20 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { private void runReadAndWriteTests(final List results, final int bufferType, final FormatSpec.FormatOptions formatOptions) { - results.add(runReadAndWrite(sWords, sEmptyBigrams, null /* shortcuts */, bufferType, + results.add(runReadAndWrite(sWords, sEmptyBigrams, bufferType, formatOptions, "unigram")); - results.add(runReadAndWrite(sWords, sChainBigrams, null /* shortcuts */, bufferType, + results.add(runReadAndWrite(sWords, sChainBigrams, bufferType, formatOptions, "chain")); - results.add(runReadAndWrite(sWords, sStarBigrams, null /* shortcuts */, bufferType, + results.add(runReadAndWrite(sWords, sStarBigrams, bufferType, formatOptions, "star")); - results.add(runReadAndWrite(sWords, sEmptyBigrams, sShortcuts, bufferType, formatOptions, + results.add(runReadAndWrite(sWords, sEmptyBigrams, bufferType, formatOptions, "unigram with shortcuts")); - results.add(runReadAndWrite(sWords, sChainBigrams, sShortcuts, bufferType, formatOptions, + results.add(runReadAndWrite(sWords, sChainBigrams, bufferType, formatOptions, "chain with shortcuts")); - results.add(runReadAndWrite(sWords, sStarBigrams, sShortcuts, bufferType, formatOptions, + results.add(runReadAndWrite(sWords, sStarBigrams, bufferType, formatOptions, "star with shortcuts")); results.add(runReadAndWrite(sWordsWithVariousCodePoints, sEmptyBigrams, - null /* shortcuts */, bufferType, formatOptions, + bufferType, formatOptions, "unigram with various code points")); } @@ -326,7 +292,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { FormatSpec.MINIMUM_SUPPORTED_STATIC_VERSION); final FusionDictionary sourcedict = new FusionDictionary(new PtNodeArray(), BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions)); - addUnigrams(words.size(), sourcedict, words, null /* shortcutMap */); + addUnigrams(words.size(), sourcedict, words); dictEncoder.writeDictionary(sourcedict, formatOptions); // Read the dictionary @@ -472,7 +438,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { // making the dictionary from lists of words. final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions)); - addUnigrams(words.size(), dict, words, null /* shortcutMap */); + addUnigrams(words.size(), dict, words); addBigrams(dict, words, bigrams); timeWritingDictToFile(file, dict, formatOptions); @@ -482,7 +448,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { // TODO: Abandon the Java code, and implement the v4 dictionary reading code in native. long wordMap = timeAndCheckReadUnigramsAndBigramsBinary(file, words, bigrams, bufferType, !formatOptions.mHasTimestamp /* checkProbability */); - long fullReading = timeReadingAndCheckDict(file, words, bigrams, null /* shortcutMap */, + long fullReading = timeReadingAndCheckDict(file, words, bigrams, bufferType); return "readDictionaryBinary=" + fullReading + ", readUnigramsAndBigramsBinary=" + wordMap @@ -567,7 +533,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions)); - addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */); + addUnigrams(sWords.size(), dict, sWords); addBigrams(dict, words, bigrams); timeWritingDictToFile(file, dict, formatOptions); @@ -636,12 +602,11 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { public void testVer2DictGetWordProperty() { final FormatOptions formatOptions = BinaryDictUtils.STATIC_OPTIONS; final ArrayList words = sWords; - final HashMap> shortcuts = sShortcuts; final String dictName = "testGetWordProperty"; final String dictVersion = Long.toString(System.currentTimeMillis()); final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions)); - addUnigrams(words.size(), dict, words, shortcuts); + addUnigrams(words.size(), dict, words); addBigrams(dict, words, sEmptyBigrams); final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions, getContext().getCacheDir()); @@ -655,30 +620,18 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { false /* isBeginningOfSentence */); assertEquals(word, wordProperty.mWord); assertEquals(UNIGRAM_FREQ, wordProperty.getProbability()); - if (shortcuts.containsKey(word)) { - assertEquals(shortcuts.get(word).size(), wordProperty.mShortcutTargets.size()); - final List shortcutList = shortcuts.get(word); - assertTrue(wordProperty.mHasShortcuts); - for (final WeightedString shortcutTarget : wordProperty.mShortcutTargets) { - assertTrue(shortcutList.contains(shortcutTarget.mWord)); - assertEquals(UNIGRAM_FREQ, shortcutTarget.getProbability()); - shortcutList.remove(shortcutTarget.mWord); - } - assertTrue(shortcutList.isEmpty()); - } } } public void testVer2DictIteration() { final FormatOptions formatOptions = BinaryDictUtils.STATIC_OPTIONS; final ArrayList words = sWords; - final HashMap> shortcuts = sShortcuts; final SparseArray> bigrams = sEmptyBigrams; final String dictName = "testGetWordProperty"; final String dictVersion = Long.toString(System.currentTimeMillis()); final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions)); - addUnigrams(words.size(), dict, words, shortcuts); + addUnigrams(words.size(), dict, words); addBigrams(dict, words, bigrams); final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions, getContext().getCacheDir()); @@ -708,17 +661,6 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { final String word0 = wordProperty.mWord; assertEquals(UNIGRAM_FREQ, wordProperty.mProbabilityInfo.mProbability); wordSet.remove(word0); - if (shortcuts.containsKey(word0)) { - assertEquals(shortcuts.get(word0).size(), wordProperty.mShortcutTargets.size()); - final List shortcutList = shortcuts.get(word0); - assertNotNull(wordProperty.mShortcutTargets); - for (final WeightedString shortcutTarget : wordProperty.mShortcutTargets) { - assertTrue(shortcutList.contains(shortcutTarget.mWord)); - assertEquals(UNIGRAM_FREQ, shortcutTarget.getProbability()); - shortcutList.remove(shortcutTarget.mWord); - } - assertTrue(shortcutList.isEmpty()); - } if (wordProperty.mHasNgrams) { for (final WeightedString bigramTarget : wordProperty.getBigrams()) { final String word1 = bigramTarget.mWord; diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java index ce905c499..bd5136583 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java @@ -16,9 +16,7 @@ package com.android.inputmethod.latin.makedict; -import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding; -import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode; import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray; @@ -91,38 +89,6 @@ public class BinaryDictEncoderUtils { return BinaryDictIOUtils.getPtNodeCountSize(nodeArray.mData.size()); } - /** - * Compute the size of a shortcut in bytes. - */ - private static int getShortcutSize(final WeightedString shortcut, - final HashMap codePointToOneByteCodeMap) { - int size = FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE; - final String word = shortcut.mWord; - final int length = word.length(); - for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) { - final int codePoint = word.codePointAt(i); - size += CharEncoding.getCharSize(codePoint, codePointToOneByteCodeMap); - } - size += FormatSpec.PTNODE_TERMINATOR_SIZE; - return size; - } - - /** - * Compute the size of a shortcut list in bytes. - * - * This is known in advance and does not change according to position in the file - * like address lists do. - */ - static int getShortcutListSize(final ArrayList shortcutList, - final HashMap codePointToOneByteCodeMap) { - if (null == shortcutList || shortcutList.isEmpty()) return 0; - int size = FormatSpec.PTNODE_SHORTCUT_LIST_SIZE_SIZE; - for (final WeightedString shortcut : shortcutList) { - size += getShortcutSize(shortcut, codePointToOneByteCodeMap); - } - return size; - } - /** * Compute the maximum size of a PtNode, assuming 3-byte addresses for everything. * @@ -137,8 +103,6 @@ public class BinaryDictEncoderUtils { size += FormatSpec.PTNODE_FREQUENCY_SIZE; } size += FormatSpec.PTNODE_MAX_ADDRESS_SIZE; // For children address - // TODO: Use codePointToOneByteCodeMap for shortcuts. - size += getShortcutListSize(ptNode.mShortcutTargets, null /* codePointToOneByteCodeMap */); if (null != ptNode.mBigrams) { size += (FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE + FormatSpec.PTNODE_ATTRIBUTE_MAX_ADDRESS_SIZE) @@ -241,27 +205,6 @@ public class BinaryDictEncoderUtils { } } - @UsedForTesting - static void writeUIntToDictBuffer(final DictBuffer dictBuffer, final int value, - final int size) { - switch(size) { - case 4: - dictBuffer.put((byte) ((value >> 24) & 0xFF)); - /* fall through */ - case 3: - dictBuffer.put((byte) ((value >> 16) & 0xFF)); - /* fall through */ - case 2: - dictBuffer.put((byte) ((value >> 8) & 0xFF)); - /* fall through */ - case 1: - dictBuffer.put((byte) (value & 0xFF)); - break; - default: - /* nop */ - } - } - // End utility methods // This method is responsible for finding a nice ordering of the nodes that favors run-time @@ -391,9 +334,6 @@ public class BinaryDictEncoderUtils { nodeSize += getByteSize(getOffsetToTargetNodeArrayDuringUpdate(ptNodeArray, nodeSize + size, ptNode.mChildren)); } - // TODO: Use codePointToOneByteCodeMap for shortcuts. - nodeSize += getShortcutListSize(ptNode.mShortcutTargets, - null /* codePointToOneByteCodeMap */); if (null != ptNode.mBigrams) { for (WeightedString bigram : ptNode.mBigrams) { final int offset = getOffsetToTargetPtNodeDuringUpdate(ptNodeArray, @@ -568,14 +508,13 @@ public class BinaryDictEncoderUtils { * @param hasMultipleChars whether the PtNode has multiple chars. * @param isTerminal whether the PtNode is terminal. * @param childrenAddressSize the size of a children address. - * @param hasShortcuts whether the PtNode has shortcuts. * @param hasBigrams whether the PtNode has bigrams. * @param isNotAWord whether the PtNode is not a word. * @param isPossiblyOffensive whether the PtNode is a possibly offensive entry. * @return the flags */ static int makePtNodeFlags(final boolean hasMultipleChars, final boolean isTerminal, - final int childrenAddressSize, final boolean hasShortcuts, final boolean hasBigrams, + final int childrenAddressSize, final boolean hasBigrams, final boolean isNotAWord, final boolean isPossiblyOffensive) { byte flags = 0; if (hasMultipleChars) flags |= FormatSpec.FLAG_HAS_MULTIPLE_CHARS; @@ -596,7 +535,6 @@ public class BinaryDictEncoderUtils { default: throw new RuntimeException("Node with a strange address"); } - if (hasShortcuts) flags |= FormatSpec.FLAG_HAS_SHORTCUT_TARGETS; if (hasBigrams) flags |= FormatSpec.FLAG_HAS_BIGRAMS; if (isNotAWord) flags |= FormatSpec.FLAG_IS_NOT_A_WORD; if (isPossiblyOffensive) flags |= FormatSpec.FLAG_IS_POSSIBLY_OFFENSIVE; @@ -606,7 +544,6 @@ public class BinaryDictEncoderUtils { /* package */ static byte makePtNodeFlags(final PtNode node, final int childrenOffset) { return (byte) makePtNodeFlags(node.mChars.length > 1, node.isTerminal(), getByteSize(childrenOffset), - node.mShortcutTargets != null && !node.mShortcutTargets.isEmpty(), node.mBigrams != null && !node.mBigrams.isEmpty(), node.mIsNotAWord, node.mIsPossiblyOffensive); } @@ -621,7 +558,7 @@ public class BinaryDictEncoderUtils { * @param word the second bigram, for debugging purposes * @return the flags */ - /* package */ static final int makeBigramFlags(final boolean more, final int offset, + /* package */ static int makeBigramFlags(final boolean more, final int offset, final int bigramFrequency, final int unigramFrequency, final String word) { int bigramFlags = (more ? FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT : 0) + (offset < 0 ? FormatSpec.FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE : 0); @@ -690,19 +627,7 @@ public class BinaryDictEncoderUtils { return discretizedFrequency > 0 ? discretizedFrequency : 0; } - /** - * Makes the flag value for a shortcut. - * - * @param more whether there are more attributes after this one. - * @param frequency the frequency of the attribute, 0..15 - * @return the flags - */ - static final int makeShortcutFlags(final boolean more, final int frequency) { - return (more ? FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT : 0) - + (frequency & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY); - } - - /* package */ static final int getChildrenPosition(final PtNode ptNode, + /* package */ static int getChildrenPosition(final PtNode ptNode, final HashMap codePointToOneByteCodeMap) { int positionOfChildrenPosField = ptNode.mCachedAddressAfterUpdate + getNodeHeaderSize(ptNode, codePointToOneByteCodeMap); diff --git a/tests/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/tests/src/com/android/inputmethod/latin/makedict/FusionDictionary.java index a42f0a93d..52060bed2 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/FusionDictionary.java +++ b/tests/src/com/android/inputmethod/latin/makedict/FusionDictionary.java @@ -82,7 +82,6 @@ public final class FusionDictionary implements Iterable { public static final class PtNode { private static final int NOT_A_TERMINAL = -1; final int mChars[]; - ArrayList mShortcutTargets; ArrayList mBigrams; // null == mProbabilityInfo indicates this is not a terminal. ProbabilityInfo mProbabilityInfo; @@ -100,26 +99,23 @@ public final class FusionDictionary implements Iterable { int mCachedAddressBeforeUpdate; // The address of this PtNode (before update) int mCachedAddressAfterUpdate; // The address of this PtNode (after update) - public PtNode(final int[] chars, final ArrayList shortcutTargets, - final ArrayList bigrams, final ProbabilityInfo probabilityInfo, - final boolean isNotAWord, final boolean isPossiblyOffensive) { + public PtNode(final int[] chars, final ArrayList bigrams, + final ProbabilityInfo probabilityInfo, final boolean isNotAWord, + final boolean isPossiblyOffensive) { mChars = chars; mProbabilityInfo = probabilityInfo; mTerminalId = probabilityInfo == null ? NOT_A_TERMINAL : probabilityInfo.mProbability; - mShortcutTargets = shortcutTargets; mBigrams = bigrams; mChildren = null; mIsNotAWord = isNotAWord; mIsPossiblyOffensive = isPossiblyOffensive; } - public PtNode(final int[] chars, final ArrayList shortcutTargets, - final ArrayList bigrams, final ProbabilityInfo probabilityInfo, - final boolean isNotAWord, final boolean isPossiblyOffensive, - final PtNodeArray children) { + public PtNode(final int[] chars, final ArrayList bigrams, + final ProbabilityInfo probabilityInfo, final boolean isNotAWord, + final boolean isPossiblyOffensive, final PtNodeArray children) { mChars = chars; mProbabilityInfo = probabilityInfo; - mShortcutTargets = shortcutTargets; mBigrams = bigrams; mChildren = children; mIsNotAWord = isNotAWord; @@ -153,14 +149,6 @@ public final class FusionDictionary implements Iterable { return mIsPossiblyOffensive; } - public ArrayList getShortcutTargets() { - // We don't want write permission to escape outside the package, so we return a copy - if (null == mShortcutTargets) return null; - final ArrayList copyOfShortcutTargets = - new ArrayList<>(mShortcutTargets); - return copyOfShortcutTargets; - } - public ArrayList getBigrams() { // We don't want write permission to escape outside the package, so we return a copy if (null == mBigrams) return null; @@ -190,24 +178,6 @@ public final class FusionDictionary implements Iterable { } } - /** - * Gets the shortcut target for the given word. Returns null if the word is not in the - * shortcut list. - */ - public WeightedString getShortcut(final String word) { - // TODO: Don't do a linear search - if (mShortcutTargets != null) { - final int size = mShortcutTargets.size(); - for (int i = 0; i < size; ++i) { - WeightedString shortcut = mShortcutTargets.get(i); - if (shortcut.mWord.equals(word)) { - return shortcut; - } - } - } - return null; - } - /** * Gets the bigram for the given word. * Returns null if the word is not in the bigrams list. @@ -232,27 +202,9 @@ public final class FusionDictionary implements Iterable { * updated if they are higher than the existing ones. */ void update(final ProbabilityInfo probabilityInfo, - final ArrayList shortcutTargets, final ArrayList bigrams, final boolean isNotAWord, final boolean isPossiblyOffensive) { mProbabilityInfo = ProbabilityInfo.max(mProbabilityInfo, probabilityInfo); - if (shortcutTargets != null) { - if (mShortcutTargets == null) { - mShortcutTargets = shortcutTargets; - } else { - final int size = shortcutTargets.size(); - for (int i = 0; i < size; ++i) { - final WeightedString shortcut = shortcutTargets.get(i); - final WeightedString existingShortcut = getShortcut(shortcut.mWord); - if (existingShortcut == null) { - mShortcutTargets.add(shortcut); - } else { - existingShortcut.mProbabilityInfo = ProbabilityInfo.max( - existingShortcut.mProbabilityInfo, shortcut.mProbabilityInfo); - } - } - } - } if (bigrams != null) { if (mBigrams == null) { mBigrams = bigrams; @@ -312,19 +264,16 @@ public final class FusionDictionary implements Iterable { * Helper method to add a word as a string. * * This method adds a word to the dictionary with the given frequency. Optional - * lists of bigrams and shortcuts can be passed here. For each word inside, + * lists of bigrams can be passed here. For each word inside, * they will be added to the dictionary as necessary. - * - * @param word the word to add. + * @param word the word to add. * @param probabilityInfo probability information of the word. - * @param shortcutTargets a list of shortcut targets for this word, or null. * @param isNotAWord true if this should not be considered a word (e.g. shortcut only) * @param isPossiblyOffensive true if this word is possibly offensive */ public void add(final String word, final ProbabilityInfo probabilityInfo, - final ArrayList shortcutTargets, final boolean isNotAWord, - final boolean isPossiblyOffensive) { - add(getCodePoints(word), probabilityInfo, shortcutTargets, isNotAWord, isPossiblyOffensive); + final boolean isNotAWord, final boolean isPossiblyOffensive) { + add(getCodePoints(word), probabilityInfo, isNotAWord, isPossiblyOffensive); } /** @@ -358,7 +307,7 @@ public final class FusionDictionary implements Iterable { if (ptNode0 != null) { final PtNode ptNode1 = findWordInTree(mRootNodeArray, word1); if (ptNode1 == null) { - add(getCodePoints(word1), new ProbabilityInfo(0), null, false /* isNotAWord */, + add(getCodePoints(word1), new ProbabilityInfo(0), false /* isNotAWord */, false /* isPossiblyOffensive */); // The PtNode for the first word may have moved by the above insertion, // if word1 and word2 share a common stem that happens not to have been @@ -376,15 +325,12 @@ public final class FusionDictionary implements Iterable { * * The shortcuts, if any, have to be in the dictionary already. If they aren't, * an exception is thrown. - * - * @param word the word, as an int array. + * @param word the word, as an int array. * @param probabilityInfo the probability information of the word. - * @param shortcutTargets an optional list of shortcut targets for this word (null if none). * @param isNotAWord true if this is not a word for spellcheking purposes (shortcut only or so) * @param isPossiblyOffensive true if this word is possibly offensive */ private void add(final int[] word, final ProbabilityInfo probabilityInfo, - final ArrayList shortcutTargets, final boolean isNotAWord, final boolean isPossiblyOffensive) { assert(probabilityInfo.mProbability <= FormatSpec.MAX_TERMINAL_FREQUENCY); if (word.length >= DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH) { @@ -414,7 +360,7 @@ public final class FusionDictionary implements Iterable { // No node at this point to accept the word. Create one. final int insertionIndex = findInsertionIndex(currentNodeArray, word[charIndex]); final PtNode newPtNode = new PtNode(Arrays.copyOfRange(word, charIndex, word.length), - shortcutTargets, null /* bigrams */, probabilityInfo, isNotAWord, + null /* bigrams */, probabilityInfo, isNotAWord, isPossiblyOffensive); currentNodeArray.mData.add(insertionIndex, newPtNode); if (DBG) checkStack(currentNodeArray); @@ -425,14 +371,14 @@ public final class FusionDictionary implements Iterable { // The new word is a prefix of an existing word, but the node on which it // should end already exists as is. Since the old PtNode was not a terminal, // make it one by filling in its frequency and other attributes - currentPtNode.update(probabilityInfo, shortcutTargets, null, isNotAWord, + currentPtNode.update(probabilityInfo, null, isNotAWord, isPossiblyOffensive); } else { // The new word matches the full old word and extends past it. // We only have to create a new node and add it to the end of this. final PtNode newNode = new PtNode( Arrays.copyOfRange(word, charIndex + differentCharIndex, word.length), - shortcutTargets, null /* bigrams */, probabilityInfo, + null /* bigrams */, probabilityInfo, isNotAWord, isPossiblyOffensive); currentPtNode.mChildren = new PtNodeArray(); currentPtNode.mChildren.mData.add(newNode); @@ -441,7 +387,7 @@ public final class FusionDictionary implements Iterable { if (0 == differentCharIndex) { // Exact same word. Update the frequency if higher. This will also add the // new shortcuts to the existing shortcut list if it already exists. - currentPtNode.update(probabilityInfo, shortcutTargets, null, + currentPtNode.update(probabilityInfo, null, currentPtNode.mIsNotAWord && isNotAWord, currentPtNode.mIsPossiblyOffensive || isPossiblyOffensive); } else { @@ -450,7 +396,7 @@ public final class FusionDictionary implements Iterable { PtNodeArray newChildren = new PtNodeArray(); final PtNode newOldWord = new PtNode( Arrays.copyOfRange(currentPtNode.mChars, differentCharIndex, - currentPtNode.mChars.length), currentPtNode.mShortcutTargets, + currentPtNode.mChars.length), currentPtNode.mBigrams, currentPtNode.mProbabilityInfo, currentPtNode.mIsNotAWord, currentPtNode.mIsPossiblyOffensive, currentPtNode.mChildren); @@ -460,17 +406,17 @@ public final class FusionDictionary implements Iterable { if (charIndex + differentCharIndex >= word.length) { newParent = new PtNode( Arrays.copyOfRange(currentPtNode.mChars, 0, differentCharIndex), - shortcutTargets, null /* bigrams */, probabilityInfo, + null /* bigrams */, probabilityInfo, isNotAWord, isPossiblyOffensive, newChildren); } else { newParent = new PtNode( Arrays.copyOfRange(currentPtNode.mChars, 0, differentCharIndex), - null /* shortcutTargets */, null /* bigrams */, - null /* probabilityInfo */, false /* isNotAWord */, - false /* isPossiblyOffensive */, newChildren); + null /* bigrams */, null /* probabilityInfo */, + false /* isNotAWord */, false /* isPossiblyOffensive */, + newChildren); final PtNode newWord = new PtNode(Arrays.copyOfRange(word, charIndex + differentCharIndex, word.length), - shortcutTargets, null /* bigrams */, probabilityInfo, + null /* bigrams */, probabilityInfo, isNotAWord, isPossiblyOffensive); final int addIndex = word[charIndex + differentCharIndex] > currentPtNode.mChars[differentCharIndex] ? 1 : 0; @@ -532,7 +478,7 @@ public final class FusionDictionary implements Iterable { private static int findInsertionIndex(final PtNodeArray nodeArray, int character) { final ArrayList data = nodeArray.mData; final PtNode reference = new PtNode(new int[] { character }, - null /* shortcutTargets */, null /* bigrams */, null /* probabilityInfo */, + null /* bigrams */, null /* probabilityInfo */, false /* isNotAWord */, false /* isPossiblyOffensive */); int result = Collections.binarySearch(data, reference, PTNODE_COMPARATOR); return result >= 0 ? result : -result - 1; @@ -669,8 +615,7 @@ public final class FusionDictionary implements Iterable { } if (currentPtNode.isTerminal()) { return new WordProperty(mCurrentString.toString(), - currentPtNode.mProbabilityInfo, - currentPtNode.mShortcutTargets, currentPtNode.mBigrams, + currentPtNode.mProbabilityInfo, currentPtNode.mBigrams, currentPtNode.mIsNotAWord, currentPtNode.mIsPossiblyOffensive); } } else { diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java index 5c261a94d..7ee1df92b 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java +++ b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java @@ -285,7 +285,7 @@ public class Ver2DictDecoder extends AbstractDictDecoder { // Insert unigrams into the fusion dictionary. for (final WordProperty wordProperty : wordProperties) { fusionDict.add(wordProperty.mWord, wordProperty.mProbabilityInfo, - wordProperty.mShortcutTargets, wordProperty.mIsNotAWord, + wordProperty.mIsNotAWord, wordProperty.mIsPossiblyOffensive); } // Insert bigrams into the fusion dictionary. diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java index b52b8c485..c63b972eb 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java +++ b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java @@ -239,37 +239,6 @@ public class Ver2DictEncoder implements DictEncoder { childrenPos); } - /** - * Write a shortcut attributes list to mBuffer. - * - * @param shortcuts the shortcut attributes list. - */ - private void writeShortcuts(final ArrayList shortcuts, - final HashMap codePointToOneByteCodeMap) { - if (null == shortcuts || shortcuts.isEmpty()) return; - - final int indexOfShortcutByteSize = mPosition; - mPosition += FormatSpec.PTNODE_SHORTCUT_LIST_SIZE_SIZE; - final Iterator shortcutIterator = shortcuts.iterator(); - while (shortcutIterator.hasNext()) { - final WeightedString target = shortcutIterator.next(); - final int shortcutFlags = BinaryDictEncoderUtils.makeShortcutFlags( - shortcutIterator.hasNext(), - target.getProbability()); - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, shortcutFlags, - FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE); - final int shortcutShift = CharEncoding.writeString(mBuffer, mPosition, target.mWord, - codePointToOneByteCodeMap); - mPosition += shortcutShift; - } - final int shortcutByteSize = mPosition - indexOfShortcutByteSize; - if (shortcutByteSize > FormatSpec.MAX_SHORTCUT_LIST_SIZE_IN_A_PTNODE) { - throw new RuntimeException("Shortcut list too large"); - } - BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, indexOfShortcutByteSize, shortcutByteSize, - FormatSpec.PTNODE_SHORTCUT_LIST_SIZE_SIZE); - } - /** * Write a bigram attributes list to mBuffer. * @@ -305,8 +274,6 @@ public class Ver2DictEncoder implements DictEncoder { writeCharacters(ptNode.mChars, ptNode.hasSeveralChars(), codePointToOneByteCodeMap); writeFrequency(ptNode.getProbability()); writeChildrenPosition(ptNode, codePointToOneByteCodeMap); - // TODO: Use codePointToOneByteCodeMap for shortcuts. - writeShortcuts(ptNode.mShortcutTargets, null /* codePointToOneByteCodeMap */); writeBigrams(ptNode.mBigrams, dict); } } diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoderTests.java index 7d858760e..dbf9b7ac2 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoderTests.java +++ b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoderTests.java @@ -16,9 +16,7 @@ package com.android.inputmethod.latin.makedict; -import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.Map.Entry; @@ -49,7 +47,7 @@ public class Ver2DictEncoderTests extends AndroidTestCase { new FormatSpec.FormatOptions(FormatSpec.VERSION2); final FusionDictionary sourcedict = new FusionDictionary(new PtNodeArray(), BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions)); - addUnigrams(sourcedict, words, null /* shortcutMap */); + addUnigrams(sourcedict, words); final CodePointTable codePointTable = Ver2DictEncoder.makeCodePointTable(sourcedict); // Check if mCodePointOccurrenceArray is correct @@ -73,17 +71,10 @@ public class Ver2DictEncoderTests extends AndroidTestCase { /** * Adds unigrams to the dictionary. */ - private static void addUnigrams(final FusionDictionary dict, final List words, - final HashMap> shortcutMap) { + private static void addUnigrams(final FusionDictionary dict, final List words) { for (final String word : words) { - final ArrayList shortcuts = new ArrayList<>(); - if (shortcutMap != null && shortcutMap.containsKey(word)) { - for (final String shortcut : shortcutMap.get(word)) { - shortcuts.add(new WeightedString(shortcut, UNIGRAM_FREQ)); - } - } dict.add(word, new ProbabilityInfo(UNIGRAM_FREQ), - (shortcutMap == null) ? null : shortcuts, false /* isNotAWord */, + false /* isNotAWord */, false /* isPossiblyOffensive */); } } diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java index 63ea89c1d..746431dfa 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java +++ b/tests/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java @@ -84,7 +84,7 @@ public class Ver4DictDecoder extends AbstractDictDecoder { // Insert unigrams into the fusion dictionary. for (final WordProperty wordProperty : wordProperties) { fusionDict.add(wordProperty.mWord, wordProperty.mProbabilityInfo, - wordProperty.mShortcutTargets, wordProperty.mIsNotAWord, + wordProperty.mIsNotAWord, wordProperty.mIsPossiblyOffensive); } // Insert bigrams into the fusion dictionary. diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java index 1e4bd768c..6e7b37d54 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java +++ b/tests/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java @@ -74,26 +74,10 @@ public class Ver4DictEncoder implements DictEncoder { throw new IOException("Cannot create dictionary file"); } for (final WordProperty wordProperty : dict) { - // TODO: switch to addMultipleDictionaryEntries when they support shortcuts - if (null == wordProperty.mShortcutTargets || wordProperty.mShortcutTargets.isEmpty()) { - if (!binaryDict.addUnigramEntry(wordProperty.mWord, wordProperty.getProbability(), - null /* shortcutTarget */, 0 /* shortcutProbability */, - wordProperty.mIsBeginningOfSentence, wordProperty.mIsNotAWord, - wordProperty.mIsPossiblyOffensive, 0 /* timestamp */)) { - MakedictLog.e("Cannot add unigram entry for " + wordProperty.mWord); - } - } else { - for (final WeightedString shortcutTarget : wordProperty.mShortcutTargets) { - if (!binaryDict.addUnigramEntry(wordProperty.mWord, - wordProperty.getProbability(), - shortcutTarget.mWord, shortcutTarget.getProbability(), - wordProperty.mIsBeginningOfSentence, wordProperty.mIsNotAWord, - wordProperty.mIsPossiblyOffensive, 0 /* timestamp */)) { - MakedictLog.e("Cannot add unigram entry for " + wordProperty.mWord - + ", shortcutTarget: " + shortcutTarget.mWord); - return; - } - } + if (!binaryDict.addUnigramEntry(wordProperty.mWord, wordProperty.getProbability(), + wordProperty.mIsBeginningOfSentence, wordProperty.mIsNotAWord, + wordProperty.mIsPossiblyOffensive, 0 /* timestamp */)) { + MakedictLog.e("Cannot add unigram entry for " + wordProperty.mWord); } if (binaryDict.needsToRunGC(true /* mindsBlockByGC */)) { if (!binaryDict.flushWithGC()) {