aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
-rw-r--r--java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java10
-rw-r--r--java/src/com/android/inputmethod/latin/AutoCorrection.java24
-rw-r--r--java/src/com/android/inputmethod/latin/EditingUtils.java17
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableDictionary.java13
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java127
-rw-r--r--java/src/com/android/inputmethod/latin/ResearchLogger.java23
-rw-r--r--java/src/com/android/inputmethod/latin/Settings.java96
-rw-r--r--java/src/com/android/inputmethod/latin/SettingsValues.java7
-rw-r--r--java/src/com/android/inputmethod/latin/SubtypeLocale.java12
-rw-r--r--java/src/com/android/inputmethod/latin/SubtypeSwitcher.java75
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java109
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java75
-rw-r--r--java/src/com/android/inputmethod/latin/VibratorUtils.java50
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java3
14 files changed, 247 insertions, 394 deletions
diff --git a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
index 9c5ccc76b..55664d411 100644
--- a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
+++ b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
@@ -21,8 +21,8 @@ import android.media.AudioManager;
import android.view.HapticFeedbackConstants;
import android.view.View;
-import com.android.inputmethod.compat.VibratorCompatWrapper;
import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.latin.VibratorUtils;
/**
* This class gathers audio feedback and haptic feedback functions.
@@ -33,13 +33,13 @@ import com.android.inputmethod.keyboard.Keyboard;
public class AudioAndHapticFeedbackManager {
final private SettingsValues mSettingsValues;
final private AudioManager mAudioManager;
- final private VibratorCompatWrapper mVibrator;
+ final private VibratorUtils mVibratorUtils;
private boolean mSoundOn;
public AudioAndHapticFeedbackManager(final LatinIME latinIme,
final SettingsValues settingsValues) {
mSettingsValues = settingsValues;
- mVibrator = VibratorCompatWrapper.getInstance(latinIme);
+ mVibratorUtils = VibratorUtils.getInstance(latinIme);
mAudioManager = (AudioManager) latinIme.getSystemService(Context.AUDIO_SERVICE);
mSoundOn = reevaluateIfSoundIsOn();
}
@@ -93,8 +93,8 @@ public class AudioAndHapticFeedbackManager {
HapticFeedbackConstants.KEYBOARD_TAP,
HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
}
- } else if (mVibrator != null) {
- mVibrator.vibrate(mSettingsValues.mKeypressVibrationDuration);
+ } else if (mVibratorUtils != null) {
+ mVibratorUtils.vibrate(mSettingsValues.mKeypressVibrationDuration);
}
}
diff --git a/java/src/com/android/inputmethod/latin/AutoCorrection.java b/java/src/com/android/inputmethod/latin/AutoCorrection.java
index ef88f9906..38444a10c 100644
--- a/java/src/com/android/inputmethod/latin/AutoCorrection.java
+++ b/java/src/com/android/inputmethod/latin/AutoCorrection.java
@@ -16,6 +16,8 @@
package com.android.inputmethod.latin;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+
import android.text.TextUtils;
import android.util.Log;
@@ -30,8 +32,9 @@ public class AutoCorrection {
// Purely static class: can't instantiate.
}
- public static CharSequence computeAutoCorrectionWord(HashMap<String, Dictionary> dictionaries,
- WordComposer wordComposer, ArrayList<CharSequence> suggestions, int[] sortedScores,
+ public static CharSequence computeAutoCorrectionWord(
+ HashMap<String, Dictionary> dictionaries,
+ WordComposer wordComposer, ArrayList<SuggestedWordInfo> suggestions,
CharSequence consideredWord, double autoCorrectionThreshold,
CharSequence whitelistedWord) {
if (hasAutoCorrectionForWhitelistedWord(whitelistedWord)) {
@@ -40,8 +43,8 @@ public class AutoCorrection {
dictionaries, wordComposer, suggestions, consideredWord)) {
return consideredWord;
} else if (hasAutoCorrectionForBinaryDictionary(wordComposer, suggestions,
- sortedScores, consideredWord, autoCorrectionThreshold)) {
- return suggestions.get(0);
+ consideredWord, autoCorrectionThreshold)) {
+ return suggestions.get(0).mWord;
}
return null;
}
@@ -89,22 +92,23 @@ public class AutoCorrection {
private static boolean hasAutoCorrectionForConsideredWord(
HashMap<String, Dictionary> dictionaries, WordComposer wordComposer,
- ArrayList<CharSequence> suggestions, CharSequence consideredWord) {
+ ArrayList<SuggestedWordInfo> suggestions, CharSequence consideredWord) {
if (TextUtils.isEmpty(consideredWord)) return false;
return wordComposer.size() > 1 && suggestions.size() > 0
&& !allowsToBeAutoCorrected(dictionaries, consideredWord, false);
}
private static boolean hasAutoCorrectionForBinaryDictionary(WordComposer wordComposer,
- ArrayList<CharSequence> suggestions, int[] sortedScores,
+ ArrayList<SuggestedWordInfo> suggestions,
CharSequence consideredWord, double autoCorrectionThreshold) {
- if (wordComposer.size() > 1 && suggestions.size() > 0 && sortedScores.length > 0) {
- final CharSequence autoCorrectionSuggestion = suggestions.get(0);
- final int autoCorrectionSuggestionScore = sortedScores[0];
+ if (wordComposer.size() > 1 && suggestions.size() > 0) {
+ final SuggestedWordInfo autoCorrectionSuggestion = suggestions.get(0);
+ //final int autoCorrectionSuggestionScore = sortedScores[0];
+ final int autoCorrectionSuggestionScore = autoCorrectionSuggestion.mScore;
// TODO: when the normalized score of the first suggestion is nearly equals to
// the normalized score of the second suggestion, behave less aggressive.
final double normalizedScore = BinaryDictionary.calcNormalizedScore(
- consideredWord.toString(), autoCorrectionSuggestion.toString(),
+ consideredWord.toString(), autoCorrectionSuggestion.mWord.toString(),
autoCorrectionSuggestionScore);
if (DBG) {
Log.d(TAG, "Normalized " + consideredWord + "," + autoCorrectionSuggestion + ","
diff --git a/java/src/com/android/inputmethod/latin/EditingUtils.java b/java/src/com/android/inputmethod/latin/EditingUtils.java
index 1e8ad1840..b3f613bae 100644
--- a/java/src/com/android/inputmethod/latin/EditingUtils.java
+++ b/java/src/com/android/inputmethod/latin/EditingUtils.java
@@ -1,12 +1,12 @@
/*
* Copyright (C) 2009 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
@@ -16,8 +16,6 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.compat.InputConnectionCompatUtils;
-
import android.text.TextUtils;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
@@ -246,7 +244,7 @@ public class EditingUtils {
if (selStart == selEnd) {
// There is just a cursor, so get the word at the cursor
// getWordRangeAtCursor returns null if the connection is null
- EditingUtils.Range range = getWordRangeAtCursor(ic, wordSeparators);
+ final EditingUtils.Range range = getWordRangeAtCursor(ic, wordSeparators);
if (range != null && !TextUtils.isEmpty(range.mWord)) {
return new SelectedWord(selStart - range.mCharsBefore, selEnd + range.mCharsAfter,
range.mWord);
@@ -254,20 +252,19 @@ public class EditingUtils {
} else {
if (null == ic) return null;
// Is the previous character empty or a word separator? If not, return null.
- CharSequence charsBefore = ic.getTextBeforeCursor(1, 0);
+ final CharSequence charsBefore = ic.getTextBeforeCursor(1, 0);
if (!isWordBoundary(charsBefore, wordSeparators)) {
return null;
}
// Is the next character empty or a word separator? If not, return null.
- CharSequence charsAfter = ic.getTextAfterCursor(1, 0);
+ final CharSequence charsAfter = ic.getTextAfterCursor(1, 0);
if (!isWordBoundary(charsAfter, wordSeparators)) {
return null;
}
// Extract the selection alone
- CharSequence touching = InputConnectionCompatUtils.getSelectedText(
- ic, selStart, selEnd);
+ final CharSequence touching = ic.getSelectedText(0);
if (TextUtils.isEmpty(touching)) return null;
// Is any part of the selection a separator? If so, return null.
final int length = touching.length();
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index 098913bef..46d11fa37 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.latin;
import android.content.Context;
+import com.android.inputmethod.keyboard.KeyDetector;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.ProximityInfo;
@@ -209,13 +210,19 @@ public class ExpandableDictionary extends Dictionary {
@SuppressWarnings("unused") final ProximityInfo proximityInfo) {
mInputLength = codes.size();
if (mCodes.length < mInputLength) mCodes = new int[mInputLength][];
+ final int[] xCoordinates = codes.getXCoordinates();
+ final int[] yCoordinates = codes.getYCoordinates();
// Cache the codes so that we don't have to lookup an array list
for (int i = 0; i < mInputLength; i++) {
// TODO: Calculate proximity info here.
if (mCodes[i] == null || mCodes[i].length < 1) {
- mCodes[i] = new int[1];
+ mCodes[i] = new int[ProximityInfo.MAX_PROXIMITY_CHARS_SIZE];
}
- mCodes[i][0] = codes.getCodeAt(i);
+ final int x = xCoordinates != null && i < xCoordinates.length ?
+ xCoordinates[i] : WordComposer.NOT_A_COORDINATE;
+ final int y = xCoordinates != null && i < yCoordinates.length ?
+ yCoordinates[i] : WordComposer.NOT_A_COORDINATE;
+ proximityInfo.fillArrayWithNearestKeyCodes(x, y, codes.getCodeAt(i), mCodes[i]);
}
mMaxDepth = mInputLength * 3;
getWordsRec(mRoots, codes, mWordBuilder, 0, false, 1, 0, -1, callback);
@@ -328,7 +335,7 @@ public class ExpandableDictionary extends Dictionary {
for (int j = 0; j < alternativesSize; j++) {
final int addedAttenuation = (j > 0 ? 1 : 2);
final int currentChar = currentChars[j];
- if (currentChar == -1) {
+ if (currentChar == KeyDetector.NOT_A_CODE) {
break;
}
if (currentChar == lowerC || currentChar == c) {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index e6094d9e1..69780d0fd 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -46,22 +46,18 @@ import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.InputConnection;
import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
import com.android.inputmethod.compat.CompatUtils;
import com.android.inputmethod.compat.EditorInfoCompatUtils;
-import com.android.inputmethod.compat.InputConnectionCompatUtils;
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper;
-import com.android.inputmethod.compat.InputTypeCompatUtils;
import com.android.inputmethod.compat.SuggestionSpanUtils;
-import com.android.inputmethod.deprecated.LanguageSwitcherProxy;
-import com.android.inputmethod.deprecated.VoiceProxy;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardActionListener;
import com.android.inputmethod.keyboard.KeyboardId;
@@ -193,7 +189,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private SharedPreferences mPrefs;
/* package for tests */ final KeyboardSwitcher mKeyboardSwitcher;
private final SubtypeSwitcher mSubtypeSwitcher;
- private VoiceProxy mVoiceProxy;
private boolean mShouldSwitchToLastSubtype = true;
private UserDictionary mUserDictionary;
@@ -234,7 +229,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
public static class UIHandler extends StaticInnerHandlerWrapper<LatinIME> {
private static final int MSG_UPDATE_SHIFT_STATE = 1;
- private static final int MSG_VOICE_RESULTS = 2;
private static final int MSG_SPACE_TYPED = 4;
private static final int MSG_SET_BIGRAM_PREDICTIONS = 5;
private static final int MSG_PENDING_IMS_CALLBACK = 6;
@@ -272,11 +266,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
case MSG_SET_BIGRAM_PREDICTIONS:
latinIme.updateBigramPredictions();
break;
- case MSG_VOICE_RESULTS:
- final Keyboard keyboard = switcher.getKeyboard();
- latinIme.mVoiceProxy.handleVoiceResults(latinIme.preferCapitalization()
- || (keyboard != null && keyboard.isShiftedOrShiftLocked()));
- break;
}
}
@@ -311,10 +300,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
removeMessages(MSG_SET_BIGRAM_PREDICTIONS);
}
- public void updateVoiceResults() {
- sendMessage(obtainMessage(MSG_VOICE_RESULTS));
- }
-
public void startDoubleSpacesTimer() {
removeMessages(MSG_SPACE_TYPED);
sendMessageDelayed(obtainMessage(MSG_SPACE_TYPED), mDoubleSpacesTurnIntoPeriodTimeout);
@@ -436,7 +421,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.init(this, prefs);
}
- LanguageSwitcherProxy.init(this, prefs);
InputMethodManagerCompatWrapper.init(this);
SubtypeSwitcher.init(this);
KeyboardSwitcher.init(this, prefs);
@@ -476,7 +460,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
registerReceiver(mReceiver, filter);
- mVoiceProxy = VoiceProxy.init(this, prefs, mHandler);
final IntentFilter packageFilter = new IntentFilter();
packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
@@ -577,7 +560,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
unregisterReceiver(mReceiver);
unregisterReceiver(mDictionaryPackInstallReceiver);
- mVoiceProxy.destroy();
LatinImeLogger.commit();
LatinImeLogger.onDestroy();
super.onDestroy();
@@ -596,14 +578,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (isShowingOptionDialog())
mOptionsDialog.dismiss();
}
-
- mVoiceProxy.startChangingConfiguration();
super.onConfigurationChanged(conf);
- mVoiceProxy.onConfigurationChanged(conf);
- mVoiceProxy.finishChangingConfiguration();
-
- // This will work only when the subtype is not supported.
- LanguageSwitcherProxy.onConfigurationChanged(conf);
}
@Override
@@ -698,13 +673,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mSubtypeSwitcher.updateParametersOnStartInputView();
- // Most such things we decide below in initializeInputAttributesAndGetMode, but we need to
- // know now whether this is a password text field, because we need to know now whether we
- // want to enable the voice button.
- final int inputType = editorInfo.inputType;
- mVoiceProxy.resetVoiceStates(InputTypeCompatUtils.isPasswordInputType(inputType)
- || InputTypeCompatUtils.isVisiblePasswordInputType(inputType));
-
// The EditorInfo might have a flag that affects fullscreen mode.
// Note: This call should be done by InputMethodService?
updateFullscreenMode();
@@ -726,9 +694,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (mSuggest != null && mSettingsValues.mAutoCorrectEnabled) {
mSuggest.setAutoCorrectionThreshold(mSettingsValues.mAutoCorrectionThreshold);
}
- mVoiceProxy.loadSettings(editorInfo, mPrefs);
- // This will work only when the subtype is not supported.
- LanguageSwitcherProxy.loadSettings();
if (mSubtypeSwitcher.isKeyboardMode()) {
switcher.loadKeyboard(editorInfo, mSettingsValues);
@@ -746,8 +711,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mSettingsValues.mKeyPreviewPopupDismissDelay);
inputView.setProximityCorrectionEnabled(true);
- mVoiceProxy.onStartInputView(inputView.getWindowToken());
-
if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
}
@@ -763,8 +726,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
LatinImeLogger.commit();
- mVoiceProxy.flushVoiceInputLogs();
-
KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null) inputView.closing();
if (mUserHistoryDictionary != null) mUserHistoryDictionary.flushPendingWrites();
@@ -780,18 +741,25 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
@Override
- public void onUpdateExtractedText(int token, ExtractedText text) {
- super.onUpdateExtractedText(token, text);
- mVoiceProxy.showPunctuationHintIfNecessary();
- }
-
- @Override
public void onUpdateSelection(int oldSelStart, int oldSelEnd,
int newSelStart, int newSelEnd,
int composingSpanStart, int composingSpanEnd) {
super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd,
composingSpanStart, composingSpanEnd);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ if (ResearchLogger.UnsLogGroup.ON_UPDATE_SELECTION.isEnabled) {
+ final String s = "onUpdateSelection: oss=" + oldSelStart
+ + ", ose=" + oldSelEnd
+ + ", lss=" + mLastSelectionStart
+ + ", lse=" + mLastSelectionEnd
+ + ", nss=" + newSelStart
+ + ", nse=" + newSelEnd
+ + ", cs=" + composingSpanStart
+ + ", ce=" + composingSpanEnd;
+ ResearchLogger.logUnstructured(ResearchLogger.UnsLogGroup.ON_UPDATE_SELECTION, s);
+ }
+ }
if (DEBUG) {
Log.i(TAG, "onUpdateSelection: oss=" + oldSelStart
+ ", ose=" + oldSelEnd
@@ -803,8 +771,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
+ ", ce=" + composingSpanEnd);
}
- mVoiceProxy.setCursorAndSelection(newSelEnd, newSelStart);
-
// TODO: refactor the following code to be less contrived.
// "newSelStart != composingSpanEnd" || "newSelEnd != composingSpanEnd" means
// that the cursor is not at the end of the composing span, or there is a selection.
@@ -892,7 +858,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mOptionsDialog.dismiss();
mOptionsDialog = null;
}
- mVoiceProxy.hideVoiceWindow();
super.hideWindow();
}
@@ -1081,7 +1046,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (ic != null) {
ic.finishComposingText();
}
- mVoiceProxy.setVoiceInputHighlighted(false);
}
private void resetComposingState(final boolean alsoResetLastComposedWord) {
@@ -1171,14 +1135,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private void onSettingsKeyPressed() {
if (isShowingOptionDialog()) return;
- if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) {
- showSubtypeSelectorAndSettings();
- } else if (SubtypeUtils.hasMultipleEnabledIMEsOrSubtypes(
- false /* exclude aux subtypes */)) {
- showOptionsMenu();
- } else {
- launchSettings();
- }
+ showSubtypeSelectorAndSettings();
}
// Virtual codes representing custom requests. These are used in onCustomRequest() below.
@@ -1338,7 +1295,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
@Override
public void onTextInput(CharSequence text) {
- mVoiceProxy.commitVoiceInput();
final InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
ic.beginBatchEdit();
@@ -1383,7 +1339,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
private void handleBackspace(final int spaceState) {
- if (mVoiceProxy.logAndRevertVoiceInput()) return;
final InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
ic.beginBatchEdit();
@@ -1393,8 +1348,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// "ic" may not be null.
private void handleBackspaceWhileInBatchEdit(final int spaceState, final InputConnection ic) {
- mVoiceProxy.handleBackspace();
-
// In many cases, we may have to put the keyboard in auto-shift state again.
mHandler.postUpdateShiftState();
@@ -1493,7 +1446,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private void handleCharacter(final int primaryCode, final int x,
final int y, final int spaceState) {
- mVoiceProxy.handleCharacter();
final InputConnection ic = getCurrentInputConnection();
if (null != ic) ic.beginBatchEdit();
// TODO: if ic is null, does it make any sense to call this?
@@ -1569,8 +1521,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Returns true if we did an autocorrection, false otherwise.
private boolean handleSeparator(final int primaryCode, final int x, final int y,
final int spaceState) {
- mVoiceProxy.handleSeparator();
-
// Should dismiss the "Touch again to save" message when handling separator
if (mSuggestionsView != null && mSuggestionsView.dismissAddToDictionaryHint()) {
mHandler.cancelUpdateBigramPredictions();
@@ -1656,7 +1606,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private void handleClose() {
commitTyped(getCurrentInputConnection(), LastComposedWord.NOT_A_SEPARATOR);
- mVoiceProxy.handleClose();
requestHideSelf(0);
LatinKeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null)
@@ -1736,8 +1685,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
public void updateSuggestions() {
// Check if we have a suggestion engine attached.
- if ((mSuggest == null || !isSuggestionsRequested())
- && !mVoiceProxy.isVoiceInputHighlighted()) {
+ if ((mSuggest == null || !isSuggestionsRequested())) {
if (mWordComposer.isComposingWord()) {
Log.w(TAG, "Called updateSuggestions but suggestions were not requested!");
mWordComposer.setAutoCorrection(mWordComposer.getTypedWord());
@@ -1837,8 +1785,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (!typedWord.equals(autoCorrection) && null != ic) {
// This will make the correction flash for a short while as a visual clue
// to the user that auto-correction happened.
- InputConnectionCompatUtils.commitCorrection(ic,
- mLastSelectionEnd - typedWord.length(), typedWord, autoCorrection);
+ ic.commitCorrection(new CorrectionInfo(mLastSelectionEnd - typedWord.length(),
+ typedWord, autoCorrection));
}
}
}
@@ -1846,8 +1794,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
@Override
public void pickSuggestionManually(final int index, final CharSequence suggestion) {
final SuggestedWords suggestedWords = mSuggestionsView.getSuggestions();
- mVoiceProxy.flushAndLogAllTextModificationCounters(index, suggestion,
- mSettingsValues.mWordSeparators);
if (SPACE_STATE_PHANTOM == mSpaceState && suggestion.length() > 0) {
int firstChar = Character.codePointAt(suggestion, 0);
@@ -1940,7 +1886,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final int separatorCode) {
final InputConnection ic = getCurrentInputConnection();
if (ic != null) {
- mVoiceProxy.rememberReplacedWord(bestWord, mSettingsValues.mWordSeparators);
if (mSettingsValues.mEnableSuggestionSpanInsertion) {
final SuggestedWords suggestedWords = mSuggestionsView.getSuggestions();
ic.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan(
@@ -2193,11 +2138,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Notify that language or mode have been changed and toggleLanguage will update KeyboardID
// according to new language or mode.
public void onRefreshKeyboard() {
- if (!CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) {
- // Before Honeycomb, Voice IME is in LatinIME and it changes the current input view,
- // so that we need to re-create the keyboard input view here.
- setInputView(mKeyboardSwitcher.onCreateInputView());
- }
// When the device locale is changed in SetupWizard etc., this method may get called via
// onConfigurationChanged before SoftInputWindow is shown.
if (mKeyboardSwitcher.getKeyboardView() != null) {
@@ -2256,11 +2196,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
};
- // TODO: remove this method when VoiceProxy has been removed
- public void vibrate() {
- mFeedbackManager.vibrate(mKeyboardSwitcher.getKeyboardView());
- }
-
private void updateCorrectionMode() {
// TODO: cleanup messy flags
final boolean shouldAutoCorrect = mSettingsValues.mAutoCorrectEnabled
@@ -2328,32 +2263,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
showOptionDialogInternal(builder.create());
}
- private void showOptionsMenu() {
- final CharSequence title = getString(R.string.english_ime_input_options);
- final CharSequence[] items = new CharSequence[] {
- getString(R.string.selectInputMethod),
- getString(R.string.english_ime_settings),
- };
- final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface di, int position) {
- di.dismiss();
- switch (position) {
- case 0:
- mImm.showInputMethodPicker();
- break;
- case 1:
- launchSettings();
- break;
- }
- }
- };
- final AlertDialog.Builder builder = new AlertDialog.Builder(this)
- .setItems(items, listener)
- .setTitle(title);
- showOptionDialogInternal(builder.create());
- }
-
@Override
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
super.dump(fd, fout, args);
diff --git a/java/src/com/android/inputmethod/latin/ResearchLogger.java b/java/src/com/android/inputmethod/latin/ResearchLogger.java
index 570333cb7..c5fb61f78 100644
--- a/java/src/com/android/inputmethod/latin/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/latin/ResearchLogger.java
@@ -259,20 +259,33 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
write(LogGroup.STATE_CHANGE, subgroup + "\t" + details);
}
+ public static enum UnsLogGroup {
+ // TODO: expand to include one flag per log point
+ // TODO: support selective enabling of flags
+ ON_UPDATE_SELECTION;
+
+ public boolean isEnabled = true;
+ }
+
+ public static void logUnstructured(UnsLogGroup logGroup, String details) {
+ }
+
private void write(final LogGroup logGroup, final String log) {
+ // TODO: rewrite in native for better performance
mLoggingHandler.post(new Runnable() {
@Override
public void run() {
final long currentTime = System.currentTimeMillis();
- mDate.setTime(currentTime);
final long upTime = SystemClock.uptimeMillis();
-
- final String printString = String.format("%s\t%d\t%s\t%s\n",
- mDateFormat.format(mDate), upTime, logGroup.mLogString, log);
+ final StringBuilder builder = new StringBuilder();
+ builder.append(currentTime);
+ builder.append('\t'); builder.append(upTime);
+ builder.append('\t'); builder.append(logGroup.mLogString);
+ builder.append('\t'); builder.append(log);
if (LatinImeLogger.sDBG) {
Log.d(TAG, "Write: " + '[' + logGroup.mLogString + ']' + log);
}
- if (mLogFileManager.append(printString)) {
+ if (mLogFileManager.append(builder.toString())) {
// success
} else {
if (LatinImeLogger.sDBG) {
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 110264892..fd61292df 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -44,16 +44,14 @@ import android.widget.TextView;
import com.android.inputmethod.compat.CompatUtils;
import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
-import com.android.inputmethod.compat.VibratorCompatWrapper;
-import com.android.inputmethod.deprecated.VoiceProxy;
+import com.android.inputmethod.latin.VibratorUtils;
import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethodcommon.InputMethodSettingsActivity;
import java.util.Locale;
public class Settings extends InputMethodSettingsActivity
- implements SharedPreferences.OnSharedPreferenceChangeListener,
- DialogInterface.OnDismissListener, OnPreferenceClickListener {
+ implements SharedPreferences.OnSharedPreferenceChangeListener, OnPreferenceClickListener {
private static final String TAG = Settings.class.getSimpleName();
public static final boolean ENABLE_EXPERIMENTAL_SETTINGS = false;
@@ -92,9 +90,6 @@ public class Settings extends InputMethodSettingsActivity
public static final String PREF_SELECTED_LANGUAGES = "selected_languages";
public static final String PREF_DEBUG_SETTINGS = "debug_settings";
- // Dialog ids
- private static final int VOICE_INPUT_CONFIRM_DIALOG = 0;
-
private PreferenceScreen mInputLanguageSelection;
private PreferenceScreen mKeypressVibrationDurationSettingsPref;
private PreferenceScreen mKeypressSoundVolumeSettingsPref;
@@ -113,7 +108,6 @@ public class Settings extends InputMethodSettingsActivity
private TextView mKeypressVibrationDurationSettingsTextView;
private TextView mKeypressSoundVolumeSettingsTextView;
- private boolean mOkClicked = false;
private String mVoiceModeOff;
private void ensureConsistencyOfAutoCorrectionSettings() {
@@ -185,7 +179,7 @@ public class Settings extends InputMethodSettingsActivity
generalSettings.removePreference(mVoicePreference);
}
- if (!VibratorCompatWrapper.getInstance(context).hasVibrator()) {
+ if (!VibratorUtils.getInstance(context).hasVibrator()) {
generalSettings.removePreference(findPreference(PREF_VIBRATE_ON));
}
@@ -291,9 +285,7 @@ public class Settings extends InputMethodSettingsActivity
public void onResume() {
super.onResume();
final boolean isShortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled();
- if (isShortcutImeEnabled
- || (VoiceProxy.VOICE_INSTALLED
- && VoiceProxy.isRecognitionAvailable(getActivityInternal()))) {
+ if (isShortcutImeEnabled) {
updateVoiceModeSummary();
} else {
getPreferenceScreen().removePreference(mVoicePreference);
@@ -312,13 +304,7 @@ public class Settings extends InputMethodSettingsActivity
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
(new BackupManager(getActivityInternal())).dataChanged();
- // If turning on voice input, show dialog
- if (key.equals(PREF_VOICE_MODE) && !mVoiceOn) {
- if (!prefs.getString(PREF_VOICE_MODE, mVoiceModeOff)
- .equals(mVoiceModeOff)) {
- showVoiceConfirmation();
- }
- } else if (key.equals(PREF_POPUP_ON)) {
+ if (key.equals(PREF_POPUP_ON)) {
final ListPreference popupDismissDelay =
(ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
if (null != popupDismissDelay) {
@@ -363,84 +349,16 @@ public class Settings extends InputMethodSettingsActivity
lp.setSummary(lp.getEntries()[lp.findIndexOfValue(lp.getValue())]);
}
- private void showVoiceConfirmation() {
- mOkClicked = false;
- getActivityInternal().showDialog(VOICE_INPUT_CONFIRM_DIALOG);
- // Make URL in the dialog message clickable
- if (mDialog != null) {
- TextView textView = (TextView) mDialog.findViewById(android.R.id.message);
- if (textView != null) {
- textView.setMovementMethod(LinkMovementMethod.getInstance());
- }
- }
- }
-
private void updateVoiceModeSummary() {
mVoicePreference.setSummary(
getResources().getStringArray(R.array.voice_input_modes_summary)
[mVoicePreference.findIndexOfValue(mVoicePreference.getValue())]);
}
- @Override
- protected Dialog onCreateDialog(int id) {
- switch (id) {
- case VOICE_INPUT_CONFIRM_DIALOG:
- DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int whichButton) {
- if (whichButton == DialogInterface.BUTTON_NEGATIVE) {
- mVoicePreference.setValue(mVoiceModeOff);
- } else if (whichButton == DialogInterface.BUTTON_POSITIVE) {
- mOkClicked = true;
- }
- }
- };
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivityInternal())
- .setTitle(R.string.voice_warning_title)
- .setPositiveButton(android.R.string.ok, listener)
- .setNegativeButton(android.R.string.cancel, listener);
-
- // Get the current list of supported locales and check the current locale against
- // that list, to decide whether to put a warning that voice input will not work in
- // the current language as part of the pop-up confirmation dialog.
- boolean localeSupported = SubtypeSwitcher.isVoiceSupported(
- this, Locale.getDefault().toString());
-
- final CharSequence message;
- if (localeSupported) {
- message = TextUtils.concat(
- getText(R.string.voice_warning_may_not_understand), "\n\n",
- getText(R.string.voice_hint_dialog_message));
- } else {
- message = TextUtils.concat(
- getText(R.string.voice_warning_locale_not_supported), "\n\n",
- getText(R.string.voice_warning_may_not_understand), "\n\n",
- getText(R.string.voice_hint_dialog_message));
- }
- builder.setMessage(message);
- AlertDialog dialog = builder.create();
- mDialog = dialog;
- dialog.setOnDismissListener(this);
- return dialog;
- default:
- Log.e(TAG, "unknown dialog " + id);
- return null;
- }
- }
-
- @Override
- public void onDismiss(DialogInterface dialog) {
- if (!mOkClicked) {
- // This assumes that onPreferenceClick gets called first, and this if the user
- // agreed after the warning, we set the mOkClicked value to true.
- mVoicePreference.setValue(mVoiceModeOff);
- }
- }
-
private void refreshEnablingsOfKeypressSoundAndVibrationSettings(
SharedPreferences sp, Resources res) {
if (mKeypressVibrationDurationSettingsPref != null) {
- final boolean hasVibrator = VibratorCompatWrapper.getInstance(this).hasVibrator();
+ final boolean hasVibrator = VibratorUtils.getInstance(this).hasVibrator();
final boolean vibrateOn = hasVibrator && sp.getBoolean(Settings.PREF_VIBRATE_ON,
res.getBoolean(R.bool.config_default_vibration_enabled));
mKeypressVibrationDurationSettingsPref.setEnabled(vibrateOn);
@@ -503,7 +421,7 @@ public class Settings extends InputMethodSettingsActivity
@Override
public void onStopTrackingTouch(SeekBar arg0) {
final int tempMs = arg0.getProgress();
- VibratorCompatWrapper.getInstance(context).vibrate(tempMs);
+ VibratorUtils.getInstance(context).vibrate(tempMs);
}
});
sb.setProgress(currentMs);
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index c1335fdfe..f76cc7e44 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -23,8 +23,9 @@ import android.util.Log;
import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.compat.InputTypeCompatUtils;
-import com.android.inputmethod.compat.VibratorCompatWrapper;
import com.android.inputmethod.keyboard.internal.KeySpecParser;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.VibratorUtils;
import java.util.ArrayList;
import java.util.Arrays;
@@ -162,7 +163,7 @@ public class SettingsValues {
if (puncs != null) {
for (final String puncSpec : puncs) {
puncList.add(new SuggestedWords.SuggestedWordInfo(
- KeySpecParser.getLabel(puncSpec)));
+ KeySpecParser.getLabel(puncSpec), SuggestedWordInfo.MAX_SCORE));
}
}
return new SuggestedWords(puncList,
@@ -187,7 +188,7 @@ public class SettingsValues {
private static boolean isVibrateOn(final Context context, final SharedPreferences prefs,
final Resources res) {
- final boolean hasVibrator = VibratorCompatWrapper.getInstance(context).hasVibrator();
+ final boolean hasVibrator = VibratorUtils.getInstance(context).hasVibrator();
return hasVibrator && prefs.getBoolean(Settings.PREF_VIBRATE_ON,
res.getBoolean(R.bool.config_default_vibration_enabled));
}
diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java
index 917521c40..66c13bd2e 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java
@@ -36,10 +36,16 @@ public class SubtypeLocale {
}
public static String getFullDisplayName(Locale locale) {
- String localeCode = locale.toString();
+ final String localeCode = locale.toString();
for (int index = 0; index < sExceptionKeys.length; index++) {
- if (sExceptionKeys[index].equals(localeCode))
- return sExceptionValues[index];
+ if (sExceptionKeys[index].equals(localeCode)) {
+ final String value = sExceptionValues[index];
+ if (value.indexOf("%s") >= 0) {
+ final String languageName = locale.getDisplayLanguage(locale);
+ return String.format(value, languageName);
+ }
+ return value;
+ }
}
return locale.getDisplayName(locale);
}
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index 3524c72f6..de2e8be3d 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -33,7 +33,6 @@ import android.util.Log;
import com.android.inputmethod.compat.InputMethodInfoCompatWrapper;
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper;
-import com.android.inputmethod.deprecated.VoiceProxy;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import java.util.ArrayList;
@@ -76,7 +75,6 @@ public class SubtypeSwitcher {
private Locale mSystemLocale;
private Locale mInputLocale;
private String mInputLocaleStr;
- private VoiceProxy.VoiceInputWrapper mVoiceInputWrapper;
/*-----------------------------------------------------------*/
private boolean mIsNetworkConnected;
@@ -108,7 +106,6 @@ public class SubtypeSwitcher {
mInputLocaleStr = null;
mCurrentSubtype = null;
mAllEnabledSubtypesOfCurrentInputMethod = null;
- mVoiceInputWrapper = null;
final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
mIsNetworkConnected = (info != null && info.isConnected());
@@ -234,34 +231,12 @@ public class SubtypeSwitcher {
}
mCurrentSubtype = newSubtype;
- // If the old mode is voice input, we need to reset or cancel its status.
- // We cancel its status when we change mode, while we reset otherwise.
if (isKeyboardMode()) {
- if (modeChanged) {
- if (VOICE_MODE.equals(oldMode) && mVoiceInputWrapper != null) {
- mVoiceInputWrapper.cancel();
- }
- }
if (modeChanged || languageChanged) {
updateShortcutIME();
mService.onRefreshKeyboard();
}
- } else if (isVoiceMode() && mVoiceInputWrapper != null) {
- if (VOICE_MODE.equals(oldMode)) {
- mVoiceInputWrapper.reset();
- }
- // If needsToShowWarningDialog is true, voice input need to show warning before
- // show recognition view.
- if (languageChanged || modeChanged
- || VoiceProxy.getInstance().needsToShowWarningDialog()) {
- triggerVoiceIME();
- }
} else {
- if (VOICE_MODE.equals(oldMode) && mVoiceInputWrapper != null) {
- // We need to reset the voice input to release the resources and to reset its status
- // as it is not the current input mode.
- mVoiceInputWrapper.reset();
- }
final String packageName = mService.getPackageName();
int version = -1;
try {
@@ -270,7 +245,7 @@ public class SubtypeSwitcher {
} catch (NameNotFoundException e) {
}
Log.w(TAG, "Unknown subtype mode: " + newMode + "," + version + ", " + packageName
- + ", " + mVoiceInputWrapper + ". IME is already changed to other IME.");
+ + ". IME is already changed to other IME.");
if (newSubtype != null) {
Log.w(TAG, "Subtype mode:" + newSubtype.getMode());
Log.w(TAG, "Subtype locale:" + newSubtype.getLocale());
@@ -477,40 +452,6 @@ public class SubtypeSwitcher {
return KEYBOARD_MODE.equals(getCurrentSubtypeMode());
}
-
- ///////////////////////////
- // Voice Input functions //
- ///////////////////////////
-
- public boolean setVoiceInputWrapper(VoiceProxy.VoiceInputWrapper vi) {
- if (mVoiceInputWrapper == null && vi != null) {
- mVoiceInputWrapper = vi;
- if (isVoiceMode()) {
- if (DBG) {
- Log.d(TAG, "Set and call voice input.: " + getInputLocaleStr());
- }
- triggerVoiceIME();
- return true;
- }
- }
- return false;
- }
-
- public boolean isVoiceMode() {
- return null == mCurrentSubtype ? false : VOICE_MODE.equals(getCurrentSubtypeMode());
- }
-
- public boolean isDummyVoiceMode() {
- return mCurrentSubtype != null && mCurrentSubtype.getOriginalObject() == null
- && VOICE_MODE.equals(getCurrentSubtypeMode());
- }
-
- private void triggerVoiceIME() {
- if (!mService.isInputViewShown()) return;
- VoiceProxy.getInstance().startListening(false,
- KeyboardSwitcher.getInstance().getKeyboardView().getWindowToken());
- }
-
public String getInputLanguageName() {
return StringUtils.getDisplayLanguage(getInputLocale());
}
@@ -537,18 +478,4 @@ public class SubtypeSwitcher {
public String getCurrentSubtypeMode() {
return null != mCurrentSubtype ? mCurrentSubtype.getMode() : KEYBOARD_MODE;
}
-
-
- public static boolean isVoiceSupported(Context context, String locale) {
- // Get the current list of supported locales and check the current locale against that
- // list. We cache this value so as not to check it every time the user starts a voice
- // input. Because this method is called by onStartInputView, this should mean that as
- // long as the locale doesn't change while the user is keeping the IME open, the
- // value should never be stale.
- String supportedLocalesString = VoiceProxy.getSupportedLocalesString(
- context.getContentResolver());
- List<String> voiceInputSupportedLocales = Arrays.asList(
- supportedLocalesString.split("\\s+"));
- return voiceInputSupportedLocales.contains(locale);
- }
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 9ae2506f4..b31f3019c 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -26,7 +26,6 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import java.io.File;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
@@ -93,11 +92,9 @@ public class Suggest implements Dictionary.WordCallback {
private static final int PREF_MAX_BIGRAMS = 60;
private double mAutoCorrectionThreshold;
- private int[] mScores = new int[mPrefMaxSuggestions];
- private int[] mBigramScores = new int[PREF_MAX_BIGRAMS];
- private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
- private ArrayList<CharSequence> mBigramSuggestions = new ArrayList<CharSequence>();
+ private ArrayList<SuggestedWordInfo> mSuggestions = new ArrayList<SuggestedWordInfo>();
+ private ArrayList<SuggestedWordInfo> mBigramSuggestions = new ArrayList<SuggestedWordInfo>();
private CharSequence mConsideredWord;
// TODO: Remove these member variables by passing more context to addWord() callback method
@@ -230,10 +227,8 @@ public class Suggest implements Dictionary.WordCallback {
return sb;
}
- protected void addBigramToSuggestions(CharSequence bigram) {
- final StringBuilder sb = new StringBuilder(getApproxMaxWordLength());
- sb.append(bigram);
- mSuggestions.add(sb);
+ protected void addBigramToSuggestions(SuggestedWordInfo bigram) {
+ mSuggestions.add(bigram);
}
private static final WordComposer sEmptyWordComposer = new WordComposer();
@@ -242,15 +237,13 @@ public class Suggest implements Dictionary.WordCallback {
mIsFirstCharCapitalized = false;
mIsAllUpperCase = false;
mTrailingSingleQuotesCount = 0;
- mSuggestions = new ArrayList<CharSequence>(mPrefMaxSuggestions);
- Arrays.fill(mScores, 0);
+ mSuggestions = new ArrayList<SuggestedWordInfo>(mPrefMaxSuggestions);
// Treating USER_TYPED as UNIGRAM suggestion for logging now.
LatinImeLogger.onAddSuggestedWord("", Suggest.DIC_USER_TYPED, Dictionary.UNIGRAM);
mConsideredWord = "";
- Arrays.fill(mBigramScores, 0);
- mBigramSuggestions = new ArrayList<CharSequence>(PREF_MAX_BIGRAMS);
+ mBigramSuggestions = new ArrayList<SuggestedWordInfo>(PREF_MAX_BIGRAMS);
CharSequence lowerPrevWord = prevWordForBigram.toString().toLowerCase();
if (mMainDict != null && mMainDict.isValidWord(lowerPrevWord)) {
@@ -265,9 +258,9 @@ public class Suggest implements Dictionary.WordCallback {
addBigramToSuggestions(mBigramSuggestions.get(i));
}
- StringUtils.removeDupes(mSuggestions);
+ SuggestedWordInfo.removeDups(mSuggestions);
- return new SuggestedWords(SuggestedWords.getFromCharSequenceList(mSuggestions),
+ return new SuggestedWords(mSuggestions,
false /* typedWordValid */,
false /* hasAutoCorrectionCandidate */,
false /* allowsToBeAutoCorrected */,
@@ -283,8 +276,7 @@ public class Suggest implements Dictionary.WordCallback {
mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
mIsAllUpperCase = wordComposer.isAllUpperCase();
mTrailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount();
- mSuggestions = new ArrayList<CharSequence>(mPrefMaxSuggestions);
- Arrays.fill(mScores, 0);
+ mSuggestions = new ArrayList<SuggestedWordInfo>(mPrefMaxSuggestions);
final String typedWord = wordComposer.getTypedWord();
final String consideredWord = mTrailingSingleQuotesCount > 0
@@ -296,8 +288,7 @@ public class Suggest implements Dictionary.WordCallback {
if (wordComposer.size() <= 1 && (correctionMode == CORRECTION_FULL_BIGRAM)) {
// At first character typed, search only the bigrams
- Arrays.fill(mBigramScores, 0);
- mBigramSuggestions = new ArrayList<CharSequence>(PREF_MAX_BIGRAMS);
+ mBigramSuggestions = new ArrayList<SuggestedWordInfo>(PREF_MAX_BIGRAMS);
if (!TextUtils.isEmpty(prevWordForBigram)) {
CharSequence lowerPrevWord = prevWordForBigram.toString().toLowerCase();
@@ -317,12 +308,14 @@ public class Suggest implements Dictionary.WordCallback {
// Word entered: return only bigrams that match the first char of the typed word
final char currentChar = consideredWord.charAt(0);
// TODO: Must pay attention to locale when changing case.
+ // TODO: Use codepoint instead of char
final char currentCharUpper = Character.toUpperCase(currentChar);
int count = 0;
final int bigramSuggestionSize = mBigramSuggestions.size();
for (int i = 0; i < bigramSuggestionSize; i++) {
- final CharSequence bigramSuggestion = mBigramSuggestions.get(i);
- final char bigramSuggestionFirstChar = bigramSuggestion.charAt(0);
+ final SuggestedWordInfo bigramSuggestion = mBigramSuggestions.get(i);
+ final char bigramSuggestionFirstChar =
+ (char)bigramSuggestion.codePointAt(0);
if (bigramSuggestionFirstChar == currentChar
|| bigramSuggestionFirstChar == currentCharUpper) {
addBigramToSuggestions(bigramSuggestion);
@@ -359,7 +352,7 @@ public class Suggest implements Dictionary.WordCallback {
if (CORRECTION_FULL == correctionMode || CORRECTION_FULL_BIGRAM == correctionMode) {
final CharSequence autoCorrection =
AutoCorrection.computeAutoCorrectionWord(mUnigramDictionaries, wordComposer,
- mSuggestions, mScores, consideredWord, mAutoCorrectionThreshold,
+ mSuggestions, consideredWord, mAutoCorrectionThreshold,
whitelistedWord);
hasAutoCorrection = (null != autoCorrection);
} else {
@@ -372,20 +365,22 @@ public class Suggest implements Dictionary.WordCallback {
for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) {
sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE);
}
- mSuggestions.add(0, sb.toString());
+ mSuggestions.add(0, new SuggestedWordInfo(
+ sb.toString(), SuggestedWordInfo.MAX_SCORE));
} else {
- mSuggestions.add(0, whitelistedWord);
+ mSuggestions.add(0, new SuggestedWordInfo(
+ whitelistedWord, SuggestedWordInfo.MAX_SCORE));
}
}
- mSuggestions.add(0, typedWord);
- StringUtils.removeDupes(mSuggestions);
+ mSuggestions.add(0, new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE));
+ SuggestedWordInfo.removeDups(mSuggestions);
final ArrayList<SuggestedWordInfo> suggestionsList;
if (DBG) {
- suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWord, mSuggestions, mScores);
+ suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWord, mSuggestions);
} else {
- suggestionsList = SuggestedWords.getFromCharSequenceList(mSuggestions);
+ suggestionsList = mSuggestions;
}
// TODO: Change this scheme - a boolean is not enough. A whitelisted word may be "valid"
@@ -415,50 +410,45 @@ public class Suggest implements Dictionary.WordCallback {
false /* isObsoleteSuggestions */);
}
- // This assumes the scores[] array is at least as long as suggestions.size() - 1.
private static ArrayList<SuggestedWordInfo> getSuggestionsInfoListWithDebugInfo(
- final String typedWord, final ArrayList<CharSequence> suggestions, final int[] scores) {
- // TODO: this doesn't take into account the fact that removing dupes from mSuggestions
- // may have made mScores[] and mSuggestions out of sync.
- final CharSequence autoCorrectionSuggestion = suggestions.get(0);
+ final String typedWord, final ArrayList<SuggestedWordInfo> suggestions) {
+ final SuggestedWordInfo typedWordInfo = suggestions.get(0);
+ typedWordInfo.setDebugString("+");
double normalizedScore = BinaryDictionary.calcNormalizedScore(
- typedWord, autoCorrectionSuggestion.toString(), scores[0]);
+ typedWord, typedWordInfo.toString(), typedWordInfo.mScore);
final int suggestionsSize = suggestions.size();
final ArrayList<SuggestedWordInfo> suggestionsList =
new ArrayList<SuggestedWordInfo>(suggestionsSize);
- suggestionsList.add(new SuggestedWordInfo(autoCorrectionSuggestion, "+"));
+ suggestionsList.add(typedWordInfo);
// Note: i here is the index in mScores[], but the index in mSuggestions is one more
// than i because we added the typed word to mSuggestions without touching mScores.
- for (int i = 0; i < scores.length && i < suggestionsSize - 1; ++i) {
+ for (int i = 0; i < suggestionsSize - 1; ++i) {
+ final SuggestedWordInfo cur = suggestions.get(i + 1);
final String scoreInfoString;
if (normalizedScore > 0) {
- scoreInfoString = String.format("%d (%4.2f)", scores[i], normalizedScore);
+ scoreInfoString = String.format("%d (%4.2f)", cur.mScore, normalizedScore);
normalizedScore = 0.0;
} else {
- scoreInfoString = Integer.toString(scores[i]);
+ scoreInfoString = Integer.toString(cur.mScore);
}
- suggestionsList.add(new SuggestedWordInfo(suggestions.get(i + 1), scoreInfoString));
- }
- for (int i = scores.length; i < suggestionsSize; ++i) {
- suggestionsList.add(new SuggestedWordInfo(suggestions.get(i), "--"));
+ cur.setDebugString(scoreInfoString);
+ suggestionsList.add(cur);
}
return suggestionsList;
}
+ // TODO: Use codepoint instead of char
@Override
public boolean addWord(final char[] word, final int offset, final int length, int score,
final int dicTypeId, final int dataType) {
int dataTypeForLog = dataType;
- final ArrayList<CharSequence> suggestions;
- final int[] sortedScores;
+ final ArrayList<SuggestedWordInfo> suggestions;
final int prefMaxSuggestions;
if (dataType == Dictionary.BIGRAM) {
suggestions = mBigramSuggestions;
- sortedScores = mBigramScores;
prefMaxSuggestions = PREF_MAX_BIGRAMS;
} else {
suggestions = mSuggestions;
- sortedScores = mScores;
prefMaxSuggestions = mPrefMaxSuggestions;
}
@@ -469,13 +459,13 @@ public class Suggest implements Dictionary.WordCallback {
// TODO: remove this surrounding if clause and move this logic to
// getSuggestedWordBuilder.
if (suggestions.size() > 0) {
- final String currentHighestWord = suggestions.get(0).toString();
+ final SuggestedWordInfo currentHighestWord = suggestions.get(0);
// If the current highest word is also equal to typed word, we need to compare
// frequency to determine the insertion position. This does not ensure strictly
// correct ordering, but ensures the top score is on top which is enough for
// removing duplicates correctly.
- if (StringUtils.equalsIgnoreCase(currentHighestWord, word, offset, length)
- && score <= sortedScores[0]) {
+ if (StringUtils.equalsIgnoreCase(currentHighestWord.mWord, word, offset, length)
+ && score <= currentHighestWord.mScore) {
pos = 1;
}
}
@@ -486,7 +476,7 @@ public class Suggest implements Dictionary.WordCallback {
if(bigramSuggestion >= 0) {
dataTypeForLog = Dictionary.BIGRAM;
// turn freq from bigram into multiplier specified above
- double multiplier = (((double) mBigramScores[bigramSuggestion])
+ double multiplier = (((double) mBigramSuggestions.get(bigramSuggestion).mScore)
/ MAXIMUM_BIGRAM_FREQUENCY)
* (BIGRAM_MULTIPLIER_MAX - BIGRAM_MULTIPLIER_MIN)
+ BIGRAM_MULTIPLIER_MIN;
@@ -500,10 +490,12 @@ public class Suggest implements Dictionary.WordCallback {
}
// Check the last one's score and bail
- if (sortedScores[prefMaxSuggestions - 1] >= score) return true;
- while (pos < prefMaxSuggestions) {
- if (sortedScores[pos] < score
- || (sortedScores[pos] == score && length < suggestions.get(pos).length())) {
+ if (suggestions.size() >= prefMaxSuggestions
+ && suggestions.get(prefMaxSuggestions - 1).mScore >= score) return true;
+ while (pos < suggestions.size()) {
+ final int curScore = suggestions.get(pos).mScore;
+ if (curScore < score
+ || (curScore == score && length < suggestions.get(pos).codePointCount())) {
break;
}
pos++;
@@ -513,8 +505,6 @@ public class Suggest implements Dictionary.WordCallback {
return true;
}
- System.arraycopy(sortedScores, pos, sortedScores, pos + 1, prefMaxSuggestions - pos - 1);
- sortedScores[pos] = score;
final StringBuilder sb = new StringBuilder(getApproxMaxWordLength());
// TODO: Must pay attention to locale when changing case.
if (mIsAllUpperCase) {
@@ -530,7 +520,7 @@ public class Suggest implements Dictionary.WordCallback {
for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) {
sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE);
}
- suggestions.add(pos, sb);
+ suggestions.add(pos, new SuggestedWordInfo(sb, score));
if (suggestions.size() > prefMaxSuggestions) {
suggestions.remove(prefMaxSuggestions);
} else {
@@ -539,15 +529,16 @@ public class Suggest implements Dictionary.WordCallback {
return true;
}
+ // TODO: Use codepoint instead of char
private int searchBigramSuggestion(final char[] word, final int offset, final int length) {
// TODO This is almost O(n^2). Might need fix.
// search whether the word appeared in bigram data
int bigramSuggestSize = mBigramSuggestions.size();
for (int i = 0; i < bigramSuggestSize; i++) {
- if (mBigramSuggestions.get(i).length() == length) {
+ if (mBigramSuggestions.get(i).codePointCount() == length) {
boolean chk = true;
for (int j = 0; j < length; j++) {
- if (mBigramSuggestions.get(i).charAt(j) != word[offset+j]) {
+ if (mBigramSuggestions.get(i).codePointAt(j) != word[offset+j]) {
chk = false;
break;
}
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index ef8e58e0c..0c0ce182f 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -56,6 +56,10 @@ public class SuggestedWords {
return mSuggestedWordInfoList.get(pos).mWord;
}
+ public SuggestedWordInfo getWordInfo(int pos) {
+ return mSuggestedWordInfoList.get(pos);
+ }
+
public SuggestedWordInfo getInfo(int pos) {
return mSuggestedWordInfoList.get(pos);
}
@@ -79,20 +83,12 @@ public class SuggestedWords {
+ " words=" + Arrays.toString(mSuggestedWordInfoList.toArray());
}
- public static ArrayList<SuggestedWordInfo> getFromCharSequenceList(
- final ArrayList<CharSequence> wordList) {
- final ArrayList<SuggestedWordInfo> result = new ArrayList<SuggestedWordInfo>();
- for (CharSequence word : wordList) {
- if (null != word) result.add(new SuggestedWordInfo(word));
- }
- return result;
- }
-
public static ArrayList<SuggestedWordInfo> getFromApplicationSpecifiedCompletions(
final CompletionInfo[] infos) {
final ArrayList<SuggestedWordInfo> result = new ArrayList<SuggestedWordInfo>();
for (CompletionInfo info : infos) {
- if (null != info) result.add(new SuggestedWordInfo(info.getText()));
+ if (null != info) result.add(new SuggestedWordInfo(info.getText(),
+ SuggestedWordInfo.MAX_SCORE));
}
return result;
}
@@ -103,14 +99,15 @@ public class SuggestedWords {
final CharSequence typedWord, final SuggestedWords previousSuggestions) {
final ArrayList<SuggestedWordInfo> suggestionsList = new ArrayList<SuggestedWordInfo>();
final HashSet<String> alreadySeen = new HashSet<String>();
- suggestionsList.add(new SuggestedWordInfo(typedWord));
+ suggestionsList.add(new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE));
alreadySeen.add(typedWord.toString());
final int previousSize = previousSuggestions.size();
for (int pos = 1; pos < previousSize; pos++) {
- final String prevWord = previousSuggestions.getWord(pos).toString();
+ final SuggestedWordInfo prevWordInfo = previousSuggestions.getWordInfo(pos);
+ final String prevWord = prevWordInfo.mWord.toString();
// Filter out duplicate suggestion.
if (!alreadySeen.contains(prevWord)) {
- suggestionsList.add(new SuggestedWordInfo(prevWord));
+ suggestionsList.add(prevWordInfo);
alreadySeen.add(prevWord);
}
}
@@ -118,30 +115,64 @@ public class SuggestedWords {
}
public static class SuggestedWordInfo {
+ public static final int MAX_SCORE = Integer.MAX_VALUE;
+ private final String mWordStr;
public final CharSequence mWord;
- private final String mDebugString;
+ public final int mScore;
+ public final int mCodePointCount;
+ private String mDebugString = "";
- public SuggestedWordInfo(final CharSequence word) {
+ public SuggestedWordInfo(final CharSequence word, final int score) {
+ mWordStr = word.toString();
mWord = word;
- mDebugString = "";
+ mScore = score;
+ mCodePointCount = mWordStr.codePointCount(0, mWordStr.length());
}
- public SuggestedWordInfo(final CharSequence word, final String debugString) {
- mWord = word;
- if (null == debugString) throw new NullPointerException("");
- mDebugString = debugString;
+
+ public void setDebugString(String str) {
+ if (null == str) throw new NullPointerException("Debug info is null");
+ mDebugString = str;
}
public String getDebugString() {
return mDebugString;
}
+ public int codePointCount() {
+ return mCodePointCount;
+ }
+
+ public int codePointAt(int i) {
+ return mWordStr.codePointAt(i);
+ }
+
@Override
public String toString() {
if (TextUtils.isEmpty(mDebugString)) {
- return mWord.toString();
+ return mWordStr;
} else {
- return mWord.toString() + " (" + mDebugString.toString() + ")";
+ return mWordStr + " (" + mDebugString.toString() + ")";
+ }
+ }
+
+ // TODO: Consolidate this method and StringUtils.removeDupes() in the future.
+ public static void removeDups(ArrayList<SuggestedWordInfo> candidates) {
+ if (candidates.size() <= 1) {
+ return;
+ }
+ int i = 1;
+ while(i < candidates.size()) {
+ final SuggestedWordInfo cur = candidates.get(i);
+ for (int j = 0; j < i; ++j) {
+ final SuggestedWordInfo previous = candidates.get(j);
+ if (TextUtils.equals(cur.mWord, previous.mWord)) {
+ candidates.remove(cur.mScore < previous.mScore ? i : j);
+ --i;
+ break;
+ }
+ }
+ ++i;
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/VibratorUtils.java b/java/src/com/android/inputmethod/latin/VibratorUtils.java
new file mode 100644
index 000000000..33ffdd9c9
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/VibratorUtils.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 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.content.Context;
+import android.os.Vibrator;
+
+public class VibratorUtils {
+ private static final VibratorUtils sInstance = new VibratorUtils();
+ private Vibrator mVibrator;
+
+ private VibratorUtils() {
+ // This utility class is not publicly instantiable.
+ }
+
+ public static VibratorUtils getInstance(Context context) {
+ if (sInstance.mVibrator == null) {
+ sInstance.mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ }
+ return sInstance;
+ }
+
+ public boolean hasVibrator() {
+ if (mVibrator == null) {
+ return false;
+ }
+ return mVibrator.hasVibrator();
+ }
+
+ public void vibrate(long milliseconds) {
+ if (mVibrator == null) {
+ return;
+ }
+ mVibrator.vibrate(milliseconds);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 5a173857e..7b13e40c2 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -26,7 +26,6 @@ import android.util.Log;
import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
-import com.android.inputmethod.compat.ArraysCompatUtils;
import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.BinaryDictionary;
@@ -237,7 +236,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService
@Override
synchronized public boolean addWord(char[] word, int wordOffset, int wordLength, int score,
int dicTypeId, int dataType) {
- final int positionIndex = ArraysCompatUtils.binarySearch(mScores, 0, mLength, score);
+ final int positionIndex = Arrays.binarySearch(mScores, 0, mLength, score);
// binarySearch returns the index if the element exists, and -<insertion index> - 1
// if it doesn't. See documentation for binarySearch.
final int insertIndex = positionIndex >= 0 ? positionIndex : -positionIndex - 1;