diff options
27 files changed, 351 insertions, 104 deletions
diff --git a/dictionaries/en_GB_wordlist.combined.gz b/dictionaries/en_GB_wordlist.combined.gz Binary files differindex 4f008ed8f..50647b847 100644 --- a/dictionaries/en_GB_wordlist.combined.gz +++ b/dictionaries/en_GB_wordlist.combined.gz diff --git a/dictionaries/en_US_wordlist.combined.gz b/dictionaries/en_US_wordlist.combined.gz Binary files differindex 5595c75c0..19f9ab4ff 100644 --- a/dictionaries/en_US_wordlist.combined.gz +++ b/dictionaries/en_US_wordlist.combined.gz diff --git a/dictionaries/en_wordlist.combined.gz b/dictionaries/en_wordlist.combined.gz Binary files differindex 69c39d5d9..874a5de20 100644 --- a/dictionaries/en_wordlist.combined.gz +++ b/dictionaries/en_wordlist.combined.gz diff --git a/dictionaries/fr_wordlist.combined.gz b/dictionaries/fr_wordlist.combined.gz Binary files differindex 1a1832079..49dfd7988 100644 --- a/dictionaries/fr_wordlist.combined.gz +++ b/dictionaries/fr_wordlist.combined.gz diff --git a/java/res/raw/main_en.dict b/java/res/raw/main_en.dict Binary files differindex bef6b1005..09b69927f 100644 --- a/java/res/raw/main_en.dict +++ b/java/res/raw/main_en.dict diff --git a/java/res/raw/main_fr.dict b/java/res/raw/main_fr.dict Binary files differindex 18f529887..0e5a71360 100644 --- a/java/res/raw/main_fr.dict +++ b/java/res/raw/main_fr.dict diff --git a/java/res/values-hy/donottranslate.xml b/java/res/values-hy/donottranslate.xml index 4a6d188fb..7b0c56655 100644 --- a/java/res/values-hy/donottranslate.xml +++ b/java/res/values-hy/donottranslate.xml @@ -26,4 +26,7 @@ <!-- Symbols that separate words. Adding armenian period and comma. --> <!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) --> <string name="symbols_word_separators">"	 \n"()[]{}*&<>+=|.,;:!?/_\"։՝</string> + <!-- The sentence separator code point, for capitalization --> + <!-- U+0589: "։" ARMENIAN FULL STOP ; 589h = 1417d --> + <integer name="sentence_separator">1417</integer> </resources> diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml index 42e692d2f..4733aa257 100644 --- a/java/res/values/donottranslate.xml +++ b/java/res/values/donottranslate.xml @@ -31,6 +31,9 @@ <string name="symbols_word_separators">"	 \n"()[]{}*&<>+=|.,;:!?/_\"</string> <!-- Word connectors --> <string name="symbols_word_connectors">\'-</string> + <!-- The sentence separator code point, for capitalization --> + <!-- U+002E: "." FULL STOP ; 2Eh = 46d --> + <integer name="sentence_separator">46</integer> <!-- Whether this language uses spaces between words --> <bool name="current_language_has_spaces">true</bool> diff --git a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java index 85ae50092..4f5961175 100644 --- a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java +++ b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java @@ -74,6 +74,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange ViewPager.OnPageChangeListener, View.OnClickListener, ScrollKeyboardView.OnKeyClickListener { private static final String TAG = EmojiPalettesView.class.getSimpleName(); + private static final boolean DEBUG_PAGER = false; private final int mKeyBackgroundId; private final int mEmojiFunctionalKeyBackgroundId; private final KeyboardLayoutSet mLayoutSet; @@ -459,6 +460,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange mEmojiPager.setAdapter(mEmojiPalettesAdapter); mEmojiPager.setOnPageChangeListener(this); mEmojiPager.setOffscreenPageLimit(0); + mEmojiPager.setPersistentDrawingCache(ViewPager.PERSISTENT_NO_CACHE); final Resources res = getResources(); final EmojiLayoutParams emojiLp = new EmojiLayoutParams(res); emojiLp.setPagerProperties(mEmojiPager); @@ -565,6 +567,20 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange // TODO: } + public void startEmojiPalettes() { + if (DEBUG_PAGER) { + Log.d(TAG, "allocate emoji palettes memory"); + } + mEmojiPager.setAdapter(mEmojiPalettesAdapter); + } + + public void stopEmojiPalettes() { + if (DEBUG_PAGER) { + Log.d(TAG, "deallocate emoji palettes memory"); + } + mEmojiPager.setAdapter(null); + } + public void setKeyboardActionListener(final KeyboardActionListener listener) { mKeyboardActionListener = listener; mDeleteKeyOnTouchListener.setKeyboardActionListener(mKeyboardActionListener); @@ -607,7 +623,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange private static class EmojiPalettesAdapter extends PagerAdapter { private final ScrollKeyboardView.OnKeyClickListener mListener; private final DynamicGridKeyboard mRecentsKeyboard; - private final SparseArray<ScrollKeyboardView> mActiveKeyboardView = + private final SparseArray<ScrollKeyboardView> mActiveKeyboardViews = CollectionUtils.newSparseArray(); private final EmojiCategory mEmojiCategory; private int mActivePosition = 0; @@ -623,7 +639,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange public void flushPendingRecentKeys() { mRecentsKeyboard.flushPendingRecentKeys(); final KeyboardView recentKeyboardView = - mActiveKeyboardView.get(mEmojiCategory.getRecentTabId()); + mActiveKeyboardViews.get(mEmojiCategory.getRecentTabId()); if (recentKeyboardView != null) { recentKeyboardView.invalidateAllKeys(); } @@ -636,7 +652,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange } mRecentsKeyboard.addKeyFirst(key); final KeyboardView recentKeyboardView = - mActiveKeyboardView.get(mEmojiCategory.getRecentTabId()); + mActiveKeyboardViews.get(mEmojiCategory.getRecentTabId()); if (recentKeyboardView != null) { recentKeyboardView.invalidateAllKeys(); } @@ -652,7 +668,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange if (mActivePosition == position) { return; } - final ScrollKeyboardView oldKeyboardView = mActiveKeyboardView.get(mActivePosition); + final ScrollKeyboardView oldKeyboardView = mActiveKeyboardViews.get(mActivePosition); if (oldKeyboardView != null) { oldKeyboardView.releaseCurrentKey(); oldKeyboardView.deallocateMemory(); @@ -662,11 +678,14 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange @Override public Object instantiateItem(final ViewGroup container, final int position) { - final ScrollKeyboardView oldKeyboardView = mActiveKeyboardView.get(position); + if (DEBUG_PAGER) { + Log.d(TAG, "instantiate item: " + position); + } + final ScrollKeyboardView oldKeyboardView = mActiveKeyboardViews.get(position); if (oldKeyboardView != null) { oldKeyboardView.deallocateMemory(); // This may be redundant but wanted to be safer.. - mActiveKeyboardView.remove(position); + mActiveKeyboardViews.remove(position); } final Keyboard keyboard = mEmojiCategory.getKeyboardFromPagePosition(position); @@ -681,7 +700,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange R.id.emoji_keyboard_scroller); keyboardView.setScrollView(scrollView); container.addView(view); - mActiveKeyboardView.put(position, keyboardView); + mActiveKeyboardViews.put(position, keyboardView); return view; } @@ -693,12 +712,19 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange @Override public void destroyItem(final ViewGroup container, final int position, final Object object) { - final ScrollKeyboardView keyboardView = mActiveKeyboardView.get(position); + if (DEBUG_PAGER) { + Log.d(TAG, "destroy item: " + position + ", " + object.getClass().getSimpleName()); + } + final ScrollKeyboardView keyboardView = mActiveKeyboardViews.get(position); if (keyboardView != null) { keyboardView.deallocateMemory(); - mActiveKeyboardView.remove(position); + mActiveKeyboardViews.remove(position); + } + if (object instanceof View) { + container.removeView((View)object); + } else { + Log.w(TAG, "Warning!!! Emoji palette may be leaking. " + object); } - container.removeView(keyboardView); } } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 4fc1082f1..97609837e 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -260,12 +260,14 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { private void setMainKeyboardFrame() { mMainKeyboardFrame.setVisibility(View.VISIBLE); mEmojiPalettesView.setVisibility(View.GONE); + mEmojiPalettesView.stopEmojiPalettes(); } // Implements {@link KeyboardState.SwitchActions}. @Override public void setEmojiKeyboard() { mMainKeyboardFrame.setVisibility(View.GONE); + mEmojiPalettesView.startEmojiPalettes(); mEmojiPalettesView.setVisibility(View.VISIBLE); } @@ -336,6 +338,16 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { return mKeyboardView; } + public void deallocateMemory() { + if (mKeyboardView != null) { + mKeyboardView.cancelAllOngoingEvents(); + mKeyboardView.deallocateMemory(); + } + if (mEmojiPalettesView != null) { + mEmojiPalettesView.stopEmojiPalettes(); + } + } + public View onCreateInputView(final boolean isHardwareAcceleratedDrawingEnabled) { if (mKeyboardView != null) { mKeyboardView.closing(); diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index aeb9e67b2..5578713a0 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -243,6 +243,8 @@ public class KeyboardView extends View { } private void freeOffscreenBuffer() { + mOffscreenCanvas.setBitmap(null); + mOffscreenCanvas.setMatrix(null); if (mOffscreenBuffer != null) { mOffscreenBuffer.recycle(); mOffscreenBuffer = null; diff --git a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java index 08302a771..09766ac6c 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java @@ -42,7 +42,6 @@ public class DynamicGridKeyboard extends Keyboard { private final Object mLock = new Object(); private final SharedPreferences mPrefs; - private final int mLeftPadding; private final int mHorizontalStep; private final int mVerticalStep; private final int mColumnsNum; @@ -58,7 +57,6 @@ public class DynamicGridKeyboard extends Keyboard { super(templateKeyboard); final Key key0 = getTemplateKey(TEMPLATE_KEY_CODE_0); final Key key1 = getTemplateKey(TEMPLATE_KEY_CODE_1); - mLeftPadding = key0.getX(); mHorizontalStep = Math.abs(key1.getX() - key0.getX()); mVerticalStep = key0.getHeight() + mVerticalGap; mColumnsNum = mBaseWidth / mHorizontalStep; @@ -122,9 +120,11 @@ public class DynamicGridKeyboard extends Keyboard { } int index = 0; for (final GridKey gridKey : mGridKeys) { - final int keyX = getKeyX(index); - final int keyY = getKeyY(index); - gridKey.updateCorrdinates(keyX, keyY); + final int keyX0 = getKeyX0(index); + final int keyY0 = getKeyY0(index); + final int keyX1 = getKeyX1(index); + final int keyY1 = getKeyY1(index); + gridKey.updateCorrdinates(keyX0, keyY0, keyX1, keyY1); index++; } } @@ -172,14 +172,24 @@ public class DynamicGridKeyboard extends Keyboard { } } - private int getKeyX(final int index) { + private int getKeyX0(final int index) { final int column = index % mColumnsNum; - return column * mHorizontalStep + mLeftPadding; + return column * mHorizontalStep; } - private int getKeyY(final int index) { + private int getKeyX1(final int index) { + final int column = index % mColumnsNum + 1; + return column * mHorizontalStep; + } + + private int getKeyY0(final int index) { final int row = index / mColumnsNum; - return row * mVerticalStep + mTopPadding; + return row * mVerticalStep; + } + + private int getKeyY1(final int index) { + final int row = index / mColumnsNum + 1; + return row * mVerticalStep; } @Override @@ -207,10 +217,10 @@ public class DynamicGridKeyboard extends Keyboard { super(originalKey); } - public void updateCorrdinates(final int x, final int y) { - mCurrentX = x; - mCurrentY = y; - getHitBox().set(x, y, x + getWidth(), y + getHeight()); + public void updateCorrdinates(final int x0, final int y0, final int x1, final int y1) { + mCurrentX = x0; + mCurrentY = y0; + getHitBox().set(x0, y0, x1, y1); } @Override diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java index 506dfa751..9f9fdaa6f 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java @@ -178,8 +178,6 @@ public final class KeyboardState { if (!state.mIsAlphabetShiftLocked) { setShifted(state.mShiftMode); } - // TODO: is this the right place to do this? Should we do this in setShift* instead? - mSwitchActions.requestUpdatingShiftState(); } else { mPrevMainKeyboardWasShiftLocked = state.mIsAlphabetShiftLocked; } diff --git a/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java b/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java index b8ee976e8..9cf68d43d 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java @@ -30,8 +30,9 @@ import com.android.inputmethod.keyboard.KeyboardView; import com.android.inputmethod.latin.R; /** - * This is an extended {@link KeyboardView} class that hosts a scroll keyboard. + * This is an extended {@link KeyboardView} class that hosts a vertical scroll keyboard. * Multi-touch unsupported. No {@link PointerTracker}s. No gesture support. + * TODO: Vertical scroll capability should be removed from this class because it's no longer used. */ // TODO: Implement key popup preview. public final class ScrollKeyboardView extends KeyboardView implements diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 851f9677f..ccdbd0d4d 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -904,12 +904,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Sometimes, while rotating, for some reason the framework tells the app we are not // connected to it and that means we can't refresh the cache. In this case, schedule a // refresh later. + final boolean canReachInputConnection; if (!mConnection.resetCachesUponCursorMoveAndReturnSuccess(editorInfo.initialSelStart, false /* shouldFinishComposition */)) { // We try resetting the caches up to 5 times before giving up. mHandler.postResetCaches(isDifferentTextField, 5 /* remainingTries */); + canReachInputConnection = false; } else { - if (isDifferentTextField) mHandler.postResumeSuggestions(); + if (isDifferentTextField) { + mHandler.postResumeSuggestions(); + } + canReachInputConnection = true; } if (isDifferentTextField) { @@ -922,6 +927,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } switcher.loadKeyboard(editorInfo, currentSettingsValues); + if (!canReachInputConnection) { + // If we can't reach the input connection, we will call loadKeyboard again later, + // so we need to save its state now. The call will be done in #retryResetCaches. + switcher.saveKeyboardState(); + } } else if (restarting) { // TODO: Come up with a more comprehensive way to reset the keyboard layout when // a keyboard layout set doesn't get reloaded in this method. @@ -1040,11 +1050,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private void onFinishInputViewInternal(final boolean finishingInput) { super.onFinishInputView(finishingInput); mKeyboardSwitcher.onFinishInputView(); - final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); - if (mainKeyboardView != null) { - mainKeyboardView.cancelAllOngoingEvents(); - mainKeyboardView.deallocateMemory(); - } + mKeyboardSwitcher.deallocateMemory(); // Remove pending messages related to update suggestions mHandler.cancelUpdateSuggestionStrip(); // Should do the following in onFinishInputInternal but until JB MR2 it's not called :( @@ -1402,14 +1408,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Called from the KeyboardSwitcher which needs to know auto caps state to display // the right layout. public int getCurrentAutoCapsState() { - if (!mSettings.getCurrent().mAutoCap) return Constants.TextUtils.CAP_MODE_OFF; + final SettingsValues currentSettingsValues = mSettings.getCurrent(); + if (!currentSettingsValues.mAutoCap) return Constants.TextUtils.CAP_MODE_OFF; final EditorInfo ei = getCurrentInputEditorInfo(); if (ei == null) return Constants.TextUtils.CAP_MODE_OFF; final int inputType = ei.inputType; // Warning: this depends on mSpaceState, which may not be the most current value. If // mSpaceState gets updated later, whoever called this may need to be told about it. - return mConnection.getCursorCapsMode(inputType, mSubtypeSwitcher.getCurrentSubtypeLocale(), + return mConnection.getCursorCapsMode(inputType, currentSettingsValues, SPACE_STATE_PHANTOM == mSpaceState); } @@ -1450,9 +1457,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } private boolean maybeDoubleSpacePeriod() { - final SettingsValues settingsValues = mSettings.getCurrent(); - if (!settingsValues.mCorrectionEnabled) return false; - if (!settingsValues.mUseDoubleSpacePeriod) return false; + final SettingsValues currentSettingsValues = mSettings.getCurrent(); + if (!currentSettingsValues.mCorrectionEnabled) return false; + if (!currentSettingsValues.mUseDoubleSpacePeriod) return false; if (!mHandler.isAcceptingDoubleSpacePeriod()) return false; // We only do this when we see two spaces and an accepted code point before the cursor. // The code point may be a surrogate pair but the two spaces may not, so we need 4 chars. @@ -1471,7 +1478,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (canBeFollowedByDoubleSpacePeriod(firstCodePoint)) { mHandler.cancelDoubleSpacePeriodTimer(); mConnection.deleteSurroundingText(2, 0); - final String textToInsert = ". "; + final String textToInsert = new String( + new int[] { currentSettingsValues.mSentenceSeparator, Constants.CODE_SPACE }, + 0, 2); mConnection.commitText(textToInsert, 1); if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { ResearchLogger.latinIME_maybeDoubleSpacePeriod(textToInsert, @@ -2955,11 +2964,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (!mConnection.resetCachesUponCursorMoveAndReturnSuccess(mLastSelectionStart, false)) { if (0 < remainingTries) { mHandler.postResetCaches(tryResumeSuggestions, remainingTries - 1); + return; } - return; + // If remainingTries is 0, we should stop waiting for new tries, but it's still + // better to load the keyboard (less things will be broken). } tryFixLyingCursorPosition(); - mKeyboardSwitcher.updateShiftState(); + mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), mSettings.getCurrent()); if (tryResumeSuggestions) mHandler.postResumeSuggestions(); } diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index 8580a6e54..e43cab5ca 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -245,11 +245,11 @@ public final class RichInputConnection { * American English, it's just the most common set of rules for English). * * @param inputType a mask of the caps modes to test for. - * @param locale what language should be considered. + * @param settingsValues the values of the settings to use for locale and separators. * @param hasSpaceBefore if we should consider there should be a space after the string. * @return the caps modes that should be on as a set of bits */ - public int getCursorCapsMode(final int inputType, final Locale locale, + public int getCursorCapsMode(final int inputType, final SettingsValues settingsValues, final boolean hasSpaceBefore) { mIC = mParent.getCurrentInputConnection(); if (null == mIC) return Constants.TextUtils.CAP_MODE_OFF; @@ -277,8 +277,8 @@ public final class RichInputConnection { } // This never calls InputConnection#getCapsMode - in fact, it's a static method that // never blocks or initiates IPC. - return CapsModeUtils.getCapsMode(mCommittedTextBeforeComposingText, inputType, locale, - hasSpaceBefore); + return CapsModeUtils.getCapsMode(mCommittedTextBeforeComposingText, inputType, + settingsValues, hasSpaceBefore); } public int getCodePointBeforeCursor() { diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java index be653feec..3bb218bea 100644 --- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java +++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java @@ -367,10 +367,11 @@ public final class FusionDictionary implements Iterable<Word> { * Helper method to convert a String to an int array. */ static int[] getCodePoints(final String word) { - // TODO: this is a copy-paste of the contents of StringUtils.toCodePointArray, + // TODO: this is a copy-paste of the old contents of StringUtils.toCodePointArray, // which is not visible from the makedict package. Factor this code. + final int length = word.length(); + if (length <= 0) return new int[] {}; final char[] characters = word.toCharArray(); - final int length = characters.length; final int[] codePoints = new int[Character.codePointCount(characters, 0, length)]; int codePoint = Character.codePointAt(characters, 0); int dsti = 0; diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java index 2abcdc7fa..f331c78e5 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java @@ -24,6 +24,7 @@ import android.view.inputmethod.EditorInfo; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.keyboard.internal.KeySpecParser; +import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.InputAttributes; import com.android.inputmethod.latin.R; @@ -57,6 +58,7 @@ public final class SettingsValues { public final int[] mWordConnectors; public final SuggestedWords mSuggestPuncList; public final String mWordSeparators; + public final int mSentenceSeparator; public final CharSequence mHintToSaveText; public final boolean mCurrentLanguageHasSpaces; @@ -120,6 +122,7 @@ public final class SettingsValues { R.string.suggested_punctuations)); mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec); mWordSeparators = res.getString(R.string.symbols_word_separators); + mSentenceSeparator = res.getInteger(R.integer.sentence_separator); mHintToSaveText = res.getText(R.string.hint_add_to_dictionary); mCurrentLanguageHasSpaces = res.getBoolean(R.bool.current_language_has_spaces); @@ -187,6 +190,7 @@ public final class SettingsValues { Arrays.sort(mSymbolsFollowedBySpace); mWordConnectors = new int[] { '\'', '-' }; Arrays.sort(mWordConnectors); + mSentenceSeparator = Constants.CODE_PERIOD; final String[] suggestPuncsSpec = new String[] { "!", "?", ",", ":", ";" }; mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec); mWordSeparators = "&\t \n()[]{}*&<>+=|.,;:!?/_\""; diff --git a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java index 60b24d5d5..3d4404a98 100644 --- a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java @@ -21,6 +21,7 @@ import android.text.TextUtils; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.WordComposer; +import com.android.inputmethod.latin.settings.SettingsValues; import java.util.Locale; @@ -60,11 +61,6 @@ public final class CapsModeUtils { || WordComposer.CAPS_MODE_AUTO_SHIFT_LOCKED == mode; } - private static boolean isPeriod(final int codePoint) { - // TODO: make this a resource. - return codePoint == Constants.CODE_PERIOD || codePoint == Constants.CODE_ARMENIAN_PERIOD; - } - /** * Determine what caps mode should be in effect at the current offset in * the text. Only the mode bits set in <var>reqModes</var> will be @@ -78,7 +74,7 @@ public final class CapsModeUtils { * @param reqModes The modes to be checked: may be any combination of * {@link TextUtils#CAP_MODE_CHARACTERS}, {@link TextUtils#CAP_MODE_WORDS}, and * {@link TextUtils#CAP_MODE_SENTENCES}. - * @param locale The locale to consider for capitalization rules + * @param settingsValues The current settings values. * @param hasSpaceBefore Whether we should consider there is a space inserted at the end of cs * * @return Returns the actual capitalization modes that can be in effect @@ -86,8 +82,8 @@ public final class CapsModeUtils { * {@link TextUtils#CAP_MODE_CHARACTERS}, {@link TextUtils#CAP_MODE_WORDS}, and * {@link TextUtils#CAP_MODE_SENTENCES}. */ - public static int getCapsMode(final CharSequence cs, final int reqModes, final Locale locale, - final boolean hasSpaceBefore) { + public static int getCapsMode(final CharSequence cs, final int reqModes, + final SettingsValues settingsValues, final boolean hasSpaceBefore) { // Quick description of what we want to do: // CAP_MODE_CHARACTERS is always on. // CAP_MODE_WORDS is on if there is some whitespace before the cursor. @@ -172,7 +168,7 @@ public final class CapsModeUtils { // mark as the exact thing quoted and handling the surrounding punctuation independently, // e.g. <<Did he say, "let's go home"?>> // Hence, specifically for English, we treat this special case here. - if (Locale.ENGLISH.getLanguage().equals(locale.getLanguage())) { + if (Locale.ENGLISH.getLanguage().equals(settingsValues.mLocale.getLanguage())) { for (; j > 0; j--) { // Here we look to go over any closing punctuation. This is because in dominant // variants of English, the final period is placed within double quotes and maybe @@ -195,7 +191,7 @@ public final class CapsModeUtils { if (c == Constants.CODE_QUESTION_MARK || c == Constants.CODE_EXCLAMATION_MARK) { return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_SENTENCES) & reqModes; } - if (!isPeriod(c) || j <= 0) { + if (settingsValues.mSentenceSeparator != c || j <= 0) { return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS) & reqModes; } @@ -245,7 +241,7 @@ public final class CapsModeUtils { case WORD: if (Character.isLetter(c)) { state = WORD; - } else if (isPeriod(c)) { + } else if (settingsValues.mSentenceSeparator == c) { state = PERIOD; } else { return caps; @@ -261,7 +257,7 @@ public final class CapsModeUtils { case LETTER: if (Character.isLetter(c)) { state = LETTER; - } else if (isPeriod(c)) { + } else if (settingsValues.mSentenceSeparator == c) { state = PERIOD; } else { return noCaps; diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp index 3d07c9d6c..a8ea69f3c 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_policy.cpp @@ -360,11 +360,11 @@ void DynamicPatriciaTriePolicy::getProperty(const char *const query, char *const } else if (strncmp(query, MAX_UNIGRAM_COUNT_QUERY, maxResultLength) == 0) { snprintf(outResult, maxResultLength, "%d", mHeaderPolicy.isDecayingDict() ? ForgettingCurveUtils::MAX_UNIGRAM_COUNT : - DynamicPatriciaTrieWritingHelper::MAX_DICTIONARY_SIZE); + static_cast<int>(DynamicPatriciaTrieWritingHelper::MAX_DICTIONARY_SIZE)); } else if (strncmp(query, MAX_BIGRAM_COUNT_QUERY, maxResultLength) == 0) { snprintf(outResult, maxResultLength, "%d", mHeaderPolicy.isDecayingDict() ? ForgettingCurveUtils::MAX_BIGRAM_COUNT : - DynamicPatriciaTrieWritingHelper::MAX_DICTIONARY_SIZE); + static_cast<int>(DynamicPatriciaTrieWritingHelper::MAX_DICTIONARY_SIZE)); } else if (strncmp(query, SET_NEEDS_TO_DECAY_FOR_TESTING_QUERY, maxResultLength) == 0) { mNeedsToDecayForTesting = true; } diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp index 067c8ec98..052558bfc 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp @@ -240,7 +240,8 @@ bool DynamicPatriciaTrieWritingHelper::markNodeAsMovedAndSetPosition( int parentOffsetFieldPos = nodeReader->getHeadPos() + DynamicPatriciaTrieWritingUtils::NODE_FLAG_FIELD_SIZE; if (!DynamicPatriciaTrieWritingUtils::writeParentPosOffsetAndAdvancePosition( - mBuffer, movedPos, nodeReader->getHeadPos(), &parentOffsetFieldPos)) { + mBuffer, bigramLinkedNodePos, nodeReader->getHeadPos(), + &parentOffsetFieldPos)) { // Parent offset cannot be written because of a bug or a broken dictionary; thus, // we give up to update dictionary. return false; diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java index cecdd2ffb..cd5384ea4 100644 --- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java +++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java @@ -18,6 +18,7 @@ package com.android.inputmethod.latin; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.LargeTest; +import android.util.Pair; import com.android.inputmethod.latin.makedict.CodePointUtils; import com.android.inputmethod.latin.makedict.FormatSpec; @@ -124,11 +125,16 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { binaryDictionary.addBigramWords("a", "c", DUMMY_PROBABILITY); assertTrue(binaryDictionary.isValidBigram("a", "c")); + // Add bigrams of not valid unigrams. + binaryDictionary.addBigramWords("x", "y", Dictionary.NOT_A_PROBABILITY); + assertFalse(binaryDictionary.isValidBigram("x", "y")); + binaryDictionary.addBigramWords("x", "y", DUMMY_PROBABILITY); + assertFalse(binaryDictionary.isValidBigram("x", "y")); + binaryDictionary.close(); dictFile.delete(); } - // TODO: Add large tests. public void testDecayingProbability() { File dictFile = null; try { @@ -233,4 +239,70 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTests( BinaryDictionary.UNIGRAM_COUNT_QUERY)) <= maxUnigramCount); } + + public void testAddManyBigramsToDecayingDict() { + final int unigramCount = 5000; + final int bigramCount = 30000; + final int bigramTypedCount = 100000; + final int codePointSetSize = 50; + final long seed = System.currentTimeMillis(); + final Random random = new Random(seed); + + File dictFile = null; + try { + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + } catch (IOException e) { + fail("IOException while writing an initial dictionary : " + e); + } + BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), + 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, + Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + + final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); + final ArrayList<String> words = new ArrayList<String>(); + final ArrayList<Pair<String, String>> bigrams = new ArrayList<Pair<String, String>>(); + + for (int i = 0; i < unigramCount; ++i) { + final String word = CodePointUtils.generateWord(random, codePointSet); + words.add(word); + } + for (int i = 0; i < bigramCount; ++i) { + final int word0Index = random.nextInt(words.size()); + int word1Index = random.nextInt(words.size() - 1); + if (word1Index >= word0Index) { + word1Index += 1; + } + final String word0 = words.get(word0Index); + final String word1 = words.get(word1Index); + final Pair<String, String> bigram = new Pair<String, String>(word0, word1); + bigrams.add(bigram); + } + + final int maxBigramCount = Integer.parseInt( + binaryDictionary.getPropertyForTests(BinaryDictionary.MAX_BIGRAM_COUNT_QUERY)); + for (int i = 0; i < bigramTypedCount; ++i) { + final Pair<String, String> bigram = bigrams.get(random.nextInt(bigrams.size())); + binaryDictionary.addUnigramWord(bigram.first, DUMMY_PROBABILITY); + binaryDictionary.addUnigramWord(bigram.second, DUMMY_PROBABILITY); + binaryDictionary.addBigramWords(bigram.first, bigram.second, DUMMY_PROBABILITY); + + if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { + final int bigramCountBeforeGC = + Integer.parseInt(binaryDictionary.getPropertyForTests( + BinaryDictionary.BIGRAM_COUNT_QUERY)); + while (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { + binaryDictionary.flushWithGC(); + } + final int bigramCountAfterGC = + Integer.parseInt(binaryDictionary.getPropertyForTests( + BinaryDictionary.BIGRAM_COUNT_QUERY)); + assertTrue(bigramCountBeforeGC > bigramCountAfterGC); + } + } + + assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTests( + BinaryDictionary.BIGRAM_COUNT_QUERY)) > 0); + assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTests( + BinaryDictionary.BIGRAM_COUNT_QUERY)) <= maxBigramCount); + } } diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java index 234bb1b31..b9b52a6f3 100644 --- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java +++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java @@ -238,12 +238,16 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { } protected void changeLanguage(final String locale) { + changeLanguageWithoutWait(locale); + waitForDictionaryToBeLoaded(); + } + + protected void changeLanguageWithoutWait(final String locale) { mEditText.mCurrentLocale = LocaleUtils.constructLocaleFromString(locale); SubtypeSwitcher.getInstance().forceLocale(mEditText.mCurrentLocale); mLatinIME.loadKeyboard(); runMessages(); mKeyboard = mLatinIME.mKeyboardSwitcher.getKeyboard(); - waitForDictionaryToBeLoaded(); } protected void changeKeyboardLocaleAndDictLocale(final String keyboardLocale, diff --git a/tests/src/com/android/inputmethod/latin/LatinImeStressTests.java b/tests/src/com/android/inputmethod/latin/LatinImeStressTests.java new file mode 100644 index 000000000..5e98cdf8d --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/LatinImeStressTests.java @@ -0,0 +1,61 @@ +/* + * 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; + +import android.test.suitebuilder.annotation.LargeTest; + +import com.android.inputmethod.latin.makedict.CodePointUtils; + +import java.util.Random; + +@LargeTest +public class LatinImeStressTests extends InputTestsBase { + public void testSwitchLanguagesAndInputLatinRandomCodePoints() { + final String[] locales = {"en_US", "de", "el", "es", "fi", "it", "nl", "pt", "ru"}; + final int switchCount = 50; + final int maxWordCountToTypeInEachIteration = 20; + final long seed = System.currentTimeMillis(); + final Random random = new Random(seed); + final int codePointSetSize = 30; + final int[] codePointSet = CodePointUtils.LATIN_ALPHABETS_LOWER; + for (int i = 0; i < switchCount; ++i) { + changeLanguageWithoutWait(locales[random.nextInt(locales.length)]); + final int wordCount = random.nextInt(maxWordCountToTypeInEachIteration); + for (int j = 0; j < wordCount; ++j) { + final String word = CodePointUtils.generateWord(random, codePointSet); + type(word); + } + } + } + public void testSwitchLanguagesAndInputRandamCodePoints() { + final String[] locales = {"en_US", "de", "el", "es", "fi", "it", "nl", "pt", "ru"}; + final int switchCount = 50; + final int maxWordCountToTypeInEachIteration = 20; + final long seed = System.currentTimeMillis(); + final Random random = new Random(seed); + final int codePointSetSize = 30; + final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); + for (int i = 0; i < switchCount; ++i) { + changeLanguageWithoutWait(locales[random.nextInt(locales.length)]); + final int wordCount = random.nextInt(maxWordCountToTypeInEachIteration); + for (int j = 0; j < wordCount; ++j) { + final String word = CodePointUtils.generateWord(random, codePointSet); + type(word); + } + } + } +} diff --git a/tests/src/com/android/inputmethod/latin/makedict/CodePointUtils.java b/tests/src/com/android/inputmethod/latin/makedict/CodePointUtils.java index 36b958af8..a270ee774 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/CodePointUtils.java +++ b/tests/src/com/android/inputmethod/latin/makedict/CodePointUtils.java @@ -24,6 +24,42 @@ public class CodePointUtils { // This utility class is not publicly instantiable. } + public static final int[] LATIN_ALPHABETS_LOWER = { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + 0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */, + 0x00E1 /* LATIN SMALL LETTER A WITH ACUTE */, + 0x00E2 /* LATIN SMALL LETTER A WITH CIRCUMFLEX */, + 0x00E3 /* LATIN SMALL LETTER A WITH TILDE */, + 0x00E4 /* LATIN SMALL LETTER A WITH DIAERESIS */, + 0x00E5 /* LATIN SMALL LETTER A WITH RING ABOVE */, + 0x00E6 /* LATIN SMALL LETTER AE */, + 0x00E7 /* LATIN SMALL LETTER C WITH CEDILLA */, + 0x00E8 /* LATIN SMALL LETTER E WITH GRAVE */, + 0x00E9 /* LATIN SMALL LETTER E WITH ACUTE */, + 0x00EA /* LATIN SMALL LETTER E WITH CIRCUMFLEX */, + 0x00EB /* LATIN SMALL LETTER E WITH DIAERESIS */, + 0x00EC /* LATIN SMALL LETTER I WITH GRAVE */, + 0x00ED /* LATIN SMALL LETTER I WITH ACUTE */, + 0x00EE /* LATIN SMALL LETTER I WITH CIRCUMFLEX */, + 0x00EF /* LATIN SMALL LETTER I WITH DIAERESIS */, + 0x00F0 /* LATIN SMALL LETTER ETH */, + 0x00F1 /* LATIN SMALL LETTER N WITH TILDE */, + 0x00F2 /* LATIN SMALL LETTER O WITH GRAVE */, + 0x00F3 /* LATIN SMALL LETTER O WITH ACUTE */, + 0x00F4 /* LATIN SMALL LETTER O WITH CIRCUMFLEX */, + 0x00F5 /* LATIN SMALL LETTER O WITH TILDE */, + 0x00F6 /* LATIN SMALL LETTER O WITH DIAERESIS */, + 0x00F7 /* LATIN SMALL LETTER O WITH STROKE */, + 0x00F9 /* LATIN SMALL LETTER U WITH GRAVE */, + 0x00FA /* LATIN SMALL LETTER U WITH ACUTE */, + 0x00FB /* LATIN SMALL LETTER U WITH CIRCUMFLEX */, + 0x00FC /* LATIN SMALL LETTER U WITH DIAERESIS */, + 0x00FD /* LATIN SMALL LETTER Y WITH ACUTE */, + 0x00FE /* LATIN SMALL LETTER THORN */, + 0x00FF /* LATIN SMALL LETTER Y WITH DIAERESIS */ + }; + public static int[] generateCodePointSet(final int codePointSetSize, final Random random) { final int[] codePointSet = new int[codePointSetSize]; for (int i = codePointSet.length - 1; i >= 0; ) { diff --git a/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java index cf3bdd680..1fd5c989a 100644 --- a/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java @@ -16,6 +16,8 @@ package com.android.inputmethod.latin.utils; +import com.android.inputmethod.latin.settings.SettingsValues; + import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; import android.text.TextUtils; @@ -25,64 +27,64 @@ import java.util.Locale; @SmallTest public class CapsModeUtilsTests extends AndroidTestCase { private static void onePathForCaps(final CharSequence cs, final int expectedResult, - final int mask, final Locale l, final boolean hasSpaceBefore) { + final int mask, final SettingsValues sv, final boolean hasSpaceBefore) { int oneTimeResult = expectedResult & mask; assertEquals("After >" + cs + "<", oneTimeResult, - CapsModeUtils.getCapsMode(cs, mask, l, hasSpaceBefore)); + CapsModeUtils.getCapsMode(cs, mask, sv, hasSpaceBefore)); } private static void allPathsForCaps(final CharSequence cs, final int expectedResult, - final Locale l, final boolean hasSpaceBefore) { + final SettingsValues sv, final boolean hasSpaceBefore) { final int c = TextUtils.CAP_MODE_CHARACTERS; final int w = TextUtils.CAP_MODE_WORDS; final int s = TextUtils.CAP_MODE_SENTENCES; - onePathForCaps(cs, expectedResult, c | w | s, l, hasSpaceBefore); - onePathForCaps(cs, expectedResult, w | s, l, hasSpaceBefore); - onePathForCaps(cs, expectedResult, c | s, l, hasSpaceBefore); - onePathForCaps(cs, expectedResult, c | w, l, hasSpaceBefore); - onePathForCaps(cs, expectedResult, c, l, hasSpaceBefore); - onePathForCaps(cs, expectedResult, w, l, hasSpaceBefore); - onePathForCaps(cs, expectedResult, s, l, hasSpaceBefore); + onePathForCaps(cs, expectedResult, c | w | s, sv, hasSpaceBefore); + onePathForCaps(cs, expectedResult, w | s, sv, hasSpaceBefore); + onePathForCaps(cs, expectedResult, c | s, sv, hasSpaceBefore); + onePathForCaps(cs, expectedResult, c | w, sv, hasSpaceBefore); + onePathForCaps(cs, expectedResult, c, sv, hasSpaceBefore); + onePathForCaps(cs, expectedResult, w, sv, hasSpaceBefore); + onePathForCaps(cs, expectedResult, s, sv, hasSpaceBefore); } public void testGetCapsMode() { final int c = TextUtils.CAP_MODE_CHARACTERS; final int w = TextUtils.CAP_MODE_WORDS; final int s = TextUtils.CAP_MODE_SENTENCES; - Locale l = Locale.ENGLISH; - allPathsForCaps("", c | w | s, l, false); - allPathsForCaps("Word", c, l, false); - allPathsForCaps("Word.", c, l, false); - allPathsForCaps("Word ", c | w, l, false); - allPathsForCaps("Word. ", c | w | s, l, false); - allPathsForCaps("Word..", c, l, false); - allPathsForCaps("Word.. ", c | w | s, l, false); - allPathsForCaps("Word... ", c | w | s, l, false); - allPathsForCaps("Word ... ", c | w | s, l, false); - allPathsForCaps("Word . ", c | w, l, false); - allPathsForCaps("In the U.S ", c | w, l, false); - allPathsForCaps("In the U.S. ", c | w, l, false); - allPathsForCaps("Some stuff (e.g. ", c | w, l, false); - allPathsForCaps("In the U.S.. ", c | w | s, l, false); - allPathsForCaps("\"Word.\" ", c | w | s, l, false); - allPathsForCaps("\"Word\". ", c | w | s, l, false); - allPathsForCaps("\"Word\" ", c | w, l, false); + SettingsValues sv = SettingsValues.makeDummySettingsValuesForTest(Locale.ENGLISH); + allPathsForCaps("", c | w | s, sv, false); + allPathsForCaps("Word", c, sv, false); + allPathsForCaps("Word.", c, sv, false); + allPathsForCaps("Word ", c | w, sv, false); + allPathsForCaps("Word. ", c | w | s, sv, false); + allPathsForCaps("Word..", c, sv, false); + allPathsForCaps("Word.. ", c | w | s, sv, false); + allPathsForCaps("Word... ", c | w | s, sv, false); + allPathsForCaps("Word ... ", c | w | s, sv, false); + allPathsForCaps("Word . ", c | w, sv, false); + allPathsForCaps("In the U.S ", c | w, sv, false); + allPathsForCaps("In the U.S. ", c | w, sv, false); + allPathsForCaps("Some stuff (e.g. ", c | w, sv, false); + allPathsForCaps("In the U.S.. ", c | w | s, sv, false); + allPathsForCaps("\"Word.\" ", c | w | s, sv, false); + allPathsForCaps("\"Word\". ", c | w | s, sv, false); + allPathsForCaps("\"Word\" ", c | w, sv, false); // Test for phantom space - allPathsForCaps("Word", c | w, l, true); - allPathsForCaps("Word.", c | w | s, l, true); + allPathsForCaps("Word", c | w, sv, true); + allPathsForCaps("Word.", c | w | s, sv, true); // Tests after some whitespace - allPathsForCaps("Word\n", c | w | s, l, false); - allPathsForCaps("Word\n", c | w | s, l, true); - allPathsForCaps("Word\n ", c | w | s, l, true); - allPathsForCaps("Word.\n", c | w | s, l, false); - allPathsForCaps("Word.\n", c | w | s, l, true); - allPathsForCaps("Word.\n ", c | w | s, l, true); + allPathsForCaps("Word\n", c | w | s, sv, false); + allPathsForCaps("Word\n", c | w | s, sv, true); + allPathsForCaps("Word\n ", c | w | s, sv, true); + allPathsForCaps("Word.\n", c | w | s, sv, false); + allPathsForCaps("Word.\n", c | w | s, sv, true); + allPathsForCaps("Word.\n ", c | w | s, sv, true); - l = Locale.FRENCH; - allPathsForCaps("\"Word.\" ", c | w, l, false); - allPathsForCaps("\"Word\". ", c | w | s, l, false); - allPathsForCaps("\"Word\" ", c | w, l, false); + sv = SettingsValues.makeDummySettingsValuesForTest(Locale.FRENCH); + allPathsForCaps("\"Word.\" ", c | w, sv, false); + allPathsForCaps("\"Word\". ", c | w | s, sv, false); + allPathsForCaps("\"Word\" ", c | w, sv, false); } } diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java index bd06e9f3a..e571bc21d 100644 --- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java +++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java @@ -183,7 +183,11 @@ public final class BinaryDictOffdeviceUtils { filename + " does not seem to be a dictionary file")); } else if (CombinedInputOutput.isCombinedDictionary( decodedSpec.mFile.getAbsolutePath())){ - if (report) System.out.println("Format : Combined format"); + if (report) { + System.out.println("Format : Combined format"); + System.out.println("Packaging : " + decodedSpec.describeChain()); + System.out.println("Uncompressed size : " + decodedSpec.mFile.length()); + } return CombinedInputOutput.readDictionaryCombined( new BufferedInputStream(new FileInputStream(decodedSpec.mFile))); } else { |