diff options
27 files changed, 146 insertions, 1316 deletions
diff --git a/java-overridable/src/com/android/inputmethod/latin/touchinputconsumer/GestureConsumer.java b/java-overridable/src/com/android/inputmethod/latin/touchinputconsumer/GestureConsumer.java index 7a5d2e68f..8291b4f72 100644 --- a/java-overridable/src/com/android/inputmethod/latin/touchinputconsumer/GestureConsumer.java +++ b/java-overridable/src/com/android/inputmethod/latin/touchinputconsumer/GestureConsumer.java @@ -19,6 +19,7 @@ package com.android.inputmethod.latin.touchinputconsumer; import android.view.inputmethod.EditorInfo; import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.common.InputPointers; import com.android.inputmethod.latin.inputlogic.PrivateCommandPerformer; @@ -62,6 +63,7 @@ public class GestureConsumer { } public void onImeSuggestionsProcessed(final SuggestedWords suggestedWords, - final int composingStart, final int composingLength) { + final int composingStart, final int composingLength, + final DictionaryFacilitator dictionaryFacilitator) { } } diff --git a/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java b/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java index b8f835ee3..c069a0f64 100644 --- a/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java +++ b/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java @@ -72,7 +72,8 @@ public final class StatsUtils { } public static void onAutoCorrection(final String typedWord, final String autoCorrectionWord, - final boolean isBatchInput, final DictionaryFacilitator dictionaryType) { + final boolean isBatchInput, final DictionaryFacilitator dictionaryFacilitator, + final String prevWordsContext) { } public static void onWordCommitUserTyped(final String commitWord, final boolean isBatchMode) { diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml index 654157912..210d9a964 100644 --- a/java/AndroidManifest.xml +++ b/java/AndroidManifest.xml @@ -133,7 +133,7 @@ </intent-filter> </receiver> - <receiver android:name=".DictionaryPackInstallBroadcastReceiver" android:exported="false"> + <receiver android:name="DictionaryPackInstallBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="com.android.inputmethod.dictionarypack.aosp.UNKNOWN_CLIENT" /> </intent-filter> @@ -148,8 +148,7 @@ </receiver> <!-- Broadcast receiver for AccountManager#LOGIN_ACCOUNTS_CHANGED_ACTION. --> - <receiver - android:name=".accounts.AccountsChangedReceiver"> + <receiver android:name=".accounts.AccountsChangedReceiver"> <intent-filter> <action android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" /> </intent-filter> diff --git a/java/res/values/donottranslate-debug-settings.xml b/java/res/values/donottranslate-debug-settings.xml index 491043f1a..9df73ae4f 100644 --- a/java/res/values/donottranslate-debug-settings.xml +++ b/java/res/values/donottranslate-debug-settings.xml @@ -41,20 +41,10 @@ <string name="prefs_key_popup_dismiss_end_x_scale_settings">Key popup dismiss end X scale</string> <!-- Title of the settings for key popup dismiss animation end Y-scale (in percentile) [CHAR LIMIT=35] --> <string name="prefs_key_popup_dismiss_end_y_scale_settings">Key popup dismiss end Y scale</string> - <!-- Title of the settings for reading an external dictionary file --> - <string name="prefs_read_external_dictionary">Read external dictionary file</string> <!-- Title of the settings to enable keyboard resizing --> <string name="prefs_resize_keyboard">Enable keyboard resizing</string> <!-- Title of the settings for setting keyboard height --> <string name="prefs_keyboard_height_scale">Keyboard height scale</string> - <!-- Message to show when there are no files to install as an external dictionary [CHAR LIMIT=100] --> - <string name="read_external_dictionary_no_files_message">No dictionary files in the Downloads folder</string> - <!-- Title of the dialog that selects a file to install as an external dictionary [CHAR LIMIT=50] --> - <string name="read_external_dictionary_multiple_files_title">Select a dictionary file to install</string> - <!-- Title of the confirmation dialog to install a file as an external dictionary [CHAR LIMIT=50] --> - <string name="read_external_dictionary_confirm_install_message">Really install this file for <xliff:g id="LANGUAGE_NAME" example="English">%s</xliff:g>?</string> - <!-- Title for an error dialog that contains the details of the error in the body [CHAR LIMIT=80] --> - <string name="read_external_dictionary_error">There was an error</string> <!-- Title of the settings group for dumpping dictionary files that have been created on the device [CHAR LIMIT=35] --> <string name="prefs_dump_dynamic_dicts">Dump dictionary</string> </resources> diff --git a/java/res/xml/prefs_screen_debug.xml b/java/res/xml/prefs_screen_debug.xml index 905bc045c..1ae2d0e9f 100644 --- a/java/res/xml/prefs_screen_debug.xml +++ b/java/res/xml/prefs_screen_debug.xml @@ -87,9 +87,6 @@ android:title="@string/prefs_keyboard_height_scale" latin:minValue="50" latin:maxValue="120" /> <!-- percentage --> - <PreferenceScreen - android:key="read_external_dictionary" - android:title="@string/prefs_read_external_dictionary" /> <PreferenceCategory android:key="pref_key_dump_dictionaries" android:title="@string/prefs_dump_dynamic_dicts"> diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java index 14e005007..88ea4e6c3 100644 --- a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java +++ b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java @@ -28,6 +28,7 @@ import android.database.Cursor; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; +import android.os.AsyncTask; import android.os.Bundle; import android.preference.Preference; import android.preference.PreferenceFragment; @@ -106,16 +107,27 @@ public final class DictionarySettingsFragment extends PreferenceFragment @Override public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { - final String metadataUri = - MetadataDbHelper.getMetadataUriAsString(getActivity(), mClientId); - // We only add the "Refresh" button if we have a non-empty URL to refresh from. If the - // URL is empty, of course we can't refresh so it makes no sense to display this. - if (!TextUtils.isEmpty(metadataUri)) { - mUpdateNowMenu = - menu.add(Menu.NONE, MENU_UPDATE_NOW, 0, R.string.check_for_updates_now); - mUpdateNowMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - refreshNetworkState(); - } + new AsyncTask<Void, Void, String>() { + @Override + protected String doInBackground(Void... params) { + return MetadataDbHelper.getMetadataUriAsString(getActivity(), mClientId); + } + + @Override + protected void onPostExecute(String metadataUri) { + // We only add the "Refresh" button if we have a non-empty URL to refresh from. If + // the URL is empty, of course we can't refresh so it makes no sense to display + // this. + if (!TextUtils.isEmpty(metadataUri)) { + if (mUpdateNowMenu == null) { + mUpdateNowMenu = menu.add(Menu.NONE, MENU_UPDATE_NOW, 0, + R.string.check_for_updates_now); + mUpdateNowMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + } + refreshNetworkState(); + } + } + }.execute(); } @Override @@ -124,18 +136,25 @@ public final class DictionarySettingsFragment extends PreferenceFragment mChangedSettings = false; UpdateHandler.registerUpdateEventListener(this); final Activity activity = getActivity(); - if (!MetadataDbHelper.isClientKnown(activity, mClientId)) { - Log.i(TAG, "Unknown dictionary pack client: " + mClientId + ". Requesting info."); - final Intent unknownClientBroadcast = - new Intent(DictionaryPackConstants.UNKNOWN_DICTIONARY_PROVIDER_CLIENT); - unknownClientBroadcast.putExtra( - DictionaryPackConstants.DICTIONARY_PROVIDER_CLIENT_EXTRA, mClientId); - activity.sendBroadcast(unknownClientBroadcast); - } final IntentFilter filter = new IntentFilter(); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); getActivity().registerReceiver(mConnectivityChangedReceiver, filter); refreshNetworkState(); + + new Thread("onResume") { + @Override + public void run() { + if (!MetadataDbHelper.isClientKnown(activity, mClientId)) { + Log.i(TAG, "Unknown dictionary pack client: " + mClientId + + ". Requesting info."); + final Intent unknownClientBroadcast = + new Intent(DictionaryPackConstants.UNKNOWN_DICTIONARY_PROVIDER_CLIENT); + unknownClientBroadcast.putExtra( + DictionaryPackConstants.DICTIONARY_PROVIDER_CLIENT_EXTRA, mClientId); + activity.sendBroadcast(unknownClientBroadcast); + } + } + }.start(); } @Override @@ -375,8 +394,13 @@ public final class DictionarySettingsFragment extends PreferenceFragment private void cancelRefresh() { UpdateHandler.unregisterUpdateEventListener(this); final Context context = getActivity(); - UpdateHandler.cancelUpdate(context, mClientId); - stopLoadingAnimation(); + new Thread("cancelByHand") { + @Override + public void run() { + UpdateHandler.cancelUpdate(context, mClientId); + stopLoadingAnimation(); + } + }.start(); } private void startLoadingAnimation() { diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 7f4631b2d..9a3ac674e 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -27,7 +27,6 @@ import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.common.FileUtils; import com.android.inputmethod.latin.common.InputPointers; import com.android.inputmethod.latin.common.StringUtils; -import com.android.inputmethod.latin.define.DecoderSpecificConstants; import com.android.inputmethod.latin.makedict.DictionaryHeader; import com.android.inputmethod.latin.makedict.FormatSpec; import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions; @@ -330,7 +329,9 @@ public final class BinaryDictionary extends Dictionary { if (len > 0) { suggestions.add(new SuggestedWordInfo( new String(session.mOutputCodePoints, start, len), - (int)(session.mOutputScores[j] * weightForLocale), session.mOutputTypes[j], + "" /* prevWordsContext */, + (int)(session.mOutputScores[j] * weightForLocale), + session.mOutputTypes[j], this /* sourceDict */, session.mSpaceIndices[j] /* indexOfTouchPointOfSecondWord */, session.mOutputAutoCommitFirstWordConfidence[0])); diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java index 5f981a009..6b49f9aa6 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java @@ -89,6 +89,24 @@ public interface DictionaryFacilitator { void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable); } + /** + * Called every time {@link LatinIME} starts on a new text field. + * Dot not affect {@link AndroidSpellCheckerService}. + * + * WARNING: The service methods that call start/finish are very spammy. + */ + void onStartInput(); + + /** + * Called every time the {@link LatinIME} finishes with the current text field. + * May be followed by {@link #onStartInput} again in another text field, + * or it may be done for a while. + * Dot not affect {@link AndroidSpellCheckerService}. + * + * WARNING: The service methods that call start/finish are very spammy. + */ + void onFinishInput(); + boolean isActive(); Locale getLocale(); diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java index a59253aad..e5d770aee 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java @@ -202,6 +202,15 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { public DictionaryFacilitatorImpl() { } + @Override + public void onStartInput() { + } + + @Override + public void onFinishInput() { + } + + @Override public boolean isActive() { return mDictionaryGroup.mLocale != null; } diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index fa8fb2028..80daedd50 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -121,8 +121,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { private static boolean needsToMigrateDictionary(final int formatVersion) { // When we bump up the dictionary format version, the old version should be added to here // for supporting migration. Note that native code has to support reading such formats. - return formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING - || formatVersion == FormatSpec.VERSION402; + return formatVersion == FormatSpec.VERSION402; } public boolean isValidDictionaryLocked() { diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index a8aeb8795..330be377b 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -792,6 +792,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @SuppressWarnings("deprecation") void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) { super.onStartInputView(editorInfo, restarting); + + mDictionaryFacilitator.onStartInput(); // Switch to the null consumer to handle cases leading to early exit below, for which we // also wouldn't be consuming gesture data. mGestureConsumer = GestureConsumer.NULL_GESTURE_CONSUMER; @@ -970,6 +972,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen void onFinishInputInternal() { super.onFinishInput(); + mDictionaryFacilitator.onFinishInput(); final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); if (mainKeyboardView != null) { mainKeyboardView.closing(); @@ -1383,7 +1386,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void onUpdateBatchInput(final InputPointers batchPointers) { - mInputLogic.onUpdateBatchInput(mSettings.getCurrent(), batchPointers, mKeyboardSwitcher); + mInputLogic.onUpdateBatchInput(batchPointers); } @Override @@ -1407,7 +1410,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen */ public void onTailBatchInputResultShown(final SuggestedWords suggestedWords) { mGestureConsumer.onImeSuggestionsProcessed(suggestedWords, - mInputLogic.getComposingStart(), mInputLogic.getComposingLength()); + mInputLogic.getComposingStart(), mInputLogic.getComposingLength(), + mDictionaryFacilitator); } // This method must run on the UI Thread. @@ -1537,7 +1541,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen setSuggestedWords(neutralSuggestions); } - // TODO: Make this private // Outside LatinIME, only used by the {@link InputTestsBase} test suite. @UsedForTesting void loadKeyboard() { @@ -1768,7 +1771,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen dialog.show(); } - // TODO: can this be removed somehow without breaking the tests? @UsedForTesting SuggestedWords getSuggestedWordsForTest() { // You may not use this method for anything else than debug diff --git a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java index c9b6d6b70..e2c562174 100644 --- a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java +++ b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java @@ -114,7 +114,8 @@ public final class PunctuationSuggestions extends SuggestedWords { } private static SuggestedWordInfo newHardCodedWordInfo(final String keySpec) { - return new SuggestedWordInfo(keySpec, SuggestedWordInfo.MAX_SCORE, + return new SuggestedWordInfo(keySpec, "" /* prevWordsContext */, + SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED, Dictionary.DICTIONARY_HARDCODED, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 8562acd83..7ccefd2dd 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -36,7 +36,6 @@ import java.util.HashMap; import java.util.Locale; import javax.annotation.Nonnull; -import javax.annotation.Nullable; /** * This class loads a dictionary and provides a list of suggestions for a given sequence of @@ -249,7 +248,8 @@ public final class Suggest { } final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString, - SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED, + "" /* prevWordsContext */, SuggestedWordInfo.MAX_SCORE, + SuggestedWordInfo.KIND_TYPED, null == sourceDictionaryOfRemovedWord ? Dictionary.DICTIONARY_USER_TYPED : sourceDictionaryOfRemovedWord, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, @@ -426,7 +426,8 @@ public final class Suggest { for (int i = quotesToAppend - 1; i >= 0; --i) { sb.appendCodePoint(Constants.CODE_SINGLE_QUOTE); } - return new SuggestedWordInfo(sb.toString(), wordInfo.mScore, wordInfo.mKindAndFlags, + return new SuggestedWordInfo(sb.toString(), wordInfo.mPrevWordsContext, + wordInfo.mScore, wordInfo.mKindAndFlags, wordInfo.mSourceDict, wordInfo.mIndexOfTouchPointOfSecondWord, wordInfo.mAutoCommitFirstWordConfidence); } diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index 87fe29159..bcd4d5f69 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -17,11 +17,9 @@ package com.android.inputmethod.latin; import android.text.TextUtils; -import android.util.Log; import android.view.inputmethod.CompletionInfo; import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.common.StringUtils; import com.android.inputmethod.latin.define.DebugFlags; @@ -264,6 +262,7 @@ public class SuggestedWords { public static final int KIND_FLAG_APPROPRIATE_FOR_AUTO_CORRECTION = 0x10000000; public final String mWord; + public final String mPrevWordsContext; // The completion info from the application. Null for suggestions that don't come from // the application (including keyboard-computed ones, so this is almost always null) public final CompletionInfo mApplicationSpecifiedCompletionInfo; @@ -284,6 +283,7 @@ public class SuggestedWords { /** * Create a new suggested word info. * @param word The string to suggest. + * @param prevWordsContext previous words context. * @param score A measure of how likely this suggestion is. * @param kindAndFlags The kind of suggestion, as one of the above KIND_* constants with * flags. @@ -291,10 +291,12 @@ public class SuggestedWords { * @param indexOfTouchPointOfSecondWord See mIndexOfTouchPointOfSecondWord. * @param autoCommitFirstWordConfidence See mAutoCommitFirstWordConfidence. */ - public SuggestedWordInfo(final String word, final int score, final int kindAndFlags, + public SuggestedWordInfo(final String word, final String prevWordsContext, + final int score, final int kindAndFlags, final Dictionary sourceDict, final int indexOfTouchPointOfSecondWord, final int autoCommitFirstWordConfidence) { mWord = word; + mPrevWordsContext = prevWordsContext; mApplicationSpecifiedCompletionInfo = null; mScore = score; mKindAndFlags = kindAndFlags; @@ -311,6 +313,7 @@ public class SuggestedWords { */ public SuggestedWordInfo(final CompletionInfo applicationSpecifiedCompletion) { mWord = applicationSpecifiedCompletion.getText().toString(); + mPrevWordsContext = ""; mApplicationSpecifiedCompletionInfo = applicationSpecifiedCompletion; mScore = SuggestedWordInfo.MAX_SCORE; mKindAndFlags = SuggestedWordInfo.KIND_APP_DEFINED; @@ -429,27 +432,6 @@ public class SuggestedWords { return isPrediction(mInputStyle); } - // Creates a new SuggestedWordInfo from the currently suggested words that removes all but the - // last word of all suggestions, separated by a space. This is necessary because when we commit - // a multiple-word suggestion, the IME only retains the last word as the composing word, and - // we should only suggest replacements for this last word. - // TODO: make this work with languages without spaces. - public SuggestedWords getSuggestedWordsForLastWordOfPhraseGesture() { - final ArrayList<SuggestedWordInfo> newSuggestions = new ArrayList<>(); - for (int i = 0; i < mSuggestedWordInfoList.size(); ++i) { - final SuggestedWordInfo info = mSuggestedWordInfoList.get(i); - final int indexOfLastSpace = info.mWord.lastIndexOf(Constants.CODE_SPACE) + 1; - final String lastWord = info.mWord.substring(indexOfLastSpace); - newSuggestions.add(new SuggestedWordInfo(lastWord, info.mScore, info.mKindAndFlags, - info.mSourceDict, SuggestedWordInfo.NOT_AN_INDEX, - SuggestedWordInfo.NOT_A_CONFIDENCE)); - } - return new SuggestedWords(newSuggestions, null /* rawSuggestions */, - newSuggestions.isEmpty() ? null : newSuggestions.get(0) /* typedWordInfo */, - mTypedWordValid, mWillAutoCorrect, mIsObsoleteSuggestions, INPUT_STYLE_TAIL_BATCH, - NOT_A_SEQUENCE_NUMBER); - } - /** * @return the {@link SuggestedWordInfo} which corresponds to the word that is originally * typed by the user. Otherwise returns {@code null}. Note that gesture input is not diff --git a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java deleted file mode 100644 index 8cc3552ed..000000000 --- a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java +++ /dev/null @@ -1,189 +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.latin.debug; - -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnCancelListener; -import android.content.DialogInterface.OnClickListener; -import android.os.Environment; - -import com.android.inputmethod.latin.BinaryDictionaryFileDumper; -import com.android.inputmethod.latin.BinaryDictionaryGetter; -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.common.LocaleUtils; -import com.android.inputmethod.latin.makedict.DictionaryHeader; -import com.android.inputmethod.latin.utils.DialogUtils; -import com.android.inputmethod.latin.utils.DictionaryInfoUtils; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Locale; - -/** - * A class to read a local file as a dictionary for debugging purposes. - */ -public class ExternalDictionaryGetterForDebug { - static final String SOURCE_FOLDER = Environment.getExternalStorageDirectory().getPath() - + "/Download"; - - private static String[] findDictionariesInTheDownloadedFolder() { - final File[] files = new File(SOURCE_FOLDER).listFiles(); - final ArrayList<String> eligibleList = new ArrayList<>(); - for (File f : files) { - final DictionaryHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(f); - if (null == header) continue; - eligibleList.add(f.getName()); - } - return eligibleList.toArray(new String[0]); - } - - public static void chooseAndInstallDictionary(final Context context) { - final String[] fileNames = findDictionariesInTheDownloadedFolder(); - if (0 == fileNames.length) { - showNoFileDialog(context); - } else if (1 == fileNames.length) { - askInstallFile(context, SOURCE_FOLDER, fileNames[0], null /* completeRunnable */); - } else { - showChooseFileDialog(context, fileNames); - } - } - - private static void showNoFileDialog(final Context context) { - new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context)) - .setMessage(R.string.read_external_dictionary_no_files_message) - .setPositiveButton(android.R.string.ok, new OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int which) { - dialog.dismiss(); - } - }).create().show(); - } - - private static void showChooseFileDialog(final Context context, final String[] fileNames) { - new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context)) - .setTitle(R.string.read_external_dictionary_multiple_files_title) - .setItems(fileNames, new OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int which) { - askInstallFile(context, SOURCE_FOLDER, fileNames[which], - null /* completeRunnable */); - } - }) - .create().show(); - } - - /** - * Shows a dialog which offers the user to install the external dictionary. - */ - public static void askInstallFile(final Context context, final String dirPath, - final String fileName, final Runnable completeRunnable) { - final File file = new File(dirPath, fileName.toString()); - final DictionaryHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(file); - final StringBuilder message = new StringBuilder(); - final String localeString = header.mLocaleString; - for (final String key : header.mDictionaryOptions.mAttributes.keySet()) { - message.append(key + " = " + header.mDictionaryOptions.mAttributes.get(key)); - message.append("\n"); - } - final String languageName = LocaleUtils.constructLocaleFromString(localeString) - .getDisplayName(Locale.getDefault()); - final String title = String.format( - context.getString(R.string.read_external_dictionary_confirm_install_message), - languageName); - new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context)) - .setTitle(title) - .setMessage(message) - .setNegativeButton(android.R.string.cancel, new OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int which) { - dialog.dismiss(); - if (completeRunnable != null) { - completeRunnable.run(); - } - } - }).setPositiveButton(android.R.string.ok, new OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int which) { - installFile(context, file, header); - dialog.dismiss(); - if (completeRunnable != null) { - completeRunnable.run(); - } - } - }).setOnCancelListener(new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - // Canceled by the user by hitting the back key - if (completeRunnable != null) { - completeRunnable.run(); - } - } - }).create().show(); - } - - static void installFile(final Context context, final File file, final DictionaryHeader header) { - BufferedOutputStream outputStream = null; - File tempFile = null; - try { - final String localeString = header.mLocaleString; - // Create the id for a main dictionary for this locale - final String id = BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY - + BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + localeString; - final String finalFileName = DictionaryInfoUtils.getCacheFileName( - id, localeString, context); - final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context); - tempFile = new File(tempFileName); - tempFile.delete(); - outputStream = new BufferedOutputStream(new FileOutputStream(tempFile)); - final BufferedInputStream bufferedStream = new BufferedInputStream( - new FileInputStream(file)); - BinaryDictionaryFileDumper.checkMagicAndCopyFileTo(bufferedStream, outputStream); - outputStream.flush(); - final File finalFile = new File(finalFileName); - finalFile.delete(); - if (!tempFile.renameTo(finalFile)) { - throw new IOException("Can't move the file to its final name"); - } - } catch (IOException e) { - // There was an error: show a dialog - new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context)) - .setTitle(R.string.read_external_dictionary_error) - .setMessage(e.toString()) - .setPositiveButton(android.R.string.ok, new OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int which) { - dialog.dismiss(); - } - }).create().show(); - return; - } finally { - try { - if (null != outputStream) outputStream.close(); - if (null != tempFile) tempFile.delete(); - } catch (IOException e) { - // Don't do anything - } - } - } -} diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index 00175f024..5b3b28d75 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -225,9 +225,7 @@ public final class InputLogic { * @return the complete transaction object */ public InputTransaction onTextInput(final SettingsValues settingsValues, final Event event, - final int keyboardShiftMode, - // TODO: remove this argument - final LatinIME.UIHandler handler) { + final int keyboardShiftMode, final LatinIME.UIHandler handler) { final String rawText = event.getTextToCommit().toString(); final InputTransaction inputTransaction = new InputTransaction(settingsValues, event, SystemClock.uptimeMillis(), mSpaceState, @@ -266,12 +264,14 @@ public final class InputLogic { // interface public InputTransaction onPickSuggestionManually(final SettingsValues settingsValues, final SuggestedWordInfo suggestionInfo, final int keyboardShiftState, - // TODO: remove these arguments final int currentKeyboardScriptId, final LatinIME.UIHandler handler) { final SuggestedWords suggestedWords = mSuggestedWords; final String suggestion = suggestionInfo.mWord; // If this is a punctuation picked from the suggestion strip, pass it to onCodeInput if (suggestion.length() == 1 && suggestedWords.isPunctuationSuggestions()) { + // We still want to log a suggestion click. + StatsUtils.onPickSuggestionManually( + mSuggestedWords, suggestionInfo, mDictionaryFacilitator); // Word separators are suggested before the user inputs something. // Rely on onCodeInput to do the complicated swapping/stripping logic consistently. final Event event = Event.createPunctuationSuggestionPickedEvent(suggestionInfo); @@ -419,7 +419,6 @@ public final class InputLogic { */ public InputTransaction onCodeInput(final SettingsValues settingsValues, @Nonnull final Event event, final int keyboardShiftMode, - // TODO: remove these arguments final int currentKeyboardScriptId, final LatinIME.UIHandler handler) { final Event processedEvent = mWordComposer.processEvent(event); final InputTransaction inputTransaction = new InputTransaction(settingsValues, @@ -466,7 +465,6 @@ public final class InputLogic { } public void onStartBatchInput(final SettingsValues settingsValues, - // TODO: remove these arguments final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) { mInputLogicHandler.onStartBatchInput(); handler.showGesturePreviewAndSuggestionStrip( @@ -530,10 +528,7 @@ public final class InputLogic { * earlier sequence number. */ private int mAutoCommitSequenceNumber = 1; - public void onUpdateBatchInput(final SettingsValues settingsValues, - final InputPointers batchPointers, - // TODO: remove these arguments - final KeyboardSwitcher keyboardSwitcher) { + public void onUpdateBatchInput(final InputPointers batchPointers) { mInputLogicHandler.onUpdateBatchInput(batchPointers, mAutoCommitSequenceNumber); } @@ -542,7 +537,6 @@ public final class InputLogic { ++mAutoCommitSequenceNumber; } - // TODO: remove this argument public void onCancelBatchInput(final LatinIME.UIHandler handler) { mInputLogicHandler.onCancelBatchInput(); handler.showGesturePreviewAndSuggestionStrip( @@ -618,7 +612,6 @@ public final class InputLogic { * @param inputTransaction The transaction in progress. */ private void handleFunctionalEvent(final Event event, final InputTransaction inputTransaction, - // TODO: remove these arguments final int currentKeyboardScriptId, final LatinIME.UIHandler handler) { switch (event.mKeyCode) { case Constants.CODE_DELETE: @@ -670,7 +663,6 @@ public final class InputLogic { // handled in {@link KeyboardState#onEvent(Event,int)}. break; case Constants.CODE_SHIFT_ENTER: - // TODO: remove this object final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER, event.mKeyCode, event.mX, event.mY, event.isKeyRepeat()); handleNonSpecialCharacterEvent(tmpEvent, inputTransaction, handler); @@ -694,7 +686,6 @@ public final class InputLogic { */ private void handleNonFunctionalEvent(final Event event, final InputTransaction inputTransaction, - // TODO: remove this argument final LatinIME.UIHandler handler) { inputTransaction.setDidAffectContents(); switch (event.mCodePoint) { @@ -740,7 +731,6 @@ public final class InputLogic { */ private void handleNonSpecialCharacterEvent(final Event event, final InputTransaction inputTransaction, - // TODO: remove this argument final LatinIME.UIHandler handler) { final int codePoint = event.mCodePoint; mSpaceState = SpaceState.NONE; @@ -846,7 +836,6 @@ public final class InputLogic { * @param inputTransaction The transaction in progress. */ private void handleSeparatorEvent(final Event event, final InputTransaction inputTransaction, - // TODO: remove this argument final LatinIME.UIHandler handler) { final int codePoint = event.mCodePoint; final SettingsValues settingsValues = inputTransaction.mSettingsValues; @@ -954,7 +943,6 @@ public final class InputLogic { * @param inputTransaction The transaction in progress. */ private void handleBackspaceEvent(final Event event, final InputTransaction inputTransaction, - // TODO: remove this argument, put it into settingsValues final int currentKeyboardScriptId) { mSpaceState = SpaceState.NONE; mDeleteCount++; @@ -1158,7 +1146,6 @@ public final class InputLogic { settingsValues.mSpacingAndPunctuations, currentKeyboardScriptId); if (range == null) { - // TODO(zivkovic): Check for bad connection before getting this far. // Happens if we don't have an input connection at all. return false; } @@ -1408,7 +1395,8 @@ public final class InputLogic { public void onGetSuggestedWords(final SuggestedWords suggestedWords) { final String typedWordString = mWordComposer.getTypedWord(); final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo( - typedWordString, SuggestedWordInfo.MAX_SCORE, + typedWordString, "" /* prevWordsContext */, + SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_A_CONFIDENCE); @@ -1441,7 +1429,6 @@ public final class InputLogic { * to a cursor move, for example). In ICS, there is a platform bug that we need to work * around only when we come here at input start time. */ - // TODO: make this private. public void restartSuggestionsOnWordTouchedByCursor(final SettingsValues settingsValues, final boolean forStartInput, // TODO: remove this argument, put it into settingsValues @@ -1492,7 +1479,7 @@ public final class InputLogic { final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<>(); final String typedWordString = range.mWord.toString(); final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString, - SuggestedWords.MAX_SUGGESTIONS + 1, + "" /* prevWordsContext */, SuggestedWords.MAX_SUGGESTIONS + 1, SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */); @@ -1507,7 +1494,7 @@ public final class InputLogic { ++i; if (!TextUtils.equals(s, typedWordString)) { suggestions.add(new SuggestedWordInfo(s, - SuggestedWords.MAX_SUGGESTIONS - i, + "" /* prevWordsContext */, SuggestedWords.MAX_SUGGESTIONS - i, SuggestedWordInfo.KIND_RESUMED, Dictionary.DICTIONARY_RESUMED, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_A_CONFIDENCE @@ -1721,7 +1708,6 @@ public final class InputLogic { * @param nthPreviousWord reverse index of the word to get (1-indexed) * @return the information of previous words */ - // TODO: Make this private public NgramContext getNgramContextFromNthPreviousWordForSuggestion( final SpacingAndPunctuations spacingAndPunctuations, final int nthPreviousWord) { if (spacingAndPunctuations.mCurrentLanguageHasSpaces) { @@ -1951,9 +1937,7 @@ public final class InputLogic { * @param suggestedWords suggestedWords to use. */ public void onUpdateTailBatchInputCompleted(final SettingsValues settingsValues, - final SuggestedWords suggestedWords, - // TODO: remove this argument - final KeyboardSwitcher keyboardSwitcher) { + final SuggestedWords suggestedWords, final KeyboardSwitcher keyboardSwitcher) { final String batchInputText = suggestedWords.isEmpty() ? null : suggestedWords.getWord(0); if (TextUtils.isEmpty(batchInputText)) { return; @@ -1986,7 +1970,6 @@ public final class InputLogic { * @param settingsValues the current values of the settings. * @param separatorString the separator that's causing the commit, or NOT_A_SEPARATOR if none. */ - // TODO: Make this private public void commitTyped(final SettingsValues settingsValues, final String separatorString) { if (!mWordComposer.isComposingWord()) return; final String typedWord = mWordComposer.getTypedWord(); @@ -2015,9 +1998,7 @@ public final class InputLogic { * @param separator the separator that's causing the commit to happen. */ private void commitCurrentAutoCorrection(final SettingsValues settingsValues, - final String separator, - // TODO: Remove this argument. - final LatinIME.UIHandler handler) { + final String separator, final LatinIME.UIHandler handler) { // Complete any pending suggestions query first if (handler.hasPendingUpdateSuggestions()) { handler.cancelUpdateSuggestionStrip(); @@ -2053,8 +2034,11 @@ public final class InputLogic { mConnection.commitCorrection(new CorrectionInfo( mConnection.getExpectedSelectionEnd() - stringToCommit.length(), typedWord, stringToCommit)); + String prevWordsContext = (autoCorrectionOrNull != null) + ? autoCorrectionOrNull.mPrevWordsContext + : ""; StatsUtils.onAutoCorrection(typedWord, stringToCommit, isBatchMode, - mDictionaryFacilitator); + mDictionaryFacilitator, prevWordsContext); StatsUtils.onWordCommitAutoCorrect(stringToCommit, isBatchMode); } else { StatsUtils.onWordCommitUserTyped(stringToCommit, isBatchMode); @@ -2103,11 +2087,8 @@ public final class InputLogic { * @param remainingTries How many times we may try again before giving up. * @return whether true if the caches were successfully reset, false otherwise. */ - // TODO: make this private public boolean retryResetCachesAndReturnSuccess(final boolean tryResumeSuggestions, - final int remainingTries, - // TODO: remove these arguments - final LatinIME.UIHandler handler) { + final int remainingTries, final LatinIME.UIHandler handler) { final boolean shouldFinishComposition = mConnection.hasSelection() || !mConnection.isCursorPositionKnown(); if (!mConnection.resetCachesUponCursorMoveAndReturnSuccess( diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java index 288261bf0..e422c4cd2 100644 --- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java +++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java @@ -174,9 +174,6 @@ public final class FormatSpec { public static final int VERSION202 = 202; // format version for Fava Dictionaries. public static final int VERSION_DELIGHT3 = 86736212; - public static final int MINIMUM_SUPPORTED_VERSION_OF_CODE_POINT_TABLE = VERSION201; - // Dictionary version used for testing. - public static final int VERSION4_ONLY_FOR_TESTING = 399; public static final int VERSION402 = 402; public static final int VERSION403 = 403; public static final int VERSION4 = VERSION403; diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java index a56de1f69..37855377d 100644 --- a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java @@ -30,7 +30,6 @@ import android.preference.TwoStatePreference; import com.android.inputmethod.latin.DictionaryDumpBroadcastReceiver; import com.android.inputmethod.latin.DictionaryFacilitatorImpl; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.debug.ExternalDictionaryGetterForDebug; import com.android.inputmethod.latin.utils.ApplicationUtils; import com.android.inputmethod.latin.utils.ResourceUtils; @@ -43,12 +42,10 @@ import java.util.Locale; */ public final class DebugSettingsFragment extends SubScreenFragment implements OnPreferenceClickListener { - private static final String PREF_READ_EXTERNAL_DICTIONARY = "read_external_dictionary"; private static final String PREF_KEY_DUMP_DICTS = "pref_key_dump_dictionaries"; private static final String PREF_KEY_DUMP_DICT_PREFIX = "pref_key_dump_dictionaries"; private boolean mServiceNeedsRestart = false; - private Preference mReadExternalDictionaryPref; private TwoStatePreference mDebugMode; @Override @@ -60,11 +57,6 @@ public final class DebugSettingsFragment extends SubScreenFragment removePreference(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI); } - mReadExternalDictionaryPref = findPreference(PREF_READ_EXTERNAL_DICTIONARY); - if (mReadExternalDictionaryPref != null) { - mReadExternalDictionaryPref.setOnPreferenceClickListener(this); - } - final PreferenceGroup dictDumpPreferenceGroup = (PreferenceGroup)findPreference(PREF_KEY_DUMP_DICTS); for (final String dictName : DictionaryFacilitatorImpl.DICT_TYPE_TO_CLASS.keySet()) { @@ -111,11 +103,6 @@ public final class DebugSettingsFragment extends SubScreenFragment @Override public boolean onPreferenceClick(final Preference pref) { final Context context = getActivity(); - if (pref == mReadExternalDictionaryPref) { - ExternalDictionaryGetterForDebug.chooseAndInstallDictionary(context); - mServiceNeedsRestart = true; - return true; - } if (pref instanceof DictDumpPreference) { final DictDumpPreference dictDumpPref = (DictDumpPreference)pref; final String dictName = dictDumpPref.mDictName; diff --git a/tests/src/com/android/inputmethod/compat/SuggestionSpanUtilsTest.java b/tests/src/com/android/inputmethod/compat/SuggestionSpanUtilsTest.java index 7bbf965f9..daf412cc3 100644 --- a/tests/src/com/android/inputmethod/compat/SuggestionSpanUtilsTest.java +++ b/tests/src/com/android/inputmethod/compat/SuggestionSpanUtilsTest.java @@ -42,7 +42,8 @@ public class SuggestionSpanUtilsTest extends AndroidTestCase { * @return a new instance of {@link SuggestedWordInfo}. */ private static SuggestedWordInfo createWordInfo(final String word, final int kindAndFlags) { - return new SuggestedWordInfo(word, 1 /* score */, kindAndFlags, null /* sourceDict */, + return new SuggestedWordInfo(word, "" /* prevWordsContext */, 1 /* score */, kindAndFlags, + null /* sourceDict */, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */); } diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java index 89167f744..e92831c48 100644 --- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java +++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java @@ -42,8 +42,6 @@ import java.util.Random; public class BinaryDictionaryTests extends AndroidTestCase { private static final String TEST_DICT_FILE_EXTENSION = ".testDict"; private static final String TEST_LOCALE = "test"; - private static final int[] DICT_FORMAT_VERSIONS = - new int[] { FormatSpec.VERSION402, FormatSpec.VERSION403 }; private static final String DICTIONARY_ID = "TestBinaryDictionary"; private static boolean supportsNgram(final int formatVersion) { @@ -113,13 +111,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testIsValidDictionary() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testIsValidDictionary(formatVersion); - } - } - - private void testIsValidDictionary(final int formatVersion) { - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); assertTrue("binaryDictionary must be valid for existing valid dictionary file.", binaryDictionary.isValidDictionary()); @@ -134,20 +126,14 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testConstructingDictionaryOnMemory() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testConstructingDictionaryOnMemory(formatVersion); - } - } - - private void testConstructingDictionaryOnMemory(final int formatVersion) { - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); FileUtils.deleteRecursively(dictFile); assertFalse(dictFile.exists()); final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), - true /* useFullEditDistance */, Locale.getDefault(), TEST_LOCALE, formatVersion, - new HashMap<String, String>()); + true /* useFullEditDistance */, Locale.getDefault(), TEST_LOCALE, + FormatSpec.VERSION403, new HashMap<String, String>()); assertTrue(binaryDictionary.isValidDictionary()); - assertEquals(formatVersion, binaryDictionary.getFormatVersion()); + assertEquals(FormatSpec.VERSION403, binaryDictionary.getFormatVersion()); final int probability = 100; addUnigramWord(binaryDictionary, "word", probability); assertEquals(probability, binaryDictionary.getFrequency("word")); @@ -155,19 +141,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { binaryDictionary.flush(); assertTrue(dictFile.exists()); assertTrue(binaryDictionary.isValidDictionary()); - assertEquals(formatVersion, binaryDictionary.getFormatVersion()); + assertEquals(FormatSpec.VERSION403, binaryDictionary.getFormatVersion()); assertEquals(probability, binaryDictionary.getFrequency("word")); binaryDictionary.close(); } public void testAddTooLongWord() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddTooLongWord(formatVersion); - } - } - - private void testAddTooLongWord(final int formatVersion) { - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final StringBuffer stringBuilder = new StringBuffer(); for (int i = 0; i < BinaryDictionary.DICTIONARY_MAX_WORD_LENGTH; i++) { stringBuilder.append('a'); @@ -234,13 +214,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testAddUnigramWord() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddUnigramWord(formatVersion); - } - } - - private void testAddUnigramWord(final int formatVersion) { - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final int probability = 100; addUnigramWord(binaryDictionary, "aaa", probability); // Reallocate and create. @@ -267,16 +241,10 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testRandomlyAddUnigramWord() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testRandomlyAddUnigramWord(formatVersion); - } - } - - private void testRandomlyAddUnigramWord(final int formatVersion) { final int wordCount = 1000; final int codePointSetSize = 50; final long seed = System.currentTimeMillis(); - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final HashMap<String, Integer> probabilityMap = new HashMap<>(); // Test a word that isn't contained within the dictionary. @@ -295,13 +263,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testAddBigramWords() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddBigramWords(formatVersion); - } - } - - private void testAddBigramWords(final int formatVersion) { - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final int unigramProbability = 100; final int bigramProbability = 150; @@ -354,18 +316,12 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testRandomlyAddBigramWords() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testRandomlyAddBigramWords(formatVersion); - } - } - - private void testRandomlyAddBigramWords(final int formatVersion) { final int wordCount = 100; final int bigramCount = 1000; final int codePointSetSize = 50; final long seed = System.currentTimeMillis(); final Random random = new Random(seed); - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final ArrayList<String> words = new ArrayList<>(); final ArrayList<Pair<String, String>> bigramWords = new ArrayList<>(); @@ -406,15 +362,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testAddTrigramWords() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - if (supportsNgram(formatVersion)) { - testAddTrigramWords(formatVersion); - } - } - } - - private void testAddTrigramWords(final int formatVersion) { - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final int unigramProbability = 100; final int trigramProbability = 150; final int updatedTrigramProbability = 200; @@ -440,13 +388,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testFlushDictionary() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testFlushDictionary(formatVersion); - } - } - - private void testFlushDictionary(final int formatVersion) { - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); final int probability = 100; @@ -480,13 +422,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testFlushWithGCDictionary() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testFlushWithGCDictionary(formatVersion); - } - } - - private void testFlushWithGCDictionary(final int formatVersion) { - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); final int unigramProbability = 100; final int bigramProbability = 150; @@ -516,20 +452,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testAddBigramWordsAndFlashWithGC() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddBigramWordsAndFlashWithGC(formatVersion); - } - } - - // TODO: Evaluate performance of GC - private void testAddBigramWordsAndFlashWithGC(final int formatVersion) { final int wordCount = 100; final int bigramCount = 1000; final int codePointSetSize = 30; final long seed = System.currentTimeMillis(); final Random random = new Random(seed); - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); final ArrayList<String> words = new ArrayList<>(); @@ -575,12 +504,6 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testRandomOperationsAndFlashWithGC() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testRandomOperationsAndFlashWithGC(formatVersion); - } - } - - private void testRandomOperationsAndFlashWithGC(final int formatVersion) { final int maxUnigramCount = 5000; final int maxBigramCount = 10000; final HashMap<String, String> attributeMap = new HashMap<>(); @@ -596,7 +519,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { final long seed = System.currentTimeMillis(); final Random random = new Random(seed); - final File dictFile = createEmptyDictionaryWithAttributesAndGetFile(formatVersion, + final File dictFile = createEmptyDictionaryWithAttributesAndGetFile(FormatSpec.VERSION403, attributeMap); BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); @@ -675,19 +598,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testAddManyUnigramsAndFlushWithGC() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddManyUnigramsAndFlushWithGC(formatVersion); - } - } - - private void testAddManyUnigramsAndFlushWithGC(final int formatVersion) { final int flashWithGCIterationCount = 3; final int codePointSetSize = 50; final long seed = System.currentTimeMillis(); final Random random = new Random(seed); - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); final ArrayList<String> words = new ArrayList<>(); final HashMap<String, Integer> unigramProbabilities = new HashMap<>(); @@ -716,12 +633,6 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testUnigramAndBigramCount() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testUnigramAndBigramCount(formatVersion); - } - } - - private void testUnigramAndBigramCount(final int formatVersion) { final int maxUnigramCount = 5000; final int maxBigramCount = 10000; final HashMap<String, String> attributeMap = new HashMap<>(); @@ -734,7 +645,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { final int bigramCountPerIteration = 2000; final long seed = System.currentTimeMillis(); final Random random = new Random(seed); - final File dictFile = createEmptyDictionaryWithAttributesAndGetFile(formatVersion, + final File dictFile = createEmptyDictionaryWithAttributesAndGetFile(FormatSpec.VERSION403, attributeMap); final ArrayList<String> words = new ArrayList<>(); @@ -778,19 +689,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testGetWordProperties() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testGetWordProperties(formatVersion); - } - } - - private void testGetWordProperties(final int formatVersion) { final long seed = System.currentTimeMillis(); final Random random = new Random(seed); final int UNIGRAM_COUNT = 1000; final int BIGRAM_COUNT = 1000; final int codePointSetSize = 20; final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); final BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); final WordProperty invalidWordProperty = binaryDictionary.getWordProperty("dummyWord", @@ -869,19 +774,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testIterateAllWords() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testIterateAllWords(formatVersion); - } - } - - private void testIterateAllWords(final int formatVersion) { final long seed = System.currentTimeMillis(); final Random random = new Random(seed); final int UNIGRAM_COUNT = 1000; final int BIGRAM_COUNT = 1000; final int codePointSetSize = 20; final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final WordProperty invalidWordProperty = binaryDictionary.getWordProperty("dummyWord", false /* isBeginningOfSentence */); @@ -965,123 +864,8 @@ public class BinaryDictionaryTests extends AndroidTestCase { assertEquals(true, wordProperty.mIsPossiblyOffensive); } - public void testDictMigration() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testDictMigration(FormatSpec.VERSION4_ONLY_FOR_TESTING, formatVersion); - } - } - - private void testDictMigration(final int fromFormatVersion, final int toFormatVersion) { - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(fromFormatVersion); - final int unigramProbability = 100; - addUnigramWord(binaryDictionary, "aaa", unigramProbability); - addUnigramWord(binaryDictionary, "bbb", unigramProbability); - final int bigramProbability = 150; - addBigramWords(binaryDictionary, "aaa", "bbb", bigramProbability); - binaryDictionary.addUnigramEntry("ccc", unigramProbability, - false /* isBeginningOfSentence */, false /* isNotAWord */, - false /* isPossiblyOffensive */, 0 /* timestamp */); - binaryDictionary.addUnigramEntry("ddd", unigramProbability, - false /* isBeginningOfSentence */, - true /* isNotAWord */, true /* isPossiblyOffensive */, 0 /* timestamp */); - binaryDictionary.addNgramEntry(NgramContext.BEGINNING_OF_SENTENCE, - "aaa", bigramProbability, 0 /* timestamp */); - assertEquals(unigramProbability, binaryDictionary.getFrequency("aaa")); - assertEquals(unigramProbability, binaryDictionary.getFrequency("bbb")); - assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb")); - assertEquals(fromFormatVersion, binaryDictionary.getFormatVersion()); - assertTrue(binaryDictionary.migrateTo(toFormatVersion)); - assertTrue(binaryDictionary.isValidDictionary()); - assertEquals(toFormatVersion, binaryDictionary.getFormatVersion()); - assertEquals(unigramProbability, binaryDictionary.getFrequency("aaa")); - assertEquals(unigramProbability, binaryDictionary.getFrequency("bbb")); - assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bbb")); - assertEquals(bigramProbability, binaryDictionary.getNgramProbability( - NgramContext.BEGINNING_OF_SENTENCE, "aaa")); - assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb")); - WordProperty wordProperty = binaryDictionary.getWordProperty("ccc", - false /* isBeginningOfSentence */); - wordProperty = binaryDictionary.getWordProperty("ddd", - false /* isBeginningOfSentence */); - assertTrue(wordProperty.mIsPossiblyOffensive); - assertTrue(wordProperty.mIsNotAWord); - } - - public void testLargeDictMigration() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testLargeDictMigration(FormatSpec.VERSION4_ONLY_FOR_TESTING, formatVersion); - } - } - - private void testLargeDictMigration(final int fromFormatVersion, final int toFormatVersion) { - final int UNIGRAM_COUNT = 3000; - final int BIGRAM_COUNT = 3000; - final int codePointSetSize = 50; - final long seed = System.currentTimeMillis(); - final Random random = new Random(seed); - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(fromFormatVersion); - - final ArrayList<String> words = new ArrayList<>(); - final ArrayList<Pair<String, String>> bigrams = new ArrayList<>(); - final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); - final HashMap<String, Integer> unigramProbabilities = new HashMap<>(); - final HashMap<Pair<String, String>, Integer> bigramProbabilities = new HashMap<>(); - - 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); - if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { - binaryDictionary.flushWithGC(); - } - words.add(word); - unigramProbabilities.put(word, unigramProbability); - } - - for (int i = 0; i < BIGRAM_COUNT; i++) { - final int word0Index = random.nextInt(words.size()); - final int word1Index = random.nextInt(words.size()); - if (word0Index == word1Index) { - continue; - } - final String word0 = words.get(word0Index); - final String word1 = words.get(word1Index); - final int unigramProbability = unigramProbabilities.get(word1); - final int bigramProbability = - random.nextInt(0xFF - unigramProbability) + unigramProbability; - addBigramWords(binaryDictionary, word0, word1, bigramProbability); - if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { - binaryDictionary.flushWithGC(); - } - final Pair<String, String> bigram = new Pair<>(word0, word1); - bigrams.add(bigram); - bigramProbabilities.put(bigram, bigramProbability); - } - assertTrue(binaryDictionary.migrateTo(toFormatVersion)); - - for (final String word : words) { - assertEquals((int)unigramProbabilities.get(word), binaryDictionary.getFrequency(word)); - } - assertEquals(unigramProbabilities.size(), Integer.parseInt( - binaryDictionary.getPropertyForGettingStats(BinaryDictionary.UNIGRAM_COUNT_QUERY))); - - for (final Pair<String, String> bigram : bigrams) { - assertEquals((int)bigramProbabilities.get(bigram), - getBigramProbability(binaryDictionary, bigram.first, bigram.second)); - assertTrue(isValidBigram(binaryDictionary, bigram.first, bigram.second)); - } - assertEquals(bigramProbabilities.size(), Integer.parseInt( - binaryDictionary.getPropertyForGettingStats(BinaryDictionary.BIGRAM_COUNT_QUERY))); - } - public void testBeginningOfSentence() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testBeginningOfSentence(formatVersion); - } - } - - private void testBeginningOfSentence(final int formatVersion) { - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final int dummyProbability = 0; final NgramContext beginningOfSentenceContext = NgramContext.BEGINNING_OF_SENTENCE; final int bigramProbability = 200; diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java index ab4060a86..0d9b36ac0 100644 --- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java +++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java @@ -409,7 +409,8 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { } protected void pickSuggestionManually(final String suggestion) { - mLatinIME.pickSuggestionManually(new SuggestedWordInfo(suggestion, 1, + mLatinIME.pickSuggestionManually(new SuggestedWordInfo(suggestion, + "" /* prevWordsContext */, 1 /* score */, SuggestedWordInfo.KIND_CORRECTION, DICTIONARY_TEST, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */)); diff --git a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java index 657cec8d7..d465ce674 100644 --- a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java +++ b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java @@ -37,7 +37,7 @@ public class SuggestedWordsTests extends AndroidTestCase { private static SuggestedWordInfo createTypedWordInfo(final String word) { // Use 100 as the frequency because the numerical value does not matter as // long as it's > 1 and < INT_MAX. - return new SuggestedWordInfo(word, 100 /* score */, + return new SuggestedWordInfo(word, "" /* prevWordsContext */, 100 /* score */, SuggestedWordInfo.KIND_TYPED, null /* sourceDict */, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, @@ -52,7 +52,7 @@ public class SuggestedWordsTests extends AndroidTestCase { * @return a new instance of {@link SuggestedWordInfo}. */ private static SuggestedWordInfo createCorrectionWordInfo(final String word) { - return new SuggestedWordInfo(word, 1 /* score */, + return new SuggestedWordInfo(word, "" /* prevWordsContext */, 1 /* score */, SuggestedWordInfo.KIND_CORRECTION, null /* sourceDict */, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java index a432ca740..da1b32a8b 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java @@ -43,22 +43,12 @@ public final class BinaryDictIOUtils { */ public static DictDecoder getDictDecoder(final File dictFile, final long offset, final long length, final int bufferType) { - if (dictFile.isDirectory()) { - return new Ver4DictDecoder(dictFile); - } else if (dictFile.isFile()) { - return new Ver2DictDecoder(dictFile, offset, length, bufferType); - } - return null; + return new Ver4DictDecoder(dictFile); } public static DictDecoder getDictDecoder(final File dictFile, final long offset, final long length, final DictionaryBufferFactory factory) { - if (dictFile.isDirectory()) { - return new Ver4DictDecoder(dictFile); - } else if (dictFile.isFile()) { - return new Ver2DictDecoder(dictFile, offset, length, factory); - } - return null; + return new Ver4DictDecoder(dictFile); } public static DictDecoder getDictDecoder(final File dictFile, final long offset, diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java deleted file mode 100644 index 7ee1df92b..000000000 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java +++ /dev/null @@ -1,319 +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.latin.makedict; - -import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.BinaryDictionary; -import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding; -import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; - -/** - * An implementation of DictDecoder for version 2 binary dictionary. - */ -// TODO: Separate logics that are used only for testing. -@UsedForTesting -public class Ver2DictDecoder extends AbstractDictDecoder { - /** - * A utility class for reading a PtNode. - */ - static class PtNodeReader { - static ProbabilityInfo readProbabilityInfo(final DictBuffer dictBuffer) { - // Ver2 dicts don't contain historical information. - return new ProbabilityInfo(dictBuffer.readUnsignedByte()); - } - - static int readPtNodeOptionFlags(final DictBuffer dictBuffer) { - return dictBuffer.readUnsignedByte(); - } - - static int readChildrenAddress(final DictBuffer dictBuffer, - final int ptNodeFlags) { - switch (ptNodeFlags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) { - case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE: - return dictBuffer.readUnsignedByte(); - case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES: - return dictBuffer.readUnsignedShort(); - case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES: - return dictBuffer.readUnsignedInt24(); - case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS: - default: - return FormatSpec.NO_CHILDREN_ADDRESS; - } - } - - // Reads shortcuts and returns the read length. - static int readShortcut(final DictBuffer dictBuffer, - final ArrayList<WeightedString> shortcutTargets) { - final int pointerBefore = dictBuffer.position(); - dictBuffer.readUnsignedShort(); // skip the size - while (true) { - final int targetFlags = dictBuffer.readUnsignedByte(); - final String word = CharEncoding.readString(dictBuffer); - shortcutTargets.add(new WeightedString(word, - targetFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY)); - if (0 == (targetFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT)) break; - } - return dictBuffer.position() - pointerBefore; - } - - static int readBigramAddresses(final DictBuffer dictBuffer, - final ArrayList<PendingAttribute> bigrams, final int baseAddress) { - int readLength = 0; - int bigramCount = 0; - while (bigramCount++ < FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) { - final int bigramFlags = dictBuffer.readUnsignedByte(); - ++readLength; - final int sign = 0 == (bigramFlags & FormatSpec.FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE) - ? 1 : -1; - int bigramAddress = baseAddress + readLength; - switch (bigramFlags & FormatSpec.MASK_BIGRAM_ATTR_ADDRESS_TYPE) { - case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE: - bigramAddress += sign * dictBuffer.readUnsignedByte(); - readLength += 1; - break; - case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_TWOBYTES: - bigramAddress += sign * dictBuffer.readUnsignedShort(); - readLength += 2; - break; - case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_THREEBYTES: - bigramAddress += sign * dictBuffer.readUnsignedInt24(); - readLength += 3; - break; - default: - throw new RuntimeException("Has bigrams with no address"); - } - bigrams.add(new PendingAttribute( - bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY, - bigramAddress)); - if (0 == (bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT)) break; - } - return readLength; - } - } - - protected final File mDictionaryBinaryFile; - protected final long mOffset; - protected final long mLength; - // TODO: Remove mBufferFactory and mDictBuffer from this class members because they are now - // used only for testing. - private final DictionaryBufferFactory mBufferFactory; - protected DictBuffer mDictBuffer; - - @UsedForTesting - /* package */ Ver2DictDecoder(final File file, final long offset, final long length, - final int factoryFlag) { - mDictionaryBinaryFile = file; - mOffset = offset; - mLength = length; - mDictBuffer = null; - if ((factoryFlag & MASK_DICTBUFFER) == USE_READONLY_BYTEBUFFER) { - mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory(); - } else if ((factoryFlag & MASK_DICTBUFFER) == USE_BYTEARRAY) { - mBufferFactory = new DictionaryBufferFromByteArrayFactory(); - } else if ((factoryFlag & MASK_DICTBUFFER) == USE_WRITABLE_BYTEBUFFER) { - mBufferFactory = new DictionaryBufferFromWritableByteBufferFactory(); - } else { - mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory(); - } - } - - /* package */ Ver2DictDecoder(final File file, final long offset, final long length, - final DictionaryBufferFactory factory) { - mDictionaryBinaryFile = file; - mOffset = offset; - mLength = length; - mBufferFactory = factory; - } - - @Override - public void openDictBuffer() throws FileNotFoundException, IOException { - mDictBuffer = mBufferFactory.getDictionaryBuffer(mDictionaryBinaryFile); - } - - @Override - public boolean isDictBufferOpen() { - return mDictBuffer != null; - } - - /* package */ DictBuffer getDictBuffer() { - return mDictBuffer; - } - - @UsedForTesting - /* package */ DictBuffer openAndGetDictBuffer() throws FileNotFoundException, IOException { - openDictBuffer(); - return getDictBuffer(); - } - - @Override - public DictionaryHeader readHeader() throws IOException, UnsupportedFormatException { - // dictType is not being used in dicttool. Passing an empty string. - final BinaryDictionary binaryDictionary = new BinaryDictionary( - mDictionaryBinaryFile.getAbsolutePath(), mOffset, mLength, - true /* useFullEditDistance */, null /* locale */, "" /* dictType */, - false /* isUpdatable */); - final DictionaryHeader header = binaryDictionary.getHeader(); - binaryDictionary.close(); - if (header == null) { - throw new IOException("Cannot read the dictionary header."); - } - if (header.mFormatOptions.mVersion != FormatSpec.VERSION2 && - header.mFormatOptions.mVersion != FormatSpec.VERSION201 && - header.mFormatOptions.mVersion != FormatSpec.VERSION202) { - throw new UnsupportedFormatException("File header has a wrong version : " - + header.mFormatOptions.mVersion); - } - if (!isDictBufferOpen()) { - openDictBuffer(); - } - // Advance buffer reading position to the head of dictionary body. - setPosition(header.mBodyOffset); - return header; - } - - // TODO: Make this buffer multi thread safe. - private final int[] mCharacterBuffer = new int[FormatSpec.MAX_WORD_LENGTH]; - @Override - public PtNodeInfo readPtNode(final int ptNodePos) { - int addressPointer = ptNodePos; - final int flags = PtNodeReader.readPtNodeOptionFlags(mDictBuffer); - addressPointer += FormatSpec.PTNODE_FLAGS_SIZE; - final int characters[]; - if (0 != (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS)) { - int index = 0; - int character = CharEncoding.readChar(mDictBuffer); - addressPointer += CharEncoding.getCharSize(character, null); - while (FormatSpec.INVALID_CHARACTER != character) { - // FusionDictionary is making sure that the length of the word is smaller than - // MAX_WORD_LENGTH. - // So we'll never write past the end of mCharacterBuffer. - mCharacterBuffer[index++] = character; - character = CharEncoding.readChar(mDictBuffer); - addressPointer += CharEncoding.getCharSize(character, null); - } - characters = Arrays.copyOfRange(mCharacterBuffer, 0, index); - } else { - final int character = CharEncoding.readChar(mDictBuffer); - addressPointer += CharEncoding.getCharSize(character, null); - characters = new int[] { character }; - } - final ProbabilityInfo probabilityInfo; - if (0 != (FormatSpec.FLAG_IS_TERMINAL & flags)) { - probabilityInfo = PtNodeReader.readProbabilityInfo(mDictBuffer); - addressPointer += FormatSpec.PTNODE_FREQUENCY_SIZE; - } else { - probabilityInfo = null; - } - int childrenAddress = PtNodeReader.readChildrenAddress(mDictBuffer, flags); - if (childrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) { - childrenAddress += addressPointer; - } - addressPointer += BinaryDictIOUtils.getChildrenAddressSize(flags); - final ArrayList<WeightedString> shortcutTargets; - if (0 != (flags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS)) { - // readShortcut will add shortcuts to shortcutTargets. - shortcutTargets = new ArrayList<>(); - addressPointer += PtNodeReader.readShortcut(mDictBuffer, shortcutTargets); - } else { - shortcutTargets = null; - } - - final ArrayList<PendingAttribute> bigrams; - if (0 != (flags & FormatSpec.FLAG_HAS_BIGRAMS)) { - bigrams = new ArrayList<>(); - addressPointer += PtNodeReader.readBigramAddresses(mDictBuffer, bigrams, - addressPointer); - if (bigrams.size() >= FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) { - throw new RuntimeException("Too many bigrams in a PtNode (" + bigrams.size() - + " but max is " + FormatSpec.MAX_BIGRAMS_IN_A_PTNODE + ")"); - } - } else { - bigrams = null; - } - return new PtNodeInfo(ptNodePos, addressPointer, flags, characters, probabilityInfo, - childrenAddress, shortcutTargets, bigrams); - } - - @Override - public FusionDictionary readDictionaryBinary(final boolean deleteDictIfBroken) - throws FileNotFoundException, IOException, UnsupportedFormatException { - // dictType is not being used in dicttool. Passing an empty string. - final BinaryDictionary binaryDictionary = new BinaryDictionary( - mDictionaryBinaryFile.getAbsolutePath(), 0 /* offset */, - mDictionaryBinaryFile.length() /* length */, true /* useFullEditDistance */, - null /* locale */, "" /* dictType */, false /* isUpdatable */); - final DictionaryHeader header = readHeader(); - final FusionDictionary fusionDict = - new FusionDictionary(new FusionDictionary.PtNodeArray(), header.mDictionaryOptions); - int token = 0; - final ArrayList<WordProperty> wordProperties = new ArrayList<>(); - do { - final BinaryDictionary.GetNextWordPropertyResult result = - binaryDictionary.getNextWordProperty(token); - final WordProperty wordProperty = result.mWordProperty; - if (wordProperty == null) { - binaryDictionary.close(); - if (deleteDictIfBroken) { - mDictionaryBinaryFile.delete(); - } - return null; - } - wordProperties.add(wordProperty); - token = result.mNextToken; - } while (token != 0); - - // Insert unigrams into the fusion dictionary. - for (final WordProperty wordProperty : wordProperties) { - fusionDict.add(wordProperty.mWord, wordProperty.mProbabilityInfo, - wordProperty.mIsNotAWord, - wordProperty.mIsPossiblyOffensive); - } - // Insert bigrams into the fusion dictionary. - for (final WordProperty wordProperty : wordProperties) { - if (!wordProperty.mHasNgrams) { - continue; - } - final String word0 = wordProperty.mWord; - for (final WeightedString bigram : wordProperty.getBigrams()) { - fusionDict.setBigram(word0, bigram.mWord, bigram.mProbabilityInfo); - } - } - binaryDictionary.close(); - return fusionDict; - } - - @Override - public void setPosition(int newPos) { - mDictBuffer.position(newPos); - } - - @Override - public int getPosition() { - return mDictBuffer.position(); - } - - @Override - public int readPtNodeCount() { - return BinaryDictDecoderUtils.readPtNodeCount(mDictBuffer); - } -} diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java deleted file mode 100644 index 3882c2c55..000000000 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java +++ /dev/null @@ -1,150 +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.latin.makedict; - -import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; -import com.android.inputmethod.latin.makedict.DictDecoder.DictionaryBufferFactory; -import com.android.inputmethod.latin.makedict.DictDecoder.DictionaryBufferFromByteArrayFactory; -import com.android.inputmethod.latin.makedict.DictDecoder. - DictionaryBufferFromReadOnlyByteBufferFactory; -import com.android.inputmethod.latin.makedict.DictDecoder. - DictionaryBufferFromWritableByteBufferFactory; - -import android.test.AndroidTestCase; -import android.util.Log; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * Unit tests for Ver2DictDecoder - */ -public class Ver2DictDecoderTests extends AndroidTestCase { - private static final String TAG = Ver2DictDecoderTests.class.getSimpleName(); - - private final byte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; - - // Utilities for testing - public void writeDataToFile(final File file) { - FileOutputStream outStream = null; - try { - outStream = new FileOutputStream(file); - outStream.write(data); - } catch (IOException e) { - fail ("Can't write data to the test file"); - } finally { - if (outStream != null) { - try { - outStream.close(); - } catch (IOException e) { - Log.e(TAG, "Failed to close the output stream", e); - } - } - } - } - - public void runTestOpenBuffer(final String testName, final DictionaryBufferFactory factory) { - File testFile = null; - try { - testFile = File.createTempFile(testName, ".tmp", getContext().getCacheDir()); - } catch (IOException e) { - Log.e(TAG, "IOException while the creating temporary file", e); - } - - assertNotNull(testFile); - final Ver2DictDecoder dictDecoder = new Ver2DictDecoder(testFile, 0, testFile.length(), - factory); - try { - dictDecoder.openDictBuffer(); - } catch (Exception e) { - Log.e(TAG, "Failed to open the buffer", e); - } - - writeDataToFile(testFile); - - try { - dictDecoder.openDictBuffer(); - } catch (Exception e) { - Log.e(TAG, "Raised the exception while opening buffer", e); - } - - assertEquals(testFile.length(), dictDecoder.getDictBuffer().capacity()); - } - - public void testOpenBufferWithByteBuffer() { - runTestOpenBuffer("testOpenBufferWithByteBuffer", - new DictionaryBufferFromReadOnlyByteBufferFactory()); - } - - public void testOpenBufferWithByteArray() { - runTestOpenBuffer("testOpenBufferWithByteArray", - new DictionaryBufferFromByteArrayFactory()); - } - - public void testOpenBufferWithWritableByteBuffer() { - runTestOpenBuffer("testOpenBufferWithWritableByteBuffer", - new DictionaryBufferFromWritableByteBufferFactory()); - } - - public void runTestGetBuffer(final String testName, final DictionaryBufferFactory factory) { - File testFile = null; - try { - testFile = File.createTempFile(testName, ".tmp", getContext().getCacheDir()); - } catch (IOException e) { - Log.e(TAG, "IOException while the creating temporary file", e); - } - - final Ver2DictDecoder dictDecoder = new Ver2DictDecoder(testFile, 0, testFile.length(), - factory); - - // the default return value of getBuffer() must be null. - assertNull("the default return value of getBuffer() is not null", - dictDecoder.getDictBuffer()); - - writeDataToFile(testFile); - assertTrue(testFile.exists()); - Log.d(TAG, "file length = " + testFile.length()); - - DictBuffer dictBuffer = null; - try { - dictBuffer = dictDecoder.openAndGetDictBuffer(); - } catch (IOException e) { - Log.e(TAG, "Failed to open and get the buffer", e); - } - assertNotNull("the buffer must not be null", dictBuffer); - - for (int i = 0; i < data.length; ++i) { - assertEquals(data[i], dictBuffer.readUnsignedByte()); - } - } - - public void testGetBufferWithByteBuffer() { - runTestGetBuffer("testGetBufferWithByteBuffer", - new DictionaryBufferFromReadOnlyByteBufferFactory()); - } - - public void testGetBufferWithByteArray() { - runTestGetBuffer("testGetBufferWithByteArray", - new DictionaryBufferFromByteArrayFactory()); - } - - public void testGetBufferWithWritableByteBuffer() { - runTestGetBuffer("testGetBufferWithWritableByteBuffer", - new DictionaryBufferFromWritableByteBufferFactory()); - } -} diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java deleted file mode 100644 index c63b972eb..000000000 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java +++ /dev/null @@ -1,279 +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.latin.makedict; - -import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding; -import com.android.inputmethod.latin.makedict.BinaryDictEncoderUtils.CodePointTable; -import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; -import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode; -import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map.Entry; - -/** - * An implementation of DictEncoder for version 2 binary dictionary. - */ -@UsedForTesting -public class Ver2DictEncoder implements DictEncoder { - - private final File mDictFile; - private OutputStream mOutStream; - private byte[] mBuffer; - private int mPosition; - private final int mCodePointTableMode; - public static final int CODE_POINT_TABLE_OFF = 0; - public static final int CODE_POINT_TABLE_ON = 1; - - @UsedForTesting - public Ver2DictEncoder(final File dictFile, final int codePointTableMode) { - mDictFile = dictFile; - mOutStream = null; - mBuffer = null; - mCodePointTableMode = codePointTableMode; - } - - // This constructor is used only by BinaryDictOffdeviceUtilsTests. - // If you want to use this in the production code, you should consider keeping consistency of - // the interface of Ver3DictDecoder by using factory. - @UsedForTesting - public Ver2DictEncoder(final OutputStream outStream) { - mDictFile = null; - mOutStream = outStream; - mCodePointTableMode = CODE_POINT_TABLE_OFF; - } - - private void openStream() throws FileNotFoundException { - mOutStream = new FileOutputStream(mDictFile); - } - - private void close() throws IOException { - if (mOutStream != null) { - mOutStream.close(); - mOutStream = null; - } - } - - // Package for testing - static CodePointTable makeCodePointTable(final FusionDictionary dict) { - final HashMap<Integer, Integer> codePointOccurrenceCounts = new HashMap<>(); - for (final WordProperty word : dict) { - // Store per code point occurrence - final String wordString = word.mWord; - for (int i = 0; i < wordString.length(); ++i) { - final int codePoint = Character.codePointAt(wordString, i); - if (codePointOccurrenceCounts.containsKey(codePoint)) { - codePointOccurrenceCounts.put(codePoint, - codePointOccurrenceCounts.get(codePoint) + 1); - } else { - codePointOccurrenceCounts.put(codePoint, 1); - } - } - } - final ArrayList<Entry<Integer, Integer>> codePointOccurrenceArray = - new ArrayList<>(codePointOccurrenceCounts.entrySet()); - // Descending order sort by occurrence (value side) - Collections.sort(codePointOccurrenceArray, new Comparator<Entry<Integer, Integer>>() { - @Override - public int compare(final Entry<Integer, Integer> a, final Entry<Integer, Integer> b) { - if (a.getValue() != b.getValue()) { - return b.getValue().compareTo(a.getValue()); - } - return b.getKey().compareTo(a.getKey()); - } - }); - int currentCodePointTableIndex = FormatSpec.MINIMAL_ONE_BYTE_CHARACTER_VALUE; - // Temporary map for writing of nodes - final HashMap<Integer, Integer> codePointToOneByteCodeMap = new HashMap<>(); - for (final Entry<Integer, Integer> entry : codePointOccurrenceArray) { - // Put a relation from the original code point to the one byte code. - codePointToOneByteCodeMap.put(entry.getKey(), currentCodePointTableIndex); - if (FormatSpec.MAXIMAL_ONE_BYTE_CHARACTER_VALUE < ++currentCodePointTableIndex) { - break; - } - } - // codePointToOneByteCodeMap for writing the trie - // codePointOccurrenceArray for writing the header - return new CodePointTable(codePointToOneByteCodeMap, codePointOccurrenceArray); - } - - @Override - public void writeDictionary(final FusionDictionary dict, final FormatOptions formatOptions) - throws IOException, UnsupportedFormatException { - // We no longer support anything but the latest version of v2. - if (formatOptions.mVersion != FormatSpec.VERSION202) { - throw new UnsupportedFormatException( - "The given format options has wrong version number : " - + formatOptions.mVersion); - } - - if (mOutStream == null) { - openStream(); - } - - // Make code point conversion table ordered by occurrence of code points - // Version 201 or later have codePointTable - final CodePointTable codePointTable; - if (mCodePointTableMode == CODE_POINT_TABLE_OFF || formatOptions.mVersion - < FormatSpec.MINIMUM_SUPPORTED_VERSION_OF_CODE_POINT_TABLE) { - codePointTable = new CodePointTable(); - } else { - codePointTable = makeCodePointTable(dict); - } - - BinaryDictEncoderUtils.writeDictionaryHeader(mOutStream, dict, formatOptions, - codePointTable.mCodePointOccurrenceArray); - - // Addresses are limited to 3 bytes, but since addresses can be relative to each node - // array, the structure itself is not limited to 16MB. However, if it is over 16MB deciding - // the order of the PtNode arrays becomes a quite complicated problem, because though the - // dictionary itself does not have a size limit, each node array must still be within 16MB - // of all its children and parents. As long as this is ensured, the dictionary file may - // grow to any size. - - // Leave the choice of the optimal node order to the flattenTree function. - MakedictLog.i("Flattening the tree..."); - ArrayList<PtNodeArray> flatNodes = BinaryDictEncoderUtils.flattenTree(dict.mRootNodeArray); - - MakedictLog.i("Computing addresses..."); - BinaryDictEncoderUtils.computeAddresses(dict, flatNodes, - codePointTable.mCodePointToOneByteCodeMap); - MakedictLog.i("Checking PtNode array..."); - if (MakedictLog.DBG) BinaryDictEncoderUtils.checkFlatPtNodeArrayList(flatNodes); - - // Create a buffer that matches the final dictionary size. - final PtNodeArray lastNodeArray = flatNodes.get(flatNodes.size() - 1); - final int bufferSize = lastNodeArray.mCachedAddressAfterUpdate + lastNodeArray.mCachedSize; - mBuffer = new byte[bufferSize]; - - MakedictLog.i("Writing file..."); - - for (PtNodeArray nodeArray : flatNodes) { - BinaryDictEncoderUtils.writePlacedPtNodeArray(dict, this, nodeArray, - codePointTable.mCodePointToOneByteCodeMap); - } - if (MakedictLog.DBG) BinaryDictEncoderUtils.showStatistics(flatNodes); - mOutStream.write(mBuffer, 0, mPosition); - - MakedictLog.i("Done"); - close(); - } - - @Override - public void setPosition(final int position) { - if (mBuffer == null || position < 0 || position >= mBuffer.length) return; - mPosition = position; - } - - @Override - public int getPosition() { - return mPosition; - } - - @Override - public void writePtNodeCount(final int ptNodeCount) { - final int countSize = BinaryDictIOUtils.getPtNodeCountSize(ptNodeCount); - if (countSize != 1 && countSize != 2) { - throw new RuntimeException("Strange size from getGroupCountSize : " + countSize); - } - final int encodedPtNodeCount = (countSize == 2) ? - (ptNodeCount | FormatSpec.LARGE_PTNODE_ARRAY_SIZE_FIELD_SIZE_FLAG) : ptNodeCount; - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, encodedPtNodeCount, - countSize); - } - - private void writePtNodeFlags(final PtNode ptNode, - final HashMap<Integer, Integer> codePointToOneByteCodeMap) { - final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode, - codePointToOneByteCodeMap); - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, - BinaryDictEncoderUtils.makePtNodeFlags(ptNode, childrenPos), - FormatSpec.PTNODE_FLAGS_SIZE); - } - - private void writeCharacters(final int[] codePoints, final boolean hasSeveralChars, - final HashMap<Integer, Integer> codePointToOneByteCodeMap) { - mPosition = CharEncoding.writeCharArray(codePoints, mBuffer, mPosition, - codePointToOneByteCodeMap); - if (hasSeveralChars) { - mBuffer[mPosition++] = FormatSpec.PTNODE_CHARACTERS_TERMINATOR; - } - } - - private void writeFrequency(final int frequency) { - if (frequency >= 0) { - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, frequency, - FormatSpec.PTNODE_FREQUENCY_SIZE); - } - } - - private void writeChildrenPosition(final PtNode ptNode, - final HashMap<Integer, Integer> codePointToOneByteCodeMap) { - final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode, - codePointToOneByteCodeMap); - mPosition += BinaryDictEncoderUtils.writeChildrenPosition(mBuffer, mPosition, - childrenPos); - } - - /** - * Write a bigram attributes list to mBuffer. - * - * @param bigrams the bigram attributes list. - * @param dict the dictionary the node array is a part of (for relative offsets). - */ - private void writeBigrams(final ArrayList<WeightedString> bigrams, - final FusionDictionary dict) { - if (bigrams == null) return; - - final Iterator<WeightedString> bigramIterator = bigrams.iterator(); - while (bigramIterator.hasNext()) { - final WeightedString bigram = bigramIterator.next(); - final PtNode target = - FusionDictionary.findWordInTree(dict.mRootNodeArray, bigram.mWord); - final int addressOfBigram = target.mCachedAddressAfterUpdate; - final int unigramFrequencyForThisWord = target.getProbability(); - final int offset = addressOfBigram - - (mPosition + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE); - final int bigramFlags = BinaryDictEncoderUtils.makeBigramFlags(bigramIterator.hasNext(), - offset, bigram.getProbability(), unigramFrequencyForThisWord, bigram.mWord); - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, bigramFlags, - FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE); - mPosition += BinaryDictEncoderUtils.writeChildrenPosition(mBuffer, mPosition, - Math.abs(offset)); - } - } - - @Override - public void writePtNode(final PtNode ptNode, final FusionDictionary dict, - final HashMap<Integer, Integer> codePointToOneByteCodeMap) { - writePtNodeFlags(ptNode, codePointToOneByteCodeMap); - writeCharacters(ptNode.mChars, ptNode.hasSeveralChars(), codePointToOneByteCodeMap); - writeFrequency(ptNode.getProbability()); - writeChildrenPosition(ptNode, codePointToOneByteCodeMap); - writeBigrams(ptNode.mBigrams, dict); - } -} diff --git a/tests/src/com/android/inputmethod/latin/touchinputconsumer/NullGestureConsumerTests.java b/tests/src/com/android/inputmethod/latin/touchinputconsumer/NullGestureConsumerTests.java index ca1039bd9..ad6bcc3c4 100644 --- a/tests/src/com/android/inputmethod/latin/touchinputconsumer/NullGestureConsumerTests.java +++ b/tests/src/com/android/inputmethod/latin/touchinputconsumer/NullGestureConsumerTests.java @@ -34,7 +34,7 @@ public class NullGestureConsumerTests extends AndroidTestCase { GestureConsumer.NULL_GESTURE_CONSUMER.onGestureStarted(null, null); GestureConsumer.NULL_GESTURE_CONSUMER.onGestureCanceled(); GestureConsumer.NULL_GESTURE_CONSUMER.onGestureCompleted(null); - GestureConsumer.NULL_GESTURE_CONSUMER.onImeSuggestionsProcessed(null, -1, -1); + GestureConsumer.NULL_GESTURE_CONSUMER.onImeSuggestionsProcessed(null, -1, -1, null); } /** |