diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
4 files changed, 116 insertions, 23 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index f27d32150..518bcd5ce 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1268,13 +1268,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (SPACE_STATE_PHANTOM == spaceState) { commitTyped(LastComposedWord.NOT_A_SEPARATOR); } + final int keyX, keyY; final Keyboard keyboard = mKeyboardSwitcher.getKeyboard(); if (keyboard != null && keyboard.hasProximityCharsCorrection(primaryCode)) { - handleCharacter(primaryCode, x, y, spaceState); + keyX = x; + keyY = y; } else { - handleCharacter(primaryCode, NOT_A_TOUCH_COORDINATE, NOT_A_TOUCH_COORDINATE, - spaceState); + keyX = NOT_A_TOUCH_COORDINATE; + keyY = NOT_A_TOUCH_COORDINATE; } + handleCharacter(primaryCode, keyX, keyY, spaceState); } mExpectingUpdateSelection = true; mShouldSwitchToLastSubtype = true; @@ -1320,10 +1323,20 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mSpaceState = SPACE_STATE_PHANTOM; } mConnection.endBatchEdit(); + // TODO: Should handle TextUtils.CAP_MODE_CHARACTER. + mWordComposer.setAutoCapitalized( + getCurrentAutoCapsState() != Constants.TextUtils.CAP_MODE_OFF); + } + + @Override + public SuggestedWords onUpdateBatchInput(InputPointers batchPointers) { + mWordComposer.setBatchInputPointers(batchPointers); + return updateSuggestionsOrPredictions(); } @Override public void onEndBatchInput(CharSequence text) { + mWordComposer.setBatchInputWord(text); mConnection.beginBatchEdit(); if (SPACE_STATE_PHANTOM == mSpaceState) { sendKeyCodePoint(Keyboard.CODE_SPACE); @@ -1669,7 +1682,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } // TODO: rename this method to updateSuggestionStrip or simply updateSuggestions - private void updateSuggestionsOrPredictions() { + private SuggestedWords updateSuggestionsOrPredictions() { mHandler.cancelUpdateSuggestionStrip(); // Check if we have a suggestion engine attached. @@ -1679,13 +1692,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen + "requested!"); mWordComposer.setAutoCorrection(mWordComposer.getTypedWord()); } - return; + return null; } final String typedWord = mWordComposer.getTypedWord(); if (!mWordComposer.isComposingWord() && !mCurrentSettings.mBigramPredictionEnabled) { setPunctuationSuggestions(); - return; + return null; } // Get the word on which we should search the bigrams. If we are composing a word, it's @@ -1701,6 +1714,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen suggestedWords = maybeRetrieveOlderSuggestions(typedWord, suggestedWords); showSuggestions(suggestedWords, typedWord); + return suggestedWords; } private SuggestedWords maybeRetrieveOlderSuggestions(final CharSequence typedWord, @@ -1761,9 +1775,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (mHandler.hasPendingUpdateSuggestions()) { updateSuggestionsOrPredictions(); } - final CharSequence autoCorrection = mWordComposer.getAutoCorrectionOrNull(); + final CharSequence typedAutoCorrection = mWordComposer.getAutoCorrectionOrNull(); + final String typedWord = mWordComposer.getTypedWord(); + final CharSequence autoCorrection = (typedAutoCorrection != null) + ? typedAutoCorrection : typedWord; if (autoCorrection != null) { - final String typedWord = mWordComposer.getTypedWord(); if (TextUtils.isEmpty(typedWord)) { throw new RuntimeException("We have an auto-correction but the typed word " + "is empty? Impossible! I must commit suicide."); @@ -1808,7 +1824,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } mConnection.beginBatchEdit(); - if (SPACE_STATE_PHANTOM == mSpaceState && suggestion.length() > 0) { + if (SPACE_STATE_PHANTOM == mSpaceState && suggestion.length() > 0 + // In the batch input mode, a manually picked suggested word should just replace + // the current batch input text and there is no need for a phantom space. + && !mWordComposer.isBatchMode()) { int firstChar = Character.codePointAt(suggestion, 0); if ((!mCurrentSettings.isWeakSpaceStripper(firstChar)) && (!mCurrentSettings.isWeakSpaceSwapper(firstChar))) { diff --git a/java/src/com/android/inputmethod/latin/ResearchLogger.java b/java/src/com/android/inputmethod/latin/ResearchLogger.java index 9055d5d32..1abfbad13 100644 --- a/java/src/com/android/inputmethod/latin/ResearchLogger.java +++ b/java/src/com/android/inputmethod/latin/ResearchLogger.java @@ -19,12 +19,16 @@ package com.android.inputmethod.latin; import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET; import android.app.AlertDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager.NameNotFoundException; import android.inputmethodservice.InputMethodService; import android.os.Build; import android.text.TextUtils; +import android.text.format.DateUtils; import android.util.Log; import android.view.MotionEvent; import android.view.inputmethod.CompletionInfo; @@ -40,6 +44,7 @@ import com.android.inputmethod.latin.RichInputConnection.Range; import com.android.inputmethod.latin.define.ProductionFlag; import java.io.File; +import java.io.FileFilter; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -93,6 +98,9 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang Character.codePointAt("\uE000", 0); // U+E000 is in the "private-use area" // U+E001 is in the "private-use area" /* package for test */ static final String WORD_REPLACEMENT_STRING = "\uE001"; + private static final String PREF_LAST_CLEANUP_TIME = "pref_last_cleanup_time"; + private static final long DURATION_BETWEEN_DIR_CLEANUP_IN_MS = DateUtils.DAY_IN_MILLIS; + private static final long MAX_LOGFILE_AGE_IN_MS = DateUtils.DAY_IN_MILLIS; // set when LatinIME should ignore an onUpdateSelection() callback that // arises from operations in this class private static boolean sLatinIMEExpectingUpdateSelection = false; @@ -101,6 +109,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang private Suggest mSuggest; private Dictionary mDictionary; private KeyboardSwitcher mKeyboardSwitcher; + private Context mContext; private ResearchLogger() { } @@ -115,6 +124,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang if (ims == null) { Log.w(TAG, "IMS is null; logging is off"); } else { + mContext = ims; mFilesDir = ims.getFilesDir(); if (mFilesDir == null || !mFilesDir.exists()) { Log.w(TAG, "IME storage directory does not exist."); @@ -124,10 +134,29 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang mUUIDString = getUUID(prefs); sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false); prefs.registerOnSharedPreferenceChangeListener(this); + + final long lastCleanupTime = prefs.getLong(PREF_LAST_CLEANUP_TIME, 0L); + final long now = System.currentTimeMillis(); + if (lastCleanupTime + DURATION_BETWEEN_DIR_CLEANUP_IN_MS < now) { + final long timeHorizon = now - MAX_LOGFILE_AGE_IN_MS; + cleanupLoggingDir(mFilesDir, timeHorizon); + Editor e = prefs.edit(); + e.putLong(PREF_LAST_CLEANUP_TIME, now); + e.apply(); + } } mKeyboardSwitcher = keyboardSwitcher; } + private void cleanupLoggingDir(final File dir, final long time) { + for (File file : dir.listFiles()) { + if (file.getName().startsWith(ResearchLogger.FILENAME_PREFIX) && + file.lastModified() < time) { + file.delete(); + } + } + } + private File createLogFile(File filesDir) { final StringBuilder sb = new StringBuilder(); sb.append(FILENAME_PREFIX).append('-'); @@ -678,18 +707,31 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang private static final String[] EVENTKEYS_LATINIME_ONSTARTINPUTVIEWINTERNAL = { "LatinIMEOnStartInputViewInternal", "uuid", "packageName", "inputType", "imeOptions", - "fieldId", "display", "model", "prefs", "outputFormatVersion" + "fieldId", "display", "model", "prefs", "versionCode", "versionName", "outputFormatVersion" }; public static void latinIME_onStartInputViewInternal(final EditorInfo editorInfo, final SharedPreferences prefs) { + final ResearchLogger researchLogger = getInstance(); + researchLogger.start(); if (editorInfo != null) { - final Object[] values = { - getInstance().mUUIDString, editorInfo.packageName, - Integer.toHexString(editorInfo.inputType), - Integer.toHexString(editorInfo.imeOptions), editorInfo.fieldId, Build.DISPLAY, - Build.MODEL, prefs, OUTPUT_FORMAT_VERSION - }; - getInstance().enqueueEvent(EVENTKEYS_LATINIME_ONSTARTINPUTVIEWINTERNAL, values); + final Context context = researchLogger.mContext; + try { + final PackageInfo packageInfo; + packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), + 0); + final Integer versionCode = packageInfo.versionCode; + final String versionName = packageInfo.versionName; + final Object[] values = { + researchLogger.mUUIDString, editorInfo.packageName, + Integer.toHexString(editorInfo.inputType), + Integer.toHexString(editorInfo.imeOptions), editorInfo.fieldId, + Build.DISPLAY, Build.MODEL, prefs, versionCode, versionName, + OUTPUT_FORMAT_VERSION + }; + researchLogger.enqueueEvent(EVENTKEYS_LATINIME_ONSTARTINPUTVIEWINTERNAL, values); + } catch (NameNotFoundException e) { + e.printStackTrace(); + } } } diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 31566bf13..598ef1de7 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -300,11 +300,27 @@ public class Suggest { final ArrayList<SuggestedWordInfo> suggestionsContainer = new ArrayList<SuggestedWordInfo>(suggestionsSet); + final int suggestionsCount = suggestionsContainer.size(); + final boolean isFirstCharCapitalized = wordComposer.isAutoCapitalized(); + // TODO: Handle the manual temporary shifted mode. + // TODO: Should handle TextUtils.CAP_MODE_CHARACTER. + final boolean isAllUpperCase = false; + if (isFirstCharCapitalized || isAllUpperCase) { + for (int i = 0; i < suggestionsCount; ++i) { + final SuggestedWordInfo wordInfo = suggestionsContainer.get(i); + final SuggestedWordInfo transformedWordInfo = getTransformedSuggestedWordInfo( + wordInfo, mLocale, isAllUpperCase, isFirstCharCapitalized, + 0 /* trailingSingleQuotesCount */); + suggestionsContainer.set(i, transformedWordInfo); + } + } SuggestedWordInfo.removeDups(suggestionsContainer); + // In the batch input mode, the most relevant suggested word should act as a "typed word" + // (typedWordValid=true), not as an "auto correct word" (willAutoCorrect=false). return new SuggestedWords(suggestionsContainer, true /* typedWordValid */, - true /* willAutoCorrect */, + false /* willAutoCorrect */, false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */, false /* isPrediction */); diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index 25e29008e..ca9dbaf05 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -130,8 +130,13 @@ public class WordComposer { if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) { mPrimaryKeyCodes[newIndex] = primaryCode >= Keyboard.CODE_SPACE ? Character.toLowerCase(primaryCode) : primaryCode; - // TODO: Set correct pointer id and time - mInputPointers.addPointer(newIndex, keyX, keyY, 0, 0); + // In the batch input mode, the {@code mInputPointers} holds batch input points and + // shouldn't be overridden by the "typed key" coordinates + // (See {@link #setBatchInputWord}). + if (!mIsBatchMode) { + // TODO: Set correct pointer id and time + mInputPointers.addPointer(newIndex, keyX, keyY, 0, 0); + } } mIsFirstCharCapitalized = isFirstCharCapitalized( newIndex, primaryCode, mIsFirstCharCapitalized); @@ -144,10 +149,21 @@ public class WordComposer { mAutoCorrection = null; } - // TODO: We may want to have appendBatchInputPointers() as well. public void setBatchInputPointers(InputPointers batchPointers) { - mInputPointers.copy(batchPointers); + mInputPointers.set(batchPointers); + mIsBatchMode = true; + } + + public void setBatchInputWord(CharSequence word) { + reset(); mIsBatchMode = true; + final int length = word.length(); + for (int i = 0; i < length; i = Character.offsetByCodePoints(word, i, 1)) { + final int codePoint = Character.codePointAt(word, i); + // We don't want to override the batch input points that are held in mInputPointers + // (See {@link #add(int,int,int)}). + add(codePoint, NOT_A_COORDINATE, NOT_A_COORDINATE); + } } /** @@ -161,7 +177,7 @@ public class WordComposer { add(codePoint, x, y); return; } - add(codePoint, WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); + add(codePoint, NOT_A_COORDINATE, NOT_A_COORDINATE); } /** |