diff options
Diffstat (limited to 'java/src')
26 files changed, 366 insertions, 217 deletions
diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java index 8badaf4b9..4a8fa51ee 100644 --- a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java +++ b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java @@ -45,10 +45,8 @@ public class MetadataDbHelper extends SQLiteOpenHelper { // This is the first released version of the database that implements CLIENTID. It is // used to identify the versions for upgrades. This should never change going forward. private static final int METADATA_DATABASE_VERSION_WITH_CLIENTID = 6; - // This is the current database version. It should be updated when the database schema - // gets updated. It is passed to the framework constructor of SQLiteOpenHelper, so - // that's what the framework uses to track our database version. - private static final int METADATA_DATABASE_VERSION = 6; + // The current database version. + private static final int CURRENT_METADATA_DATABASE_VERSION = 7; private final static long NOT_A_DOWNLOAD_ID = -1; @@ -169,7 +167,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper { private MetadataDbHelper(final Context context, final String clientId) { super(context, METADATA_DATABASE_NAME_STEM + (TextUtils.isEmpty(clientId) ? "" : "." + clientId), - null, METADATA_DATABASE_VERSION); + null, CURRENT_METADATA_DATABASE_VERSION); mContext = context; mClientId = clientId; } @@ -219,22 +217,45 @@ public class MetadataDbHelper extends SQLiteOpenHelper { /** * Upgrade the database. Upgrade from version 3 is supported. + * Version 3 has a DB named METADATA_DATABASE_NAME_STEM containing a table METADATA_TABLE_NAME. + * Version 6 and above has a DB named METADATA_DATABASE_NAME_STEM containing a + * table CLIENT_TABLE_NAME, and for each client a table called METADATA_TABLE_STEM + "." + the + * name of the client and contains a table METADATA_TABLE_NAME. + * For schemas, see the above create statements. The schemas have never changed so far. + * + * This method is called by the framework. See {@link SQLiteOpenHelper#onUpgrade} + * @param db The database we are upgrading + * @param oldVersion The old database version (the one on the disk) + * @param newVersion The new database version as supplied to the constructor of SQLiteOpenHelper */ @Override public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) { if (METADATA_DATABASE_INITIAL_VERSION == oldVersion - && METADATA_DATABASE_VERSION_WITH_CLIENTID == newVersion) { + && METADATA_DATABASE_VERSION_WITH_CLIENTID <= newVersion + && CURRENT_METADATA_DATABASE_VERSION >= newVersion) { // Upgrade from version METADATA_DATABASE_INITIAL_VERSION to version // METADATA_DATABASE_VERSION_WITH_CLIENT_ID + // Only the default database should contain the client table, so we test for mClientId. if (TextUtils.isEmpty(mClientId)) { - // Only the default database should contain the client table. - // Anyway in version 3 only the default table existed so the emptyness + // Anyway in version 3 only the default table existed so the emptiness // test should always be true, but better check to be sure. createClientTable(db); } + } else if (METADATA_DATABASE_VERSION_WITH_CLIENTID < newVersion + && CURRENT_METADATA_DATABASE_VERSION >= newVersion) { + // Here we drop the client table, so that all clients send us their information again. + // The client table contains the URL to hit to update the available dictionaries list, + // but the info about the dictionaries themselves is stored in the table called + // METADATA_TABLE_NAME and we want to keep it, so we only drop the client table. + db.execSQL("DROP TABLE IF EXISTS " + CLIENT_TABLE_NAME); + // Only the default database should contain the client table, so we test for mClientId. + if (TextUtils.isEmpty(mClientId)) { + createClientTable(db); + } } else { - // Version 3 was the earliest version, so we should never come here. If we do, we - // have no idea what this database is, so we'd better wipe it off. + // If we're not in the above case, either we are upgrading from an earlier versionCode + // and we should wipe the database, or we are handling a version we never heard about + // (can only be a bug) so it's safer to wipe the database. db.execSQL("DROP TABLE IF EXISTS " + METADATA_TABLE_NAME); db.execSQL("DROP TABLE IF EXISTS " + CLIENT_TABLE_NAME); onCreate(db); diff --git a/java/src/com/android/inputmethod/event/Event.java b/java/src/com/android/inputmethod/event/Event.java index 646590948..6535d2d76 100644 --- a/java/src/com/android/inputmethod/event/Event.java +++ b/java/src/com/android/inputmethod/event/Event.java @@ -36,25 +36,25 @@ public class Event { // Should the types below be represented by separate classes instead? It would be cleaner // but probably a bit too much // An event we don't handle in Latin IME, for example pressing Ctrl on a hardware keyboard. - final public static int EVENT_NOT_HANDLED = 0; + final public static int EVENT_TYPE_NOT_HANDLED = 0; // A key press that is part of input, for example pressing an alphabetic character on a // hardware qwerty keyboard. It may be part of a sequence that will be re-interpreted later // through combination. - final public static int EVENT_INPUT_KEYPRESS = 1; + final public static int EVENT_TYPE_INPUT_KEYPRESS = 1; // A toggle event is triggered by a key that affects the previous character. An example would // be a numeric key on a 10-key keyboard, which would toggle between 1 - a - b - c with // repeated presses. - final public static int EVENT_TOGGLE = 2; + final public static int EVENT_TYPE_TOGGLE = 2; // A mode event instructs the combiner to change modes. The canonical example would be the // hankaku/zenkaku key on a Japanese keyboard, or even the caps lock key on a qwerty keyboard // if handled at the combiner level. - final public static int EVENT_MODE_KEY = 3; + final public static int EVENT_TYPE_MODE_KEY = 3; // An event corresponding to a gesture. - final public static int EVENT_GESTURE = 4; + final public static int EVENT_TYPE_GESTURE = 4; // An event corresponding to the manual pick of a suggestion. - final public static int EVENT_SUGGESTION_PICKED = 5; + final public static int EVENT_TYPE_SUGGESTION_PICKED = 5; // An event corresponding to a string generated by some software process. - final public static int EVENT_SOFTWARE_GENERATED_STRING = 6; + final public static int EVENT_TYPE_SOFTWARE_GENERATED_STRING = 6; // 0 is a valid code point, so we use -1 here. final public static int NOT_A_CODE_POINT = -1; @@ -66,7 +66,7 @@ public class Event { // or dead-abovering. final private static int FLAG_DEAD = 0x1; - final private int mType; // The type of event - one of the constants above + final private int mEventType; // The type of event - one of the constants above // The code point associated with the event, if relevant. This is a unicode code point, and // has nothing to do with other representations of the key. It is only relevant if this event // is of KEYPRESS type, but for a mode key like hankaku/zenkaku or ctrl, there is no code point @@ -94,7 +94,7 @@ public class Event { // Some flags that can't go into the key code. It's a bit field of FLAG_* final private int mFlags; - // If this is of type EVENT_SUGGESTION_PICKED, this must not be null (and must be null in + // If this is of type EVENT_TYPE_SUGGESTION_PICKED, this must not be null (and must be null in // other cases). final public SuggestedWordInfo mSuggestedWordInfo; @@ -105,7 +105,7 @@ public class Event { private Event(final int type, final CharSequence text, final int codePoint, final int keyCode, final int x, final int y, final SuggestedWordInfo suggestedWordInfo, final int flags, final Event next) { - mType = type; + mEventType = type; mText = text; mCodePoint = codePoint; mKeyCode = keyCode; @@ -116,7 +116,7 @@ public class Event { mNextEvent = next; // Sanity checks // mSuggestedWordInfo is non-null if and only if the type is SUGGESTION_PICKED - if (EVENT_SUGGESTION_PICKED == mType) { + if (EVENT_TYPE_SUGGESTION_PICKED == mEventType) { if (null == mSuggestedWordInfo) { throw new RuntimeException("Wrong event: SUGGESTION_PICKED event must have a " + "non-null SuggestedWordInfo"); @@ -131,13 +131,13 @@ public class Event { public static Event createSoftwareKeypressEvent(final int codePoint, final int keyCode, final int x, final int y) { - return new Event(EVENT_INPUT_KEYPRESS, null /* text */, codePoint, keyCode, x, y, - null /* suggestedWordInfo */, FLAG_NONE, null); + return new Event(EVENT_TYPE_INPUT_KEYPRESS, null /* text */, codePoint, keyCode, x, y, + null /* suggestedWordInfo */, FLAG_NONE, null /* next */); } public static Event createHardwareKeypressEvent(final int codePoint, final int keyCode, final Event next) { - return new Event(EVENT_INPUT_KEYPRESS, null /* text */, codePoint, keyCode, + return new Event(EVENT_TYPE_INPUT_KEYPRESS, null /* text */, codePoint, keyCode, Constants.EXTERNAL_KEYBOARD_COORDINATE, Constants.EXTERNAL_KEYBOARD_COORDINATE, null /* suggestedWordInfo */, FLAG_NONE, next); } @@ -145,7 +145,7 @@ public class Event { // This creates an input event for a dead character. @see {@link #FLAG_DEAD} public static Event createDeadEvent(final int codePoint, final int keyCode, final Event next) { // TODO: add an argument or something if we ever create a software layout with dead keys. - return new Event(EVENT_INPUT_KEYPRESS, null /* text */, codePoint, keyCode, + return new Event(EVENT_TYPE_INPUT_KEYPRESS, null /* text */, codePoint, keyCode, Constants.EXTERNAL_KEYBOARD_COORDINATE, Constants.EXTERNAL_KEYBOARD_COORDINATE, null /* suggestedWordInfo */, FLAG_DEAD, next); } @@ -159,7 +159,7 @@ public class Event { */ public static Event createEventForCodePointFromUnknownSource(final int codePoint) { // TODO: should we have a different type of event for this? After all, it's not a key press. - return new Event(EVENT_INPUT_KEYPRESS, null /* text */, codePoint, NOT_A_KEY_CODE, + return new Event(EVENT_TYPE_INPUT_KEYPRESS, null /* text */, codePoint, NOT_A_KEY_CODE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, null /* suggestedWordInfo */, FLAG_NONE, null /* next */); } @@ -175,8 +175,8 @@ public class Event { public static Event createEventForCodePointFromAlreadyTypedText(final int codePoint, final int x, final int y) { // TODO: should we have a different type of event for this? After all, it's not a key press. - return new Event(EVENT_INPUT_KEYPRESS, null /* text */, codePoint, NOT_A_KEY_CODE, x, y, - null /* suggestedWordInfo */, FLAG_NONE, null /* next */); + return new Event(EVENT_TYPE_INPUT_KEYPRESS, null /* text */, codePoint, NOT_A_KEY_CODE, + x, y, null /* suggestedWordInfo */, FLAG_NONE, null /* next */); } /** @@ -184,10 +184,10 @@ public class Event { * @return an event for this suggestion pick. */ public static Event createSuggestionPickedEvent(final SuggestedWordInfo suggestedWordInfo) { - return new Event(EVENT_SUGGESTION_PICKED, suggestedWordInfo.mWord, + return new Event(EVENT_TYPE_SUGGESTION_PICKED, suggestedWordInfo.mWord, NOT_A_CODE_POINT, NOT_A_KEY_CODE, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, - suggestedWordInfo, FLAG_NONE, null); + suggestedWordInfo, FLAG_NONE, null /* next */); } /** @@ -199,13 +199,26 @@ public class Event { * @return an event for this text. */ public static Event createSoftwareTextEvent(final CharSequence text, final int keyCode) { - return new Event(EVENT_SOFTWARE_GENERATED_STRING, text, NOT_A_CODE_POINT, keyCode, + return new Event(EVENT_TYPE_SOFTWARE_GENERATED_STRING, text, NOT_A_CODE_POINT, keyCode, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, null /* suggestedWordInfo */, FLAG_NONE, null /* next */); } + /** + * Creates an input event representing the manual pick of a punctuation suggestion. + * @return an event for this suggestion pick. + */ + public static Event createPunctuationSuggestionPickedEvent( + final SuggestedWordInfo suggestedWordInfo) { + final int primaryCode = suggestedWordInfo.mWord.charAt(0); + return new Event(EVENT_TYPE_SUGGESTION_PICKED, suggestedWordInfo.mWord, primaryCode, + NOT_A_KEY_CODE, Constants.SUGGESTION_STRIP_COORDINATE, + Constants.SUGGESTION_STRIP_COORDINATE, suggestedWordInfo, FLAG_NONE, + null /* next */); + } + public static Event createNotHandledEvent() { - return new Event(EVENT_NOT_HANDLED, null /* text */, NOT_A_CODE_POINT, NOT_A_KEY_CODE, + return new Event(EVENT_TYPE_NOT_HANDLED, null /* text */, NOT_A_CODE_POINT, NOT_A_KEY_CODE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, null /* suggestedWordInfo */, FLAG_NONE, null); } @@ -218,25 +231,26 @@ public class Event { // Returns whether this is a fake key press from the suggestion strip. This happens with // punctuation signs selected from the suggestion strip. public boolean isSuggestionStripPress() { - return EVENT_INPUT_KEYPRESS == mType && Constants.SUGGESTION_STRIP_COORDINATE == mX; + return EVENT_TYPE_SUGGESTION_PICKED == mEventType; } public boolean isHandled() { - return EVENT_NOT_HANDLED != mType; + return EVENT_TYPE_NOT_HANDLED != mEventType; } public CharSequence getTextToCommit() { - switch (mType) { - case EVENT_MODE_KEY: - case EVENT_NOT_HANDLED: - case EVENT_TOGGLE: + switch (mEventType) { + case EVENT_TYPE_MODE_KEY: + case EVENT_TYPE_NOT_HANDLED: + case EVENT_TYPE_TOGGLE: return ""; - case EVENT_INPUT_KEYPRESS: + case EVENT_TYPE_INPUT_KEYPRESS: return StringUtils.newSingleCodePointString(mCodePoint); - case EVENT_GESTURE: - case EVENT_SOFTWARE_GENERATED_STRING: + case EVENT_TYPE_GESTURE: + case EVENT_TYPE_SOFTWARE_GENERATED_STRING: + case EVENT_TYPE_SUGGESTION_PICKED: return mText; } - throw new RuntimeException("Unknown event type: " + mType); + throw new RuntimeException("Unknown event type: " + mEventType); } } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 37a4bf8f6..2e4a0902d 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -204,10 +204,12 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { keyboardView.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady()); final boolean subtypeChanged = (oldKeyboard == null) || !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale); - final boolean needsToDisplayLanguage = mSubtypeSwitcher.needsToDisplayLanguage( + final int languageOnSpacebarFormatType = mSubtypeSwitcher.getLanguageOnSpacebarFormatType( keyboard.mId.mSubtype); - keyboardView.startDisplayLanguageOnSpacebar(subtypeChanged, needsToDisplayLanguage, - RichInputMethodManager.getInstance().hasMultipleEnabledIMEsOrSubtypes(true)); + final boolean hasMultipleEnabledIMEsOrSubtypes = RichInputMethodManager.getInstance() + .hasMultipleEnabledIMEsOrSubtypes(true /* shouldIncludeAuxiliarySubtypes */); + keyboardView.startDisplayLanguageOnSpacebar(subtypeChanged, languageOnSpacebarFormatType, + hasMultipleEnabledIMEsOrSubtypes); } public Keyboard getKeyboard() { @@ -217,22 +219,15 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { return null; } - /** - * Update keyboard shift state triggered by connected EditText status change. - */ - public void updateShiftState() { - mState.onUpdateShiftState(mLatinIME.getCurrentAutoCapsState(), - mLatinIME.getCurrentRecapitalizeState()); - } - // TODO: Remove this method. Come up with a more comprehensive way to reset the keyboard layout // when a keyboard layout set doesn't get reloaded in LatinIME.onStartInputViewInternal(). public void resetKeyboardStateToAlphabet() { mState.onResetKeyboardStateToAlphabet(); } - public void onPressKey(final int code, final boolean isSinglePointer) { - mState.onPressKey(code, isSinglePointer, mLatinIME.getCurrentAutoCapsState()); + public void onPressKey(final int code, final boolean isSinglePointer, + final int currentAutoCapsState) { + mState.onPressKey(code, isSinglePointer, currentAutoCapsState); } public void onReleaseKey(final int code, final boolean withSliding) { @@ -336,8 +331,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { /** * Updates state machine to figure out when to automatically switch back to the previous mode. */ - public void onCodeInput(final int code) { - mState.onCodeInput(code, mLatinIME.getCurrentAutoCapsState()); + public void onCodeInput(final int code, final int currentAutoCapsState) { + mState.onCodeInput(code, currentAutoCapsState); } public boolean isShowingEmojiPalettes() { diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index 03425ef1f..0f9c39a80 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -49,6 +49,7 @@ import com.android.inputmethod.keyboard.internal.GestureTrailsDrawingPreview; import com.android.inputmethod.keyboard.internal.KeyDrawParams; import com.android.inputmethod.keyboard.internal.KeyPreviewChoreographer; import com.android.inputmethod.keyboard.internal.KeyPreviewDrawParams; +import com.android.inputmethod.keyboard.internal.LanguageOnSpacebarHelper; import com.android.inputmethod.keyboard.internal.NonDistinctMultitouchHelper; import com.android.inputmethod.keyboard.internal.SlidingKeyInputDrawingPreview; import com.android.inputmethod.keyboard.internal.TimerHandler; @@ -123,7 +124,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack // Stuff to draw language name on spacebar. private final int mLanguageOnSpacebarFinalAlpha; private ObjectAnimator mLanguageOnSpacebarFadeoutAnimator; - private boolean mNeedsToDisplayLanguage; + private int mLanguageOnSpacebarFormatType; private boolean mHasMultipleEnabledIMEsOrSubtypes; private int mLanguageOnSpacebarAnimAlpha = Constants.Color.ALPHA_OPAQUE; private final float mLanguageOnSpacebarTextRatio; @@ -811,14 +812,16 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack } public void startDisplayLanguageOnSpacebar(final boolean subtypeChanged, - final boolean needsToDisplayLanguage, final boolean hasMultipleEnabledIMEsOrSubtypes) { - mNeedsToDisplayLanguage = needsToDisplayLanguage; + final int languageOnSpacebarFormatType, + final boolean hasMultipleEnabledIMEsOrSubtypes) { + mLanguageOnSpacebarFormatType = languageOnSpacebarFormatType; mHasMultipleEnabledIMEsOrSubtypes = hasMultipleEnabledIMEsOrSubtypes; final ObjectAnimator animator = mLanguageOnSpacebarFadeoutAnimator; if (animator == null) { - mNeedsToDisplayLanguage = false; + mLanguageOnSpacebarFormatType = LanguageOnSpacebarHelper.FORMAT_TYPE_NONE; } else { - if (subtypeChanged && needsToDisplayLanguage) { + if (subtypeChanged + && languageOnSpacebarFormatType != LanguageOnSpacebarHelper.FORMAT_TYPE_NONE) { setLanguageOnSpacebarAnimAlpha(Constants.Color.ALPHA_OPAQUE); if (animator.isStarted()) { animator.cancel(); @@ -919,9 +922,11 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack private String layoutLanguageOnSpacebar(final Paint paint, final InputMethodSubtype subtype, final int width) { // Choose appropriate language name to fit into the width. - final String fullText = SpacebarLanguageUtils.getFullDisplayName(subtype); - if (fitsTextIntoWidth(width, fullText, paint)) { - return fullText; + if (mLanguageOnSpacebarFormatType == LanguageOnSpacebarHelper.FORMAT_TYPE_FULL_LOCALE) { + final String fullText = SpacebarLanguageUtils.getFullDisplayName(subtype); + if (fitsTextIntoWidth(width, fullText, paint)) { + return fullText; + } } final String middleText = SpacebarLanguageUtils.getMiddleDisplayName(subtype); @@ -937,7 +942,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack final int height = key.getHeight(); // If input language are explicitly selected. - if (mNeedsToDisplayLanguage) { + if (mLanguageOnSpacebarFormatType != LanguageOnSpacebarHelper.FORMAT_TYPE_NONE) { paint.setTextAlign(Align.CENTER); paint.setTypeface(Typeface.DEFAULT); paint.setTextSize(mLanguageOnSpacebarTextSize); diff --git a/java/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelper.java b/java/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelper.java new file mode 100644 index 000000000..6400a2440 --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelper.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.internal; + +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +import java.util.Collections; +import java.util.List; + +/** + * This class determines that the language name on the spacebar should be displayed in what format. + */ +public final class LanguageOnSpacebarHelper { + public static final int FORMAT_TYPE_NONE = 0; + public static final int FORMAT_TYPE_LANGUAGE_ONLY = 1; + public static final int FORMAT_TYPE_FULL_LOCALE = 2; + + private List<InputMethodSubtype> mEnabledSubtypes = Collections.emptyList(); + private boolean mIsSystemLanguageSameAsInputLanguage; + + public int getLanguageOnSpacebarFormatType(final InputMethodSubtype subtype) { + if (SubtypeLocaleUtils.isNoLanguage(subtype)) { + return FORMAT_TYPE_FULL_LOCALE; + } + // Only this subtype is enabled and equals to the system locale. + if (mEnabledSubtypes.size() < 2 && mIsSystemLanguageSameAsInputLanguage) { + return FORMAT_TYPE_NONE; + } + final String keyboardLanguage = SubtypeLocaleUtils.getSubtypeLocale(subtype).getLanguage(); + final String keyboardLayout = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype); + int sameLanguageAndLayoutCount = 0; + for (final InputMethodSubtype ims : mEnabledSubtypes) { + final String language = SubtypeLocaleUtils.getSubtypeLocale(ims).getLanguage(); + if (keyboardLanguage.equals(language) && keyboardLayout.equals( + SubtypeLocaleUtils.getKeyboardLayoutSetName(ims))) { + sameLanguageAndLayoutCount++; + } + } + // Display full locale name only when there are multiple subtypes that have the same + // locale and keyboard layout. Otherwise displaying language name is enough. + return sameLanguageAndLayoutCount > 1 ? FORMAT_TYPE_FULL_LOCALE + : FORMAT_TYPE_LANGUAGE_ONLY; + } + + public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes) { + mEnabledSubtypes = enabledSubtypes; + } + + public void updateIsSystemLanguageSameAsInputLanguage(final boolean isSame) { + mIsSystemLanguageSameAsInputLanguage = isSame; + } +} diff --git a/java/src/com/android/inputmethod/keyboard/internal/NeedsToDisplayLanguage.java b/java/src/com/android/inputmethod/keyboard/internal/NeedsToDisplayLanguage.java deleted file mode 100644 index e548de589..000000000 --- a/java/src/com/android/inputmethod/keyboard/internal/NeedsToDisplayLanguage.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.inputmethod.keyboard.internal; - -import android.view.inputmethod.InputMethodSubtype; - -import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; - -/** - * This class determines that the language name on the spacebar should be displayed or not. - */ -public final class NeedsToDisplayLanguage { - private int mEnabledSubtypeCount; - private boolean mIsSystemLanguageSameAsInputLanguage; - - public boolean needsToDisplayLanguage(final InputMethodSubtype subtype) { - if (SubtypeLocaleUtils.isNoLanguage(subtype)) { - return true; - } - return mEnabledSubtypeCount >= 2 || !mIsSystemLanguageSameAsInputLanguage; - } - - public void updateEnabledSubtypeCount(final int count) { - mEnabledSubtypeCount = count; - } - - public void updateIsSystemLanguageSameAsInputLanguage(final boolean isSame) { - mIsSystemLanguageSameAsInputLanguage = isSame; - } -} diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 60ac1ba48..30c2dfedb 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -89,6 +89,8 @@ public final class BinaryDictionary extends Dictionary { private final long mDictSize; private final String mDictFilePath; private final boolean mIsUpdatable; + private boolean mHasUpdated; + private final int[] mInputCodePoints = new int[MAX_WORD_LENGTH]; private final int[] mOutputSuggestionCount = new int[1]; private final int[] mOutputCodePoints = new int[MAX_WORD_LENGTH * MAX_RESULTS]; @@ -97,6 +99,7 @@ public final class BinaryDictionary extends Dictionary { private final int[] mOutputTypes = new int[MAX_RESULTS]; // Only one result is ever used private final int[] mOutputAutoCommitFirstWordConfidence = new int[1]; + private final float[] mInputOutputLanguageWeight = new float[1]; private final NativeSuggestOptions mNativeSuggestOptions = new NativeSuggestOptions(); @@ -137,6 +140,7 @@ public final class BinaryDictionary extends Dictionary { mDictSize = length; mDictFilePath = filename; mIsUpdatable = isUpdatable; + mHasUpdated = false; mNativeSuggestOptions.setUseFullEditDistance(useFullEditDistance); loadDictionary(filename, offset, length, isUpdatable); } @@ -167,7 +171,7 @@ public final class BinaryDictionary extends Dictionary { int[] pointerIds, int[] inputCodePoints, int inputSize, int[] suggestOptions, int[] prevWordCodePointArray, int[] outputSuggestionCount, int[] outputCodePoints, int[] outputScores, int[] outputIndices, int[] outputTypes, - int[] outputAutoCommitFirstWordConfidence); + int[] outputAutoCommitFirstWordConfidence, float[] inOutLanguageWeight); private static native void addUnigramWordNative(long dict, int[] word, int probability, int[] shortcutTarget, int shortcutProbability, boolean isNotAWord, boolean isBlacklisted, int timestamp); @@ -184,6 +188,7 @@ public final class BinaryDictionary extends Dictionary { // TODO: Move native dict into session private final void loadDictionary(final String path, final long startOffset, final long length, final boolean isUpdatable) { + mHasUpdated = false; mNativeDict = openNative(path, startOffset, length, isUpdatable); } @@ -231,16 +236,17 @@ public final class BinaryDictionary extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, - final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) { + final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, + final float[] inOutLanguageWeight) { return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords, - additionalFeaturesOptions, 0 /* sessionId */); + additionalFeaturesOptions, 0 /* sessionId */, inOutLanguageWeight); } @Override public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final int sessionId) { + final int sessionId, final float[] inOutLanguageWeight) { if (!isValidDictionary()) return null; Arrays.fill(mInputCodePoints, Constants.NOT_A_CODE); @@ -261,13 +267,22 @@ public final class BinaryDictionary extends Dictionary { final int inputSize = isGesture ? ips.getPointerSize() : composerSize; mNativeSuggestOptions.setIsGesture(isGesture); mNativeSuggestOptions.setAdditionalFeaturesOptions(additionalFeaturesOptions); + if (inOutLanguageWeight != null) { + mInputOutputLanguageWeight[0] = inOutLanguageWeight[0]; + } else { + mInputOutputLanguageWeight[0] = Dictionary.NOT_A_LANGUAGE_WEIGHT; + } // proximityInfo and/or prevWordForBigrams may not be null. getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(), getTraverseSession(sessionId).getSession(), ips.getXCoordinates(), ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(), mInputCodePoints, inputSize, mNativeSuggestOptions.getOptions(), prevWordCodePointArray, mOutputSuggestionCount, mOutputCodePoints, mOutputScores, - mSpaceIndices, mOutputTypes, mOutputAutoCommitFirstWordConfidence); + mSpaceIndices, mOutputTypes, mOutputAutoCommitFirstWordConfidence, + mInputOutputLanguageWeight); + if (inOutLanguageWeight != null) { + inOutLanguageWeight[0] = mInputOutputLanguageWeight[0]; + } final int count = mOutputSuggestionCount[0]; final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList(); for (int j = 0; j < count; ++j) { @@ -390,6 +405,7 @@ public final class BinaryDictionary extends Dictionary { StringUtils.toCodePointArray(shortcutTarget) : null; addUnigramWordNative(mNativeDict, codePoints, probability, shortcutTargetCodePoints, shortcutProbability, isNotAWord, isBlacklisted, timestamp); + mHasUpdated = true; } // Add a bigram entry to binary dictionary with timestamp in native code. @@ -401,6 +417,7 @@ public final class BinaryDictionary extends Dictionary { final int[] codePoints0 = StringUtils.toCodePointArray(word0); final int[] codePoints1 = StringUtils.toCodePointArray(word1); addBigramWordsNative(mNativeDict, codePoints0, codePoints1, probability, timestamp); + mHasUpdated = true; } // Remove a bigram entry form binary dictionary in native code. @@ -411,6 +428,7 @@ public final class BinaryDictionary extends Dictionary { final int[] codePoints0 = StringUtils.toCodePointArray(word0); final int[] codePoints1 = StringUtils.toCodePointArray(word1); removeBigramWordsNative(mNativeDict, codePoints0, codePoints1); + mHasUpdated = true; } public void addMultipleDictionaryEntries(final LanguageModelParam[] languageModelParams) { @@ -422,6 +440,7 @@ public final class BinaryDictionary extends Dictionary { } processedParamCount = addMultipleDictionaryEntriesNative(mNativeDict, languageModelParams, processedParamCount); + mHasUpdated = true; if (processedParamCount <= 0) { return; } @@ -440,8 +459,10 @@ public final class BinaryDictionary extends Dictionary { public void flush() { if (!isValidDictionary()) return; - flushNative(mNativeDict, mDictFilePath); - reopen(); + if (mHasUpdated) { + flushNative(mNativeDict, mDictFilePath); + reopen(); + } } public void flushWithGC() { diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java index 4e17f8389..d5873d70f 100644 --- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java @@ -100,10 +100,6 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { }); } - public void reopen(final Context context) { - registerObserver(context); - } - @Override public synchronized void close() { if (mObserver != null) { diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java index e04524843..0742fbde9 100644 --- a/java/src/com/android/inputmethod/latin/Dictionary.java +++ b/java/src/com/android/inputmethod/latin/Dictionary.java @@ -27,6 +27,7 @@ import java.util.ArrayList; */ public abstract class Dictionary { public static final int NOT_A_PROBABILITY = -1; + public static final float NOT_A_LANGUAGE_WEIGHT = -1.0f; // The following types do not actually come from real dictionary instances, so we create // corresponding instances. @@ -70,22 +71,26 @@ public abstract class Dictionary { * @param proximityInfo the object for key proximity. May be ignored by some implementations. * @param blockOffensiveWords whether to block potentially offensive words * @param additionalFeaturesOptions options about additional features used for the suggestion. + * @param inOutLanguageWeight the language weight used for generating suggestions. + * inOutLanguageWeight is a float array that has only one element. This can be updated when the + * different language weight is used. * @return the list of suggestions (possibly null if none) */ // TODO: pass more context than just the previous word, to enable better suggestions (n-gram // and more) abstract public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, - final boolean blockOffensiveWords, final int[] additionalFeaturesOptions); + final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, + final float[] inOutLanguageWeight); // The default implementation of this method ignores sessionId. // Subclasses that want to use sessionId need to override this method. public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final int sessionId) { + final int sessionId, final float[] inOutLanguageWeight) { return getSuggestions(composer, prevWord, proximityInfo, blockOffensiveWords, - additionalFeaturesOptions); + additionalFeaturesOptions, inOutLanguageWeight); } /** @@ -159,7 +164,8 @@ public abstract class Dictionary { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, - final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) { + final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, + final float[] inOutLanguageWeight) { return null; } diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java index bf075140e..16173fffc 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java +++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java @@ -58,18 +58,21 @@ public final class DictionaryCollection extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, - final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) { + final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, + final float[] inOutLanguageWeight) { final CopyOnWriteArrayList<Dictionary> dictionaries = mDictionaries; if (dictionaries.isEmpty()) return null; // To avoid creating unnecessary objects, we get the list out of the first // dictionary and add the rest to it if not null, hence the get(0) ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getSuggestions(composer, - prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions); + prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, + inOutLanguageWeight); if (null == suggestions) suggestions = CollectionUtils.newArrayList(); final int length = dictionaries.size(); for (int i = 1; i < length; ++ i) { final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getSuggestions(composer, - prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions); + prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, + inOutLanguageWeight); if (null != sugg) suggestions.addAll(sugg); } return suggestions; diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java index ae2d7c9c6..7cb218fbe 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java @@ -36,7 +36,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; import java.util.Map; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -54,6 +53,15 @@ public class DictionaryFacilitatorForSuggest { // To synchronize assigning mDictionaries to ensure closing dictionaries. private Object mLock = new Object(); + private static final String[] dictTypesOrderedToGetSuggestion = + new String[] { + Dictionary.TYPE_MAIN, + Dictionary.TYPE_USER_HISTORY, + Dictionary.TYPE_PERSONALIZATION, + Dictionary.TYPE_USER, + Dictionary.TYPE_CONTACTS + }; + /** * Class contains dictionaries for a locale. */ @@ -453,11 +461,14 @@ public class DictionaryFacilitatorForSuggest { final Map<String, Dictionary> dictMap = dictionaries.mDictMap; final SuggestionResults suggestionResults = new SuggestionResults(dictionaries.mLocale, SuggestedWords.MAX_SUGGESTIONS); - for (final Dictionary dictionary : dictMap.values()) { + final float[] languageWeight = new float[] { Dictionary.NOT_A_LANGUAGE_WEIGHT }; + for (final String dictType : dictTypesOrderedToGetSuggestion) { + final Dictionary dictionary = dictMap.get(dictType); if (null == dictionary) continue; final ArrayList<SuggestedWordInfo> dictionarySuggestions = dictionary.getSuggestionsWithSessionId(composer, prevWord, proximityInfo, - blockOffensiveWords, additionalFeaturesOptions, sessionId); + blockOffensiveWords, additionalFeaturesOptions, sessionId, + languageWeight); if (null == dictionarySuggestions) continue; suggestionResults.addAll(dictionarySuggestions); if (null != rawSuggestions) { diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index 92b535458..64e9d2b51 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -262,6 +262,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { ExecutorUtils.getExecutor(mDictName).execute(new Runnable() { @Override public void run() { + if (mBinaryDictionary == null) { + return; + } runGCAfterAllPrioritizedTasksIfRequiredLocked(mindsBlockByGC); } }); @@ -274,9 +277,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } private void runGCAfterAllPrioritizedTasksIfRequiredLocked(final boolean mindsBlockByGC) { - if (mBinaryDictionary == null) { - return; - } // needsToRunGC() have to be called with lock. if (mBinaryDictionary.needsToRunGC(mindsBlockByGC)) { if (setProcessingLargeTaskIfNot()) { @@ -301,9 +301,13 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { protected void addWordDynamically(final String word, final int frequency, final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord, final boolean isBlacklisted, final int timestamp) { + reloadDictionaryIfRequired(); ExecutorUtils.getExecutor(mDictName).execute(new Runnable() { @Override public void run() { + if (mBinaryDictionary == null) { + return; + } runGCAfterAllPrioritizedTasksIfRequiredLocked(true /* mindsBlockByGC */); addWordDynamicallyLocked(word, frequency, shortcutTarget, shortcutFreq, isNotAWord, isBlacklisted, timestamp); @@ -323,9 +327,13 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { */ protected void addBigramDynamically(final String word0, final String word1, final int frequency, final int timestamp) { + reloadDictionaryIfRequired(); ExecutorUtils.getExecutor(mDictName).execute(new Runnable() { @Override public void run() { + if (mBinaryDictionary == null) { + return; + } runGCAfterAllPrioritizedTasksIfRequiredLocked(true /* mindsBlockByGC */); addBigramDynamicallyLocked(word0, word1, frequency, timestamp); } @@ -341,9 +349,13 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { * Dynamically remove a word bigram in the dictionary. */ protected void removeBigramDynamically(final String word0, final String word1) { + reloadDictionaryIfRequired(); ExecutorUtils.getExecutor(mDictName).execute(new Runnable() { @Override public void run() { + if (mBinaryDictionary == null) { + return; + } runGCAfterAllPrioritizedTasksIfRequiredLocked(true /* mindsBlockByGC */); mBinaryDictionary.removeBigramWords(word0, word1); } @@ -360,14 +372,15 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { protected void addMultipleDictionaryEntriesDynamically( final ArrayList<LanguageModelParam> languageModelParams, final AddMultipleDictionaryEntriesCallback callback) { + reloadDictionaryIfRequired(); ExecutorUtils.getExecutor(mDictName).execute(new Runnable() { @Override public void run() { + if (mBinaryDictionary == null) { + return; + } final boolean locked = setProcessingLargeTaskIfNot(); try { - if (mBinaryDictionary == null) { - return; - } mBinaryDictionary.addMultipleDictionaryEntries( languageModelParams.toArray( new LanguageModelParam[languageModelParams.size()])); @@ -387,7 +400,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final int sessionId) { + final int sessionId, final float[] inOutLanguageWeight) { reloadDictionaryIfRequired(); if (processingLargeTask()) { return null; @@ -404,7 +417,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { final ArrayList<SuggestedWordInfo> binarySuggestion = mBinaryDictionary.getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, - sessionId); + sessionId, inOutLanguageWeight); holder.set(binarySuggestion); if (mBinaryDictionary.isCorrupted()) { removeBinaryDictionaryLocked(); @@ -417,9 +430,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, - final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) { + final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, + final float[] inOutLanguageWeight) { return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords, - additionalFeaturesOptions, 0 /* sessionId */); + additionalFeaturesOptions, 0 /* sessionId */, inOutLanguageWeight); } @Override diff --git a/java/src/com/android/inputmethod/latin/ImportantNoticeDialog.java b/java/src/com/android/inputmethod/latin/ImportantNoticeDialog.java index 9870faa98..be54b669b 100644 --- a/java/src/com/android/inputmethod/latin/ImportantNoticeDialog.java +++ b/java/src/com/android/inputmethod/latin/ImportantNoticeDialog.java @@ -23,6 +23,7 @@ import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnDismissListener; import android.content.DialogInterface.OnShowListener; +import com.android.inputmethod.latin.utils.DialogUtils; import com.android.inputmethod.latin.utils.ImportantNoticeUtils; /** @@ -40,7 +41,7 @@ public final class ImportantNoticeDialog extends AlertDialog implements OnShowLi public ImportantNoticeDialog( final Context context, final ImportantNoticeDialogListener listener) { - super(context, THEME_HOLO_DARK); + super(DialogUtils.getPlatformDialogThemeContext(context)); mListener = listener; mNextImportantNoticeVersion = ImportantNoticeUtils.getNextImportantNoticeVersion(context); setMessage(ImportantNoticeUtils.getNextImportantNoticeContents(context)); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 53e6232b6..ca99998e0 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -83,6 +83,7 @@ import com.android.inputmethod.latin.suggestions.SuggestionStripViewAccessor; import com.android.inputmethod.latin.utils.ApplicationUtils; import com.android.inputmethod.latin.utils.CapsModeUtils; import com.android.inputmethod.latin.utils.CoordinateUtils; +import com.android.inputmethod.latin.utils.DialogUtils; import com.android.inputmethod.latin.utils.ImportantNoticeUtils; import com.android.inputmethod.latin.utils.IntentUtils; import com.android.inputmethod.latin.utils.JniUtils; @@ -156,7 +157,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private static final int MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP = 3; private static final int MSG_RESUME_SUGGESTIONS = 4; private static final int MSG_REOPEN_DICTIONARIES = 5; - private static final int MSG_ON_END_BATCH_INPUT = 6; + private static final int MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED = 6; private static final int MSG_RESET_CACHES = 7; // Update this when adding new messages private static final int MSG_LAST = MSG_RESET_CACHES; @@ -197,7 +198,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen latinIme.mSettings.getCurrent()); break; case MSG_UPDATE_SHIFT_STATE: - switcher.updateShiftState(); + switcher.requestUpdatingShiftState(); break; case MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP: if (msg.arg1 == ARG1_NOT_GESTURE_INPUT) { @@ -220,8 +221,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // get any suggestions. Wait one frame. postUpdateSuggestionStrip(); break; - case MSG_ON_END_BATCH_INPUT: - latinIme.mInputLogic.endBatchInputInternal(latinIme.mSettings.getCurrent(), + case MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED: + latinIme.mInputLogic.onUpdateTailBatchInputCompleted( + latinIme.mSettings.getCurrent(), (SuggestedWords) msg.obj, latinIme.mKeyboardSwitcher); break; case MSG_RESET_CACHES: @@ -304,8 +306,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen ARG1_NOT_GESTURE_INPUT, ARG2_UNUSED, suggestedWords).sendToTarget(); } - public void onEndBatchInput(final SuggestedWords suggestedWords) { - obtainMessage(MSG_ON_END_BATCH_INPUT, suggestedWords).sendToTarget(); + public void showTailBatchInputResult(final SuggestedWords suggestedWords) { + obtainMessage(MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED, suggestedWords).sendToTarget(); } // Working variables for the following methods. @@ -832,7 +834,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // we need to re-evaluate the shift state, but not the whole layout which would be // disruptive. // Space state must be updated before calling updateShiftState - switcher.updateShiftState(); + switcher.requestUpdatingShiftState(); } // This will set the punctuation suggestions if next word suggestion is off; // otherwise it will clear the suggestion strip. @@ -911,7 +913,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // TODO: find a better way to simulate actual execution. if (isInputViewShown() && mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd)) { - mKeyboardSwitcher.updateShiftState(); + mKeyboardSwitcher.requestUpdatingShiftState(); } mSubtypeState.currentSubtypeUsed(); @@ -1230,7 +1232,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mInputLogic.onCodeInput(mSettings.getCurrent(), event, mKeyboardSwitcher.getKeyboardShiftMode(), mHandler); updateStateAfterInputTransaction(completeInputTransaction); - mKeyboardSwitcher.onCodeInput(codePoint); + mKeyboardSwitcher.onCodeInput(codePoint, getCurrentAutoCapsState()); } // A helper method to split the code point and the key code. Ultimately, they should not be @@ -1255,8 +1257,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // TODO: have the keyboard pass the correct key code when we need it. final Event event = Event.createSoftwareTextEvent(rawText, Event.NOT_A_KEY_CODE); mInputLogic.onTextInput(mSettings.getCurrent(), event, mHandler); - mKeyboardSwitcher.updateShiftState(); - mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT); + mKeyboardSwitcher.requestUpdatingShiftState(); + mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT, getCurrentAutoCapsState()); } @Override @@ -1499,7 +1501,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mHandler.postUpdateShiftState(); break; case InputTransaction.SHIFT_UPDATE_NOW: - mKeyboardSwitcher.updateShiftState(); + mKeyboardSwitcher.requestUpdatingShiftState(); break; default: // SHIFT_NO_UPDATE } @@ -1539,7 +1541,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void onPressKey(final int primaryCode, final int repeatCount, final boolean isSinglePointer) { - mKeyboardSwitcher.onPressKey(primaryCode, isSinglePointer); + mKeyboardSwitcher.onPressKey(primaryCode, isSinglePointer, getCurrentAutoCapsState()); hapticAndAudioFeedback(primaryCode, repeatCount); } @@ -1661,8 +1663,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } }; - final AlertDialog.Builder builder = - new AlertDialog.Builder(this).setItems(items, listener).setTitle(title); + final AlertDialog.Builder builder = new AlertDialog.Builder( + DialogUtils.getPlatformDialogThemeContext(this)); + builder.setItems(items, listener).setTitle(title); showOptionDialog(builder.create()); } diff --git a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java index 68505ce38..9f61d6c37 100644 --- a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java @@ -51,20 +51,21 @@ public final class ReadOnlyBinaryDictionary extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, - final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) { + final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, + final float[] inOutLanguageWeight) { return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords, - additionalFeaturesOptions, 0 /* sessionId */); + additionalFeaturesOptions, 0 /* sessionId */, inOutLanguageWeight); } @Override public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final int sessionId) { + final int sessionId, final float[] inOutLanguageWeight) { if (mLock.readLock().tryLock()) { try { return mBinaryDictionary.getSuggestions(composer, prevWord, proximityInfo, - blockOffensiveWords, additionalFeaturesOptions); + blockOffensiveWords, additionalFeaturesOptions, inOutLanguageWeight); } finally { mLock.readLock().unlock(); } diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index d4301229c..021133945 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -34,7 +34,7 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils; import com.android.inputmethod.keyboard.KeyboardSwitcher; -import com.android.inputmethod.keyboard.internal.NeedsToDisplayLanguage; +import com.android.inputmethod.keyboard.internal.LanguageOnSpacebarHelper; import com.android.inputmethod.latin.utils.LocaleUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; @@ -54,7 +54,8 @@ public final class SubtypeSwitcher { private /* final */ Resources mResources; private /* final */ ConnectivityManager mConnectivityManager; - private final NeedsToDisplayLanguage mNeedsToDisplayLanguage = new NeedsToDisplayLanguage(); + private final LanguageOnSpacebarHelper mLanguageOnSpacebarHelper = + new LanguageOnSpacebarHelper(); private InputMethodInfo mShortcutInputMethodInfo; private InputMethodSubtype mShortcutSubtype; private InputMethodSubtype mNoLanguageSubtype; @@ -127,7 +128,7 @@ public final class SubtypeSwitcher { public void updateParametersOnStartInputView() { final List<InputMethodSubtype> enabledSubtypesOfThisIme = mRichImm.getMyEnabledInputMethodSubtypeList(true); - mNeedsToDisplayLanguage.updateEnabledSubtypeCount(enabledSubtypesOfThisIme.size()); + mLanguageOnSpacebarHelper.updateEnabledSubtypes(enabledSubtypesOfThisIme); updateShortcutIME(); } @@ -176,7 +177,7 @@ public final class SubtypeSwitcher { final boolean sameLanguage = systemLocale.getLanguage().equals(newLocale.getLanguage()); final boolean implicitlyEnabled = mRichImm.checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled(newSubtype); - mNeedsToDisplayLanguage.updateIsSystemLanguageSameAsInputLanguage( + mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage( sameLocale || (sameLanguage && implicitlyEnabled)); updateShortcutIME(); @@ -249,8 +250,8 @@ public final class SubtypeSwitcher { // Subtype Switching functions // ////////////////////////////////// - public boolean needsToDisplayLanguage(final InputMethodSubtype subtype) { - return mNeedsToDisplayLanguage.needsToDisplayLanguage(subtype); + public int getLanguageOnSpacebarFormatType(final InputMethodSubtype subtype) { + return mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(subtype); } public boolean isSystemLocaleSameAsLocaleOfAllEnabledSubtypesOfEnabledImes() { diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java index 9c095e4b1..c24ee4033 100644 --- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java @@ -34,10 +34,11 @@ public final class SynchronouslyLoadedContactsBinaryDictionary extends ContactsB @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes, final String prevWordForBigrams, final ProximityInfo proximityInfo, - final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) { + final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, + final float[] inOutLanguageWeight) { synchronized (mLock) { return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, - blockOffensiveWords, additionalFeaturesOptions); + blockOffensiveWords, additionalFeaturesOptions, inOutLanguageWeight); } } diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java index 801fb5b89..1d29d7ad0 100644 --- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java @@ -39,10 +39,11 @@ public final class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDic @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes, final String prevWordForBigrams, final ProximityInfo proximityInfo, - final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) { + final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, + final float[] inOutLanguageWeight) { synchronized (mLock) { return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, - blockOffensiveWords, additionalFeaturesOptions); + blockOffensiveWords, additionalFeaturesOptions, inOutLanguageWeight); } } diff --git a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java index 800f56597..139e73aa4 100644 --- a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java +++ b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java @@ -28,6 +28,7 @@ import com.android.inputmethod.latin.BinaryDictionaryGetter; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.makedict.DictionaryHeader; import com.android.inputmethod.latin.utils.CollectionUtils; +import com.android.inputmethod.latin.utils.DialogUtils; import com.android.inputmethod.latin.utils.DictionaryInfoUtils; import com.android.inputmethod.latin.utils.LocaleUtils; @@ -70,7 +71,7 @@ public class ExternalDictionaryGetterForDebug { } private static void showNoFileDialog(final Context context) { - new AlertDialog.Builder(context) + new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context)) .setMessage(R.string.read_external_dictionary_no_files_message) .setPositiveButton(android.R.string.ok, new OnClickListener() { @Override @@ -81,8 +82,8 @@ public class ExternalDictionaryGetterForDebug { } private static void showChooseFileDialog(final Context context, final String[] fileNames) { - final AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.read_external_dictionary_multiple_files_title) + 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) { @@ -111,7 +112,7 @@ public class ExternalDictionaryGetterForDebug { final String title = String.format( context.getString(R.string.read_external_dictionary_confirm_install_message), languageName); - new AlertDialog.Builder(context) + new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context)) .setTitle(title) .setMessage(message) .setNegativeButton(android.R.string.cancel, new OnClickListener() { @@ -167,7 +168,7 @@ public class ExternalDictionaryGetterForDebug { } } catch (IOException e) { // There was an error: show a dialog - new AlertDialog.Builder(context) + new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context)) .setTitle(R.string.error) .setMessage(e.toString()) .setPositiveButton(android.R.string.ok, new OnClickListener() { diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index ec6bd289a..7ffc95697 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -210,22 +210,12 @@ public final class InputLogic { // So, LatinImeLogger logs "" as a user's input. LatinImeLogger.logOnManualSuggestion("", suggestion, index, suggestedWords); // Rely on onCodeInput to do the complicated swapping/stripping logic consistently. - final int primaryCode = suggestion.charAt(0); - // TODO: we should be using createSuggestionPickedEvent here, but for legacy reasons, - // onCodeInput is expected a software keypress event for a suggested punctuation - // because the current code is descended from a time where this information used not - // to be available. Fix this. - final Event event = Event.createSoftwareKeypressEvent(primaryCode, - Event.NOT_A_KEY_CODE /* keyCode*/, - Constants.SUGGESTION_STRIP_COORDINATE /* x */, - Constants.SUGGESTION_STRIP_COORDINATE /* y */); - final InputTransaction completeTransaction = onCodeInput(settingsValues, event, - keyboardShiftState, handler); + final Event event = Event.createPunctuationSuggestionPickedEvent(suggestionInfo); if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { ResearchLogger.latinIME_punctuationSuggestion(index, suggestion, false /* isBatchMode */, suggestedWords.mIsPrediction); } - return completeTransaction; + return onCodeInput(settingsValues, event, keyboardShiftState, handler); } final Event event = Event.createSuggestionPickedEvent(suggestionInfo); @@ -547,7 +537,7 @@ public final class InputLogic { // after typing some letters and a period, then gesturing; the keyboard is not in // caps mode yet, but since a gesture is starting, it should go in caps mode, // unless the user explictly said it should not. - keyboardSwitcher.updateShiftState(); + keyboardSwitcher.requestUpdatingShiftState(); } } mConnection.endBatchEdit(); @@ -589,7 +579,7 @@ public final class InputLogic { promotePhantomSpace(settingsValues); mConnection.commitText(commitParts[0], 0); mSpaceState = SpaceState.PHANTOM; - keyboardSwitcher.updateShiftState(); + keyboardSwitcher.requestUpdatingShiftState(); mWordComposer.setCapitalizedModeAndPreviousWordAtStartComposingTime( getActualCapsMode(settingsValues, keyboardSwitcher.getKeyboardShiftMode()), commitParts[0]); @@ -601,7 +591,7 @@ public final class InputLogic { } public void onEndBatchInput(final InputPointers batchPointers) { - mInputLogicHandler.onEndBatchInput(batchPointers, mAutoCommitSequenceNumber); + mInputLogicHandler.updateTailBatchInput(batchPointers, mAutoCommitSequenceNumber); ++mAutoCommitSequenceNumber; } @@ -833,13 +823,11 @@ public final class InputLogic { } if (Constants.CODE_SPACE == codePoint) { - if (inputTransaction.mSettingsValues.isSuggestionsRequested()) { - if (maybeDoubleSpacePeriod(inputTransaction)) { - inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); - mSpaceState = SpaceState.DOUBLE; - } else if (!mSuggestedWords.isPunctuationSuggestions()) { - mSpaceState = SpaceState.WEAK; - } + if (maybeDoubleSpacePeriod(inputTransaction)) { + inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); + mSpaceState = SpaceState.DOUBLE; + } else if (!mSuggestedWords.isPunctuationSuggestions()) { + mSpaceState = SpaceState.WEAK; } startDoubleSpacePeriodCountdown(inputTransaction); @@ -1794,7 +1782,7 @@ public final class InputLogic { * @param settingsValues the current values of the settings. * @param suggestedWords suggestedWords to use. */ - public void endBatchInputInternal(final SettingsValues settingsValues, + public void onUpdateTailBatchInputCompleted(final SettingsValues settingsValues, final SuggestedWords suggestedWords, // TODO: remove this argument final KeyboardSwitcher keyboardSwitcher) { @@ -1831,7 +1819,7 @@ public final class InputLogic { } // Space state must be updated before calling updateShiftState mSpaceState = SpaceState.PHANTOM; - keyboardSwitcher.updateShiftState(); + keyboardSwitcher.requestUpdatingShiftState(); } /** diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java index 42f0d7c00..e3b8ab465 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java @@ -54,7 +54,8 @@ class InputLogicHandler implements Handler.Callback { @Override public void onCancelBatchInput() {} @Override - public void onEndBatchInput(final InputPointers batchPointers, final int sequenceNumber) {} + public void updateTailBatchInput(final InputPointers batchPointers, + final int sequenceNumber) {} @Override public void getSuggestedWords(final int sessionId, final int sequenceNumber, final OnGetSuggestedWordsCallback callback) {} @@ -106,7 +107,7 @@ class InputLogicHandler implements Handler.Callback { * Fetch suggestions corresponding to an update of a batch input. * @param batchPointers the updated pointers, including the part that was passed last time. * @param sequenceNumber the sequence number associated with this batch input. - * @param forEnd true if this is the end of a batch input, false if it's an update. + * @param isTailBatchInput true if this is the end of a batch input, false if it's an update. */ // This method can be called from any thread and will see to it that the correct threads // are used for parts that require it. This method will send a message to the Non-UI handler @@ -115,7 +116,7 @@ class InputLogicHandler implements Handler.Callback { // send a message to the UI handler in LatinIME so that showing suggestions can be done on // the UI thread. private void updateBatchInput(final InputPointers batchPointers, - final int sequenceNumber, final boolean forEnd) { + final int sequenceNumber, final boolean isTailBatchInput) { synchronized (mLock) { if (!mInBatchInput) { // Batch input has ended or canceled while the message was being delivered. @@ -136,12 +137,12 @@ class InputLogicHandler implements Handler.Callback { suggestedWords = mInputLogic.mSuggestedWords; } mLatinIME.mHandler.showGesturePreviewAndSuggestionStrip(suggestedWords, - forEnd /* dismissGestureFloatingPreviewText */); - if (forEnd) { + isTailBatchInput /* dismissGestureFloatingPreviewText */); + if (isTailBatchInput) { mInBatchInput = false; // The following call schedules onEndBatchInputInternal // to be called on the UI thread. - mLatinIME.mHandler.onEndBatchInput(suggestedWords); + mLatinIME.mHandler.showTailBatchInputResult(suggestedWords); } } }); @@ -159,13 +160,13 @@ class InputLogicHandler implements Handler.Callback { // Called on the UI thread by InputLogic. public void onUpdateBatchInput(final InputPointers batchPointers, final int sequenceNumber) { - updateBatchInput(batchPointers, sequenceNumber, false /* forEnd */); + updateBatchInput(batchPointers, sequenceNumber, false /* isTailBatchInput */); } /** * Cancel a batch input. * - * Note that as opposed to onEndBatchInput, we do the UI side of this immediately on the + * Note that as opposed to updateTailBatchInput, we do the UI side of this immediately on the * same thread, rather than get this to call a method in LatinIME. This is because * canceling a batch input does not necessitate the long operation of pulling suggestions. */ @@ -177,17 +178,20 @@ class InputLogicHandler implements Handler.Callback { } /** - * Finish a batch input. + * Trigger an update for a tail batch input. * - * This fetches suggestions, updates the suggestion strip and commits the first suggestion. - * It also dismisses the floating text preview. + * A tail batch input is the last update for a gesture, the one that is triggered after the + * user lifts their finger. This method schedules fetching suggestions on the non-UI thread, + * then when the suggestions are computed it comes back on the UI thread to update the + * suggestion strip, commit the first suggestion, and dismiss the floating text preview. * * @param batchPointers the updated batch pointers. * @param sequenceNumber the sequence number associated with this batch input. */ // Called on the UI thread by InputLogic. - public void onEndBatchInput(final InputPointers batchPointers, final int sequenceNumber) { - updateBatchInput(batchPointers, sequenceNumber, true /* forEnd */); + public void updateTailBatchInput(final InputPointers batchPointers, + final int sequenceNumber) { + updateBatchInput(batchPointers, sequenceNumber, true /* isTailBatchInput */); } public void getSuggestedWords(final int sessionId, final int sequenceNumber, diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java index 6f84e1f10..712e314a8 100644 --- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java +++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java @@ -66,7 +66,7 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB } // Flush pending writes. flush(); - // TODO: Quit depending on finalize() and really close the dictionary file. + super.close(); } public void flush() { diff --git a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java index 6dae6206c..39977e76f 100644 --- a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java +++ b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java @@ -48,6 +48,7 @@ import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.RichInputMethodManager; import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; import com.android.inputmethod.latin.utils.CollectionUtils; +import com.android.inputmethod.latin.utils.DialogUtils; import com.android.inputmethod.latin.utils.IntentUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; @@ -517,7 +518,8 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { private AlertDialog createDialog( @SuppressWarnings("unused") final SubtypePreference subtypePref) { - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + final AlertDialog.Builder builder = new AlertDialog.Builder( + DialogUtils.getPlatformDialogThemeContext(getActivity())); builder.setTitle(R.string.custom_input_styles_title) .setMessage(R.string.custom_input_style_note_message) .setNegativeButton(R.string.not_now, null) diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java index 3947019ca..69d092751 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java @@ -327,7 +327,8 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { final ArrayList<SuggestedWordInfo> suggestions = dictInfo.mDictionary.getSuggestions(composer, prevWord, dictInfo.getProximityInfo(), true /* blockOffensiveWords */, - null /* additionalFeaturesOptions */); + null /* additionalFeaturesOptions */, + null /* inOutLanguageWeight */); if (suggestions != null) { for (final SuggestedWordInfo suggestion : suggestions) { final String suggestionStr = suggestion.mWord; diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java index b7a5a4026..c99264347 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java @@ -53,7 +53,8 @@ public final class DictionaryPool extends LinkedBlockingQueue<DictAndKeyboard> { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, - final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) { + final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, + final float[] inOutLanguageWeight) { return noSuggestions; } @Override diff --git a/java/src/com/android/inputmethod/latin/utils/DialogUtils.java b/java/src/com/android/inputmethod/latin/utils/DialogUtils.java new file mode 100644 index 000000000..a05c932d0 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/utils/DialogUtils.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.utils; + +import android.content.Context; +import android.view.ContextThemeWrapper; + +import com.android.inputmethod.latin.R; + +public final class DialogUtils { + private DialogUtils() { + // This utility class is not publicly instantiable. + } + + public static Context getPlatformDialogThemeContext(final Context context) { + // Because {@link AlertDialog.Builder.create()} doesn't honor the specified theme with + // createThemeContextWrapper=false, the result dialog box has unneeded paddings around it. + return new ContextThemeWrapper(context, R.style.platformDialogTheme); + } +} |