From bf9d8348d89be257ccc3db75333bfd4cdf0a9b7e Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Sun, 17 Jul 2011 21:18:47 -0700 Subject: Support select input method dialog on pre-HC platform Bug: 4971680 Change-Id: I641b336da54813e13409bd7874aa22e51f790729 --- .../compat/InputMethodManagerCompatWrapper.java | 130 ++++++++++++++++++--- 1 file changed, 111 insertions(+), 19 deletions(-) (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java index 1cc13f249..51dc4cd37 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -16,21 +16,28 @@ package com.android.inputmethod.compat; -import com.android.inputmethod.deprecated.LanguageSwitcherProxy; -import com.android.inputmethod.latin.LatinIME; -import com.android.inputmethod.latin.SubtypeSwitcher; -import com.android.inputmethod.latin.Utils; - +import android.app.AlertDialog; import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.os.IBinder; import android.text.TextUtils; import android.util.Log; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; +import com.android.inputmethod.deprecated.LanguageSwitcherProxy; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.SubtypeSwitcher; +import com.android.inputmethod.latin.Utils; + import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -72,27 +79,27 @@ public class InputMethodManagerCompatWrapper { private static final String VOICE_MODE = "voice"; private static final String KEYBOARD_MODE = "keyboard"; + private InputMethodServiceCompatWrapper mService; private InputMethodManager mImm; + private PackageManager mPackageManager; + private ApplicationInfo mApplicationInfo; private LanguageSwitcherProxy mLanguageSwitcherProxy; private String mLatinImePackageName; - private InputMethodManagerCompatWrapper() { - } - - public static InputMethodManagerCompatWrapper getInstance(Context context) { - if (sInstance.mImm == null) { - sInstance.init(context); - } + public static InputMethodManagerCompatWrapper getInstance() { + if (sInstance.mImm == null) + Log.w(TAG, "getInstance() is called before initialization"); return sInstance; } - private synchronized void init(Context context) { - mImm = (InputMethodManager) context.getSystemService( + public static void init(InputMethodServiceCompatWrapper service) { + sInstance.mService = service; + sInstance.mImm = (InputMethodManager) service.getSystemService( Context.INPUT_METHOD_SERVICE); - if (context instanceof LatinIME) { - mLatinImePackageName = context.getPackageName(); - } - mLanguageSwitcherProxy = LanguageSwitcherProxy.getInstance(); + sInstance.mLatinImePackageName = service.getPackageName(); + sInstance.mPackageManager = service.getPackageManager(); + sInstance.mApplicationInfo = service.getApplicationInfo(); + sInstance.mLanguageSwitcherProxy = LanguageSwitcherProxy.getInstance(); } public InputMethodSubtypeCompatWrapper getCurrentInputMethodSubtype() { @@ -196,11 +203,15 @@ public class InputMethodManagerCompatWrapper { return shortcutMap; } + // We don't call this method when we switch between subtypes within this IME. public void setInputMethodAndSubtype( IBinder token, String id, InputMethodSubtypeCompatWrapper subtype) { + // TODO: Support subtype change on non-subtype-supported platform. if (subtype != null && subtype.hasOriginalObject()) { CompatUtils.invoke(mImm, null, METHOD_setInputMethodAndSubtype, token, id, subtype.getOriginalObject()); + } else { + mImm.setInputMethod(token, id); } } @@ -222,6 +233,87 @@ public class InputMethodManagerCompatWrapper { public void showInputMethodPicker() { if (mImm == null) return; - mImm.showInputMethodPicker(); + if (SUBTYPE_SUPPORTED) { + mImm.showInputMethodPicker(); + return; + } + + // The code below are based on {@link InputMethodManager#showInputMethodMenuInternal}. + + final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo( + this, mLatinImePackageName); + final List myImsList = getEnabledInputMethodSubtypeList( + myImi, true); + final InputMethodSubtypeCompatWrapper currentIms = getCurrentInputMethodSubtype(); + final List imiList = getEnabledInputMethodList(); + imiList.remove(myImi); + Collections.sort(imiList, new Comparator() { + @Override + public int compare(InputMethodInfoCompatWrapper imi1, + InputMethodInfoCompatWrapper imi2) { + final CharSequence imiId1 = imi1.loadLabel(mPackageManager) + "/" + imi1.getId(); + final CharSequence imiId2 = imi2.loadLabel(mPackageManager) + "/" + imi2.getId(); + return imiId1.toString().compareTo(imiId2.toString()); + } + }); + + final int myImsCount = myImsList.size(); + final int imiCount = imiList.size(); + final CharSequence[] items = new CharSequence[myImsCount + imiCount]; + + int checkedItem = 0; + int index = 0; + final CharSequence myImiLabel = myImi.loadLabel(mPackageManager); + for (int i = 0; i < myImsCount; i++) { + InputMethodSubtypeCompatWrapper ims = myImsList.get(i); + if (currentIms.equals(ims)) + checkedItem = index; + final CharSequence title = TextUtils.concat( + ims.getDisplayName(mService, mLatinImePackageName, mApplicationInfo), + " (" + myImiLabel, ")"); + items[index] = title; + index++; + } + + for (int i = 0; i < imiCount; i++) { + final InputMethodInfoCompatWrapper imi = imiList.get(i); + final CharSequence title = imi.loadLabel(mPackageManager); + items[index] = title; + index++; + } + + final OnClickListener buttonListener = new OnClickListener() { + @Override + public void onClick(DialogInterface di, int whichButton) { + final Intent intent = new Intent("android.settings.INPUT_METHOD_SETTINGS"); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED + | Intent.FLAG_ACTIVITY_CLEAR_TOP); + mService.startActivity(intent); + } + }; + final InputMethodServiceCompatWrapper service = mService; + final IBinder token = service.getWindow().getWindow().getAttributes().token; + final OnClickListener selectionListener = new OnClickListener() { + @Override + public void onClick(DialogInterface di, int which) { + di.dismiss(); + if (which < myImsCount) { + final int imsIndex = which; + final InputMethodSubtypeCompatWrapper ims = myImsList.get(imsIndex); + service.notifyOnCurrentInputMethodSubtypeChanged(ims); + } else { + final int imiIndex = which - myImsCount; + final InputMethodInfoCompatWrapper imi = imiList.get(imiIndex); + setInputMethodAndSubtype(token, imi.getId(), null); + } + } + }; + + final AlertDialog.Builder builder = new AlertDialog.Builder(mService) + .setTitle(mService.getString(R.string.selectInputMethod)) + .setNeutralButton(R.string.configure_input_method, buttonListener) + .setSingleChoiceItems(items, checkedItem, selectionListener); + mService.showOptionDialogInternal(builder.create()); } } -- cgit v1.2.3-83-g751a From 8fbf29e2d54027a17993cd0d4ad486e3454b56f6 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Fri, 28 Oct 2011 13:31:31 +0900 Subject: Make some private method static Change-Id: Ia23765268be0ef89d7fe7c3f5372ed32d6615765 --- .../compat/InputMethodManagerCompatWrapper.java | 3 +-- java/src/com/android/inputmethod/keyboard/Key.java | 2 +- .../android/inputmethod/keyboard/internal/KeyStyles.java | 2 +- .../com/android/inputmethod/latin/AutoCorrection.java | 2 +- java/src/com/android/inputmethod/latin/LatinIME.java | 16 ++++++---------- java/src/com/android/inputmethod/latin/Suggest.java | 5 +++-- .../android/inputmethod/latin/UserBigramDictionary.java | 8 ++++---- .../android/inputmethod/latin/UserUnigramDictionary.java | 4 ++-- java/src/com/android/inputmethod/latin/Utils.java | 4 ++-- java/src/com/android/inputmethod/latin/WordComposer.java | 2 +- .../latin/spellcheck/AndroidSpellCheckerService.java | 2 +- 11 files changed, 23 insertions(+), 27 deletions(-) (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java index 51dc4cd37..0e5f8c80a 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -153,8 +153,7 @@ public class InputMethodManagerCompatWrapper { return Utils.getInputMethodInfo(this, mLatinImePackageName); } - @SuppressWarnings("unused") - private InputMethodSubtypeCompatWrapper getLastResortSubtype(String mode) { + private static InputMethodSubtypeCompatWrapper getLastResortSubtype(String mode) { if (VOICE_MODE.equals(mode) && !FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) return null; Locale inputLocale = SubtypeSwitcher.getInstance().getInputLocale(); diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index f1ae0b313..f2014b771 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -223,7 +223,7 @@ public class Key { if (style == null) throw new ParseException("Unknown key style: " + styleName, parser); } else { - style = keyStyles.getEmptyKeyStyle(); + style = KeyStyles.getEmptyKeyStyle(); } final float keyXPos = row.getKeyX(keyAttr); diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java index b385b7a04..39fb521ea 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java @@ -235,7 +235,7 @@ public class KeyStyles { return mStyles.get(styleName); } - public KeyStyle getEmptyKeyStyle() { + public static KeyStyle getEmptyKeyStyle() { return EMPTY_KEY_STYLE; } } diff --git a/java/src/com/android/inputmethod/latin/AutoCorrection.java b/java/src/com/android/inputmethod/latin/AutoCorrection.java index 485ec511f..cd066a3d1 100644 --- a/java/src/com/android/inputmethod/latin/AutoCorrection.java +++ b/java/src/com/android/inputmethod/latin/AutoCorrection.java @@ -98,7 +98,7 @@ public class AutoCorrection { return whiteListedWord != null; } - private boolean hasAutoCorrectionForTypedWord(Map dictionaries, + private static boolean hasAutoCorrectionForTypedWord(Map dictionaries, WordComposer wordComposer, ArrayList suggestions, CharSequence typedWord, int correctionMode) { if (TextUtils.isEmpty(typedWord)) return false; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 1666fc191..70e0a1852 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1178,7 +1178,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } // "ic" must not be null - private void maybeRemovePreviousPeriod(final InputConnection ic, CharSequence text) { + private static void maybeRemovePreviousPeriod(final InputConnection ic, CharSequence text) { // When the text's first character is '.', remove the previous period // if there is one. final CharSequence lastOne = ic.getTextBeforeCursor(1, 0); @@ -1190,7 +1190,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } // "ic" may be null - private void removeTrailingSpaceWhileInBatchEdit(final InputConnection ic) { + private static void removeTrailingSpaceWhileInBatchEdit(final InputConnection ic) { if (ic == null) return; final CharSequence lastOne = ic.getTextBeforeCursor(1, 0); if (lastOne != null && lastOne.length() == 1 @@ -1208,12 +1208,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return true; } - private boolean isAlphabet(int code) { - if (Character.isLetter(code)) { - return true; - } else { - return false; - } + private static boolean isAlphabet(int code) { + return Character.isLetter(code); } private void onSettingsKeyPressed() { @@ -2075,7 +2071,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } // "ic" must not be null - private boolean sameAsTextBeforeCursor(final InputConnection ic, CharSequence text) { + private static boolean sameAsTextBeforeCursor(final InputConnection ic, CharSequence text) { CharSequence beforeText = ic.getTextBeforeCursor(text.length(), 0); return TextUtils.equals(text, beforeText); } @@ -2129,7 +2125,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return true; } - private boolean revertSwapPunctuation(final InputConnection ic) { + private static boolean revertSwapPunctuation(final InputConnection ic) { // Here we test whether we indeed have a space and something else before us. This should not // be needed, but it's there just in case something went wrong. final CharSequence textBeforeCursor = ic.getTextBeforeCursor(2, 0); diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index caa5aac51..97e91745c 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -144,7 +144,7 @@ public class Suggest implements Dictionary.WordCallback { initWhitelistAndAutocorrectAndPool(context, locale); } - private void addOrReplaceDictionary(Map dictionaries, String key, + private static void addOrReplaceDictionary(Map dictionaries, String key, Dictionary dict) { final Dictionary oldDict = (dict == null) ? dictionaries.remove(key) @@ -518,7 +518,8 @@ public class Suggest implements Dictionary.WordCallback { return -1; } - private void collectGarbage(ArrayList suggestions, int prefMaxSuggestions) { + private static void collectGarbage(ArrayList suggestions, + int prefMaxSuggestions) { int poolSize = StringBuilderPool.getSize(); int garbageSize = suggestions.size(); while (poolSize < prefMaxSuggestions && garbageSize > 0) { diff --git a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java index 9e656675e..3a1af9311 100644 --- a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java @@ -238,7 +238,7 @@ public class UserBigramDictionary extends ExpandableDictionary { /** * Query the database */ - private Cursor query(String selection, String[] selectionArgs) { + private static Cursor query(String selection, String[] selectionArgs) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); // main INNER JOIN frequency ON (main._id=freq.pair_id) @@ -310,7 +310,7 @@ public class UserBigramDictionary extends ExpandableDictionary { } /** Prune any old data if the database is getting too big. */ - private void checkPruneData(SQLiteDatabase db) { + private static void checkPruneData(SQLiteDatabase db) { db.execSQL("PRAGMA foreign_keys = ON;"); Cursor c = db.query(FREQ_TABLE_NAME, new String[] { FREQ_COLUMN_PAIR_ID }, null, null, null, null, null); @@ -380,7 +380,7 @@ public class UserBigramDictionary extends ExpandableDictionary { return null; } - private ContentValues getContentValues(String word1, String word2, String locale) { + private static ContentValues getContentValues(String word1, String word2, String locale) { ContentValues values = new ContentValues(3); values.put(MAIN_COLUMN_WORD1, word1); values.put(MAIN_COLUMN_WORD2, word2); @@ -388,7 +388,7 @@ public class UserBigramDictionary extends ExpandableDictionary { return values; } - private ContentValues getFrequencyContentValues(int pairId, int frequency) { + private static ContentValues getFrequencyContentValues(int pairId, int frequency) { ContentValues values = new ContentValues(2); values.put(FREQ_COLUMN_PAIR_ID, pairId); values.put(FREQ_COLUMN_FREQUENCY, frequency); diff --git a/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java b/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java index e41230b3c..de7cb5716 100644 --- a/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java @@ -206,7 +206,7 @@ public class UserUnigramDictionary extends ExpandableDictionary { } } - private Cursor query(String selection, String[] selectionArgs) { + private static Cursor query(String selection, String[] selectionArgs) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); qb.setTables(USER_UNIGRAM_DICT_TABLE_NAME); qb.setProjectionMap(sDictProjectionMap); @@ -251,7 +251,7 @@ public class UserUnigramDictionary extends ExpandableDictionary { return null; } - private ContentValues getContentValues(String word, int frequency, String locale) { + private static ContentValues getContentValues(String word, int frequency, String locale) { ContentValues values = new ContentValues(4); values.put(COLUMN_WORD, word); values.put(COLUMN_FREQUENCY, frequency); diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index b29ff1975..3d0aa09f1 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -242,7 +242,7 @@ public class Utils { UsabilityStudyLogUtils.getInstance().init(context); return sRingCharBuffer; } - private int normalize(int in) { + private static int normalize(int in) { int ret = in % BUFSIZE; return ret < 0 ? ret + BUFSIZE : ret; } @@ -465,7 +465,7 @@ public class Utils { } } - public void writeBackSpace() { + public static void writeBackSpace() { UsabilityStudyLogUtils.getInstance().write("\t0\t0"); } diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index adc5637f6..7f3a54244 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -135,7 +135,7 @@ public class WordComposer { * @param primaryCode the preferred character * @param codes array of codes based on distance from touch point */ - private void correctPrimaryJuxtapos(int primaryCode, int[] codes) { + private static void correctPrimaryJuxtapos(int primaryCode, int[] codes) { if (codes.length < 2) return; if (codes[0] > 0 && codes[1] > 0 && codes[0] != primaryCode && codes[1] == primaryCode) { codes[1] = codes[0]; diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index 095c2c51c..5d296f892 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -368,7 +368,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService { * @param text the string to evaluate. * @return true if we should filter this text out, false otherwise */ - private boolean shouldFilterOut(final String text) { + private static boolean shouldFilterOut(final String text) { if (TextUtils.isEmpty(text) || text.length() <= 1) return true; // TODO: check if an equivalent processing can't be done more quickly with a -- cgit v1.2.3-83-g751a From 2d25ba27506fe209c63b4d7b7059d1c2525e231a Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Fri, 2 Mar 2012 22:40:51 +0900 Subject: Omit InputMethodManagerCompatWrapper argument from some utility methods Change-Id: Ic837018c702c8c575de3e5e81fe8e31fee16fe22 --- .../inputmethod/compat/InputMethodManagerCompatWrapper.java | 5 ++--- java/src/com/android/inputmethod/latin/LatinIME.java | 2 +- java/src/com/android/inputmethod/latin/Settings.java | 7 +++---- java/src/com/android/inputmethod/latin/Utils.java | 12 ++++++++---- 4 files changed, 14 insertions(+), 12 deletions(-) (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java index 0e5f8c80a..7e216e5c8 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -150,7 +150,7 @@ public class InputMethodManagerCompatWrapper { private InputMethodInfoCompatWrapper getLatinImeInputMethodInfo() { if (TextUtils.isEmpty(mLatinImePackageName)) return null; - return Utils.getInputMethodInfo(this, mLatinImePackageName); + return Utils.getInputMethodInfo(mLatinImePackageName); } private static InputMethodSubtypeCompatWrapper getLastResortSubtype(String mode) { @@ -239,8 +239,7 @@ public class InputMethodManagerCompatWrapper { // The code below are based on {@link InputMethodManager#showInputMethodMenuInternal}. - final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo( - this, mLatinImePackageName); + final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo(mLatinImePackageName); final List myImsList = getEnabledInputMethodSubtypeList( myImi, true); final InputMethodSubtypeCompatWrapper currentIms = getCurrentInputMethodSubtype(); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 211b69a44..481850f60 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -2419,7 +2419,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar switch (position) { case 0: Intent intent = CompatUtils.getInputLanguageSelectionIntent( - Utils.getInputMethodId(mImm, getPackageName()), + Utils.getInputMethodId(getPackageName()), Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP); diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index dfcb6450e..3029057be 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -329,10 +329,9 @@ public class Settings extends InputMethodSettingsActivity @Override public boolean onPreferenceClick(Preference pref) { if (pref == mInputLanguageSelection) { - startActivity(CompatUtils.getInputLanguageSelectionIntent( - Utils.getInputMethodId( - InputMethodManagerCompatWrapper.getInstance(), - getActivityInternal().getApplicationInfo().packageName), 0)); + final String imeId = Utils.getInputMethodId( + getActivityInternal().getApplicationInfo().packageName); + startActivity(CompatUtils.getInputLanguageSelectionIntent(imeId, 0)); return true; } return false; diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index 47ea9ee8a..a77e4b86b 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -171,12 +171,16 @@ public class Utils { return keyboardCount > 1; } - public static String getInputMethodId(InputMethodManagerCompatWrapper imm, String packageName) { - return getInputMethodInfo(imm, packageName).getId(); + public static String getInputMethodId(String packageName) { + return getInputMethodInfo(packageName).getId(); } - public static InputMethodInfoCompatWrapper getInputMethodInfo( - InputMethodManagerCompatWrapper imm, String packageName) { + public static InputMethodInfoCompatWrapper getInputMethodInfo(String packageName) { + final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); + if (imm == null) { + throw new RuntimeException("Input method manager not found"); + } + for (final InputMethodInfoCompatWrapper imi : imm.getEnabledInputMethodList()) { if (imi.getPackageName().equals(packageName)) return imi; -- cgit v1.2.3-83-g751a From 81d4e3cd66a9388c47c7dba55240ddf849b31934 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Fri, 17 Feb 2012 17:46:01 -0800 Subject: Add language switch key only to the phone layouts Bug: 5759092 Change-Id: Ic7d7d4812976654c0e85fecabd1128eadfc52c5c --- .../drawable-hdpi/sym_keyboard_language_switch.png | Bin 0 -> 2093 bytes .../drawable-mdpi/sym_keyboard_language_switch.png | Bin 0 -> 1290 bytes java/res/values/attrs.xml | 3 ++ java/res/values/keyboard-icons-black.xml | 2 ++ java/res/values/keyboard-icons-ics.xml | 1 + java/res/values/keyboard-icons-white.xml | 1 + java/res/values/keycodes.xml | 3 +- java/res/values/strings.xml | 7 ++++ java/res/xml/key_styles_common.xml | 8 ++--- java/res/xml/prefs.xml | 11 ++++++ java/res/xml/row_qwerty4.xml | 20 +++++++++-- .../compat/InputMethodManagerCompatWrapper.java | 21 +++++++++++ .../com/android/inputmethod/keyboard/Keyboard.java | 15 +++++--- .../android/inputmethod/keyboard/KeyboardId.java | 9 +++-- .../android/inputmethod/keyboard/KeyboardSet.java | 7 ++-- .../inputmethod/keyboard/KeyboardSwitcher.java | 3 +- .../inputmethod/keyboard/LatinKeyboardView.java | 7 +++- .../keyboard/internal/KeyboardIconsSet.java | 3 +- .../com/android/inputmethod/latin/LatinIME.java | 27 ++++++++++++++ .../com/android/inputmethod/latin/Settings.java | 16 ++++++++- .../android/inputmethod/latin/SettingsValues.java | 24 +++++++++++++ java/src/com/android/inputmethod/latin/Utils.java | 39 ++++++++++++++++++++- 22 files changed, 206 insertions(+), 21 deletions(-) create mode 100644 java/res/drawable-hdpi/sym_keyboard_language_switch.png create mode 100644 java/res/drawable-mdpi/sym_keyboard_language_switch.png (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/res/drawable-hdpi/sym_keyboard_language_switch.png b/java/res/drawable-hdpi/sym_keyboard_language_switch.png new file mode 100644 index 000000000..fa747642d Binary files /dev/null and b/java/res/drawable-hdpi/sym_keyboard_language_switch.png differ diff --git a/java/res/drawable-mdpi/sym_keyboard_language_switch.png b/java/res/drawable-mdpi/sym_keyboard_language_switch.png new file mode 100644 index 000000000..f30c1b640 Binary files /dev/null and b/java/res/drawable-mdpi/sym_keyboard_language_switch.png differ diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml index a5d590e04..775807420 100644 --- a/java/res/values/attrs.xml +++ b/java/res/values/attrs.xml @@ -216,6 +216,7 @@ + @@ -296,6 +297,7 @@ + @@ -361,6 +363,7 @@ + diff --git a/java/res/values/keyboard-icons-black.xml b/java/res/values/keyboard-icons-black.xml index 1c5a5f720..44fc2b9c1 100644 --- a/java/res/values/keyboard-icons-black.xml +++ b/java/res/values/keyboard-icons-black.xml @@ -34,5 +34,7 @@ @drawable/sym_bkeyboard_shift_locked @drawable/sym_bkeyboard_voice_off @drawable/sym_keyboard_feedback_tab + + @drawable/sym_keyboard_language_switch diff --git a/java/res/values/keyboard-icons-ics.xml b/java/res/values/keyboard-icons-ics.xml index f68be5f1e..5fba0253d 100644 --- a/java/res/values/keyboard-icons-ics.xml +++ b/java/res/values/keyboard-icons-ics.xml @@ -33,5 +33,6 @@ @drawable/sym_keyboard_shift_locked_holo @drawable/sym_keyboard_voice_off_holo @drawable/sym_keyboard_feedback_tab + @drawable/sym_keyboard_language_switch diff --git a/java/res/values/keyboard-icons-white.xml b/java/res/values/keyboard-icons-white.xml index 35197a1c0..837b1a37a 100644 --- a/java/res/values/keyboard-icons-white.xml +++ b/java/res/values/keyboard-icons-white.xml @@ -31,5 +31,6 @@ @drawable/sym_keyboard_voice_off_holo @drawable/sym_keyboard_feedback_tab + @drawable/sym_keyboard_language_switch diff --git a/java/res/values/keycodes.xml b/java/res/values/keycodes.xml index 7f9e4bda4..d3d9b6324 100644 --- a/java/res/values/keycodes.xml +++ b/java/res/values/keycodes.xml @@ -32,5 +32,6 @@ -7 -8 -9 - -10 + -10 + -11 diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml index d8a3a689e..f2c02d014 100644 --- a/java/res/values/strings.xml +++ b/java/res/values/strings.xml @@ -64,6 +64,13 @@ Options for experts + + Switch to other input methods + + Language switch key covers other input methods too + + Suppress language switch key + Key popup dismiss delay diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml index 76eacb673..f153a7d96 100644 --- a/java/res/xml/key_styles_common.xml +++ b/java/res/xml/key_styles_common.xml @@ -117,10 +117,10 @@ latin:altCode="@integer/key_space" latin:parentStyle="f1MoreKeysStyle" /> + + - + + + + + + + + + + getEnabledInputMethodSubtypeList( InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) { if (!SUBTYPE_SUPPORTED) { @@ -221,6 +234,14 @@ public class InputMethodManagerCompatWrapper { return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToLastInputMethod, token); } + public boolean switchToNextInputMethod(IBinder token, boolean onlyCurrentIme) { + if (SubtypeSwitcher.getInstance().isDummyVoiceMode()) { + return true; + } + return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToNextInputMethod, token, + onlyCurrentIme); + } + public List getEnabledInputMethodList() { if (mImm == null) return null; List imis = new ArrayList(); diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index c6cdf7986..5660d1942 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -99,8 +99,9 @@ public class Keyboard { public static final int CODE_ACTION_ENTER = -7; public static final int CODE_ACTION_NEXT = -8; public static final int CODE_ACTION_PREVIOUS = -9; + public static final int CODE_LANGUAGE_SWITCH = -10; // Code value representing the code is not specified. - public static final int CODE_UNSPECIFIED = -10; + public static final int CODE_UNSPECIFIED = -11; public final KeyboardId mId; public final int mThemeId; @@ -1076,6 +1077,9 @@ public class Keyboard { R.styleable.Keyboard_Case_shortcutKeyEnabled, id.mShortcutKeyEnabled); final boolean hasShortcutKeyMatched = matchBoolean(a, R.styleable.Keyboard_Case_hasShortcutKey, id.mHasShortcutKey); + final boolean languageSwitchKeyEnabledMatched = matchBoolean(a, + R.styleable.Keyboard_Case_languageSwitchKeyEnabled, + id.mLanguageSwitchKeyEnabled); final boolean isMultiLineMatched = matchBoolean(a, R.styleable.Keyboard_Case_isMultiLine, id.isMultiLine()); final boolean imeActionMatched = matchInteger(a, @@ -1089,11 +1093,12 @@ public class Keyboard { final boolean selected = keyboardSetElementMatched && modeMatched && navigateNextMatched && navigatePreviousMatched && passwordInputMatched && clobberSettingsKeyMatched && shortcutKeyEnabledMatched - && hasShortcutKeyMatched && isMultiLineMatched && imeActionMatched - && localeCodeMatched && languageCodeMatched && countryCodeMatched; + && hasShortcutKeyMatched && languageSwitchKeyEnabledMatched + && isMultiLineMatched && imeActionMatched && localeCodeMatched + && languageCodeMatched && countryCodeMatched; if (DEBUG) { - startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE, + startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE, textAttr(a.getString(R.styleable.Keyboard_Case_keyboardSetElement), "keyboardSetElement"), textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"), @@ -1111,6 +1116,8 @@ public class Keyboard { "shortcutKeyEnabled"), booleanAttr(a, R.styleable.Keyboard_Case_hasShortcutKey, "hasShortcutKey"), + booleanAttr(a, R.styleable.Keyboard_Case_languageSwitchKeyEnabled, + "languageSwitchKeyEnabled"), booleanAttr(a, R.styleable.Keyboard_Case_isMultiLine, "isMultiLine"), textAttr(a.getString(R.styleable.Keyboard_Case_localeCode), diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java index f5752962e..6703b9301 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java @@ -62,13 +62,14 @@ public class KeyboardId { public final boolean mClobberSettingsKey; public final boolean mShortcutKeyEnabled; public final boolean mHasShortcutKey; + public final boolean mLanguageSwitchKeyEnabled; public final String mCustomActionLabel; private final int mHashCode; public KeyboardId(int elementId, Locale locale, int orientation, int width, int mode, EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled, - boolean hasShortcutKey) { + boolean hasShortcutKey, boolean languageSwitchKeyEnabled) { this.mLocale = locale; this.mOrientation = orientation; this.mWidth = width; @@ -78,6 +79,7 @@ public class KeyboardId { this.mClobberSettingsKey = clobberSettingsKey; this.mShortcutKeyEnabled = shortcutKeyEnabled; this.mHasShortcutKey = hasShortcutKey; + this.mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled; this.mCustomActionLabel = (editorInfo.actionLabel != null) ? editorInfo.actionLabel.toString() : null; @@ -94,6 +96,7 @@ public class KeyboardId { id.mClobberSettingsKey, id.mShortcutKeyEnabled, id.mHasShortcutKey, + id.mLanguageSwitchKeyEnabled, id.isMultiLine(), id.imeAction(), id.mCustomActionLabel, @@ -114,6 +117,7 @@ public class KeyboardId { && other.mClobberSettingsKey == this.mClobberSettingsKey && other.mShortcutKeyEnabled == this.mShortcutKeyEnabled && other.mHasShortcutKey == this.mHasShortcutKey + && other.mLanguageSwitchKeyEnabled == this.mLanguageSwitchKeyEnabled && other.isMultiLine() == this.isMultiLine() && other.imeAction() == this.imeAction() && TextUtils.equals(other.mCustomActionLabel, this.mCustomActionLabel) @@ -172,7 +176,7 @@ public class KeyboardId { @Override public String toString() { - return String.format("[%s %s %s%d %s %s %s%s%s%s%s%s%s]", + return String.format("[%s %s %s%d %s %s %s%s%s%s%s%s%s%s]", elementIdToName(mElementId), mLocale, (mOrientation == 1 ? "port" : "land"), mWidth, @@ -184,6 +188,7 @@ public class KeyboardId { (passwordInput() ? " passwordInput" : ""), (mShortcutKeyEnabled ? " shortcutKeyEnabled" : ""), (mHasShortcutKey ? " hasShortcutKey" : ""), + (mLanguageSwitchKeyEnabled ? " languageSwitchKeyEnabled" : ""), (isMultiLine() ? "isMultiLine" : "") ); } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java index ee882edc0..731aaf7c5 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java @@ -101,6 +101,7 @@ public class KeyboardSet { boolean mVoiceKeyEnabled; boolean mVoiceKeyOnMain; boolean mNoSettingsKey; + boolean mLanguageSwitchKeyEnabled; Locale mLocale; int mOrientation; int mWidth; @@ -196,7 +197,7 @@ public class KeyboardSet { && (isSymbols != params.mVoiceKeyOnMain); return new KeyboardId(keyboardSetElementId, params.mLocale, params.mOrientation, params.mWidth, params.mMode, params.mEditorInfo, params.mNoSettingsKey, - params.mVoiceKeyEnabled, hasShortcutKey); + params.mVoiceKeyEnabled, hasShortcutKey, params.mLanguageSwitchKeyEnabled); } public static class Builder { @@ -239,7 +240,8 @@ public class KeyboardSet { return this; } - public Builder setOptions(boolean voiceKeyEnabled, boolean voiceKeyOnMain) { + public Builder setOptions(boolean voiceKeyEnabled, boolean voiceKeyOnMain, + boolean languageSwitchKeyEnabled) { @SuppressWarnings("deprecation") final boolean deprecatedNoMicrophone = Utils.inPrivateImeOptions( null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, mEditorInfo); @@ -248,6 +250,7 @@ public class KeyboardSet { || deprecatedNoMicrophone; mParams.mVoiceKeyEnabled = voiceKeyEnabled && !noMicrophone; mParams.mVoiceKeyOnMain = voiceKeyOnMain; + mParams.mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled; return this; } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index e1c6f2604..ac8dd1b95 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -133,7 +133,8 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, LatinIME.SUBTYPE_EXTRA_VALUE_SUPPORT_TOUCH_POSITION_CORRECTION)); builder.setOptions( settingsValues.isVoiceKeyEnabled(editorInfo), - settingsValues.isVoiceKeyOnMain()); + settingsValues.isVoiceKeyOnMain(), + settingsValues.isLanguageSwitchKeyEnabled(mThemeContext)); mKeyboardSet = builder.build(); try { mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols)); diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 78c371ff0..afc4932e9 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -489,7 +489,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke KeyboardSwitcher.getInstance().hapticAndAudioFeedback(primaryCode); return true; } - if (primaryCode == Keyboard.CODE_SPACE) { + if (primaryCode == Keyboard.CODE_SPACE || primaryCode == Keyboard.CODE_LANGUAGE_SWITCH) { // Long pressing the space key invokes IME switcher dialog. if (invokeCustomRequest(LatinIME.CODE_SHOW_INPUT_METHOD_PICKER)) { tracker.onLongPressed(); @@ -782,6 +782,11 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke && Utils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) { drawKeyPopupHint(key, canvas, paint, params); } + } else if (key.mCode == Keyboard.CODE_LANGUAGE_SWITCH) { + super.onDrawKeyTopVisuals(key, canvas, paint, params); + if (Utils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) { + drawKeyPopupHint(key, canvas, paint, params); + } } else { super.onDrawKeyTopVisuals(key, canvas, paint, params); } diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java index 7c8fd1225..ca711ec7d 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java @@ -31,7 +31,7 @@ public class KeyboardIconsSet { // The value should be aligned with the enum value of Key.keyIcon. public static final int ICON_UNDEFINED = 0; - private static final int NUM_ICONS = 13; + private static final int NUM_ICONS = 14; private final Drawable[] mIcons = new Drawable[NUM_ICONS + 1]; @@ -57,6 +57,7 @@ public class KeyboardIconsSet { addIconIdMap(11, "shiftKeyShifted", R.styleable.Keyboard_iconShiftKeyShifted); addIconIdMap(12, "disabledShortcurKey", R.styleable.Keyboard_iconDisabledShortcutKey); addIconIdMap(13, "previewTabKey", R.styleable.Keyboard_iconPreviewTabKey); + addIconIdMap(14, "languageSwitchKey", R.styleable.Keyboard_iconLanguageSwitchKey); } private static void addIconIdMap(int iconId, String name, int attrId) { diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 2bcd947f1..cb22b4935 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -29,6 +29,7 @@ import android.inputmethodservice.InputMethodService; import android.media.AudioManager; import android.net.ConnectivityManager; import android.os.Debug; +import android.os.IBinder; import android.os.Message; import android.os.SystemClock; import android.preference.PreferenceActivity; @@ -55,6 +56,7 @@ 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.compat.VibratorCompatWrapper; @@ -196,6 +198,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private KeyboardSwitcher mKeyboardSwitcher; private SubtypeSwitcher mSubtypeSwitcher; private VoiceProxy mVoiceProxy; + private boolean mShouldSwitchToLastSubtype = true; private UserDictionary mUserDictionary; private UserBigramDictionary mUserBigramDictionary; @@ -1263,6 +1266,25 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } + private void handleLanguageSwitchKey() { + final boolean includesOtherImes = !mSettingsValues.mIncludesOtherImesInLanguageSwitchList; + final IBinder token = getWindow().getWindow().getAttributes().token; + if (mShouldSwitchToLastSubtype) { + final InputMethodSubtypeCompatWrapper lastSubtype = mImm.getLastInputMethodSubtype(); + final boolean lastSubtypeBelongsToThisIme = Utils.checkIfSubtypeBelongsToThisIme( + this, lastSubtype); + if ((includesOtherImes || lastSubtypeBelongsToThisIme) + && mImm.switchToLastInputMethod(token)) { + mShouldSwitchToLastSubtype = false; + } else { + mImm.switchToNextInputMethod(token, !includesOtherImes); + mShouldSwitchToLastSubtype = true; + } + } else { + mImm.switchToNextInputMethod(token, !includesOtherImes); + } + } + private void sendKeyCodePoint(int code) { // TODO: Remove this special handling of digit letters. // For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}. @@ -1306,6 +1328,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar handleBackspace(spaceState); mDeleteCount++; mExpectingUpdateSelection = true; + mShouldSwitchToLastSubtype = true; LatinImeLogger.logOnDelete(); break; case Keyboard.CODE_SHIFT: @@ -1327,6 +1350,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar case Keyboard.CODE_ACTION_PREVIOUS: EditorInfoCompatUtils.performEditorActionPrevious(getCurrentInputConnection()); break; + case Keyboard.CODE_LANGUAGE_SWITCH: + handleLanguageSwitchKey(); + break; default: mSpaceState = SPACE_STATE_NONE; if (mSettingsValues.isWordSeparator(primaryCode)) { @@ -1335,6 +1361,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar handleCharacter(primaryCode, x, y, spaceState); } mExpectingUpdateSelection = true; + mShouldSwitchToLastSubtype = true; break; } switcher.onCodeInput(primaryCode); diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index 3029057be..305cef22d 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -43,7 +43,6 @@ import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; import com.android.inputmethod.compat.CompatUtils; -import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; import com.android.inputmethod.compat.VibratorCompatWrapper; import com.android.inputmethod.deprecated.VoiceProxy; @@ -73,6 +72,10 @@ public class Settings extends InputMethodSettingsActivity public static final String PREF_MISC_SETTINGS = "misc_settings"; public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode"; public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings"; + public static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY = + "pref_suppress_language_switch_key"; + public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST = + "pref_include_other_imes_in_language_switch_list"; public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY = "pref_key_preview_popup_dismiss_delay"; public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict"; @@ -204,6 +207,11 @@ public class Settings extends InputMethodSettingsActivity } } + final CheckBoxPreference includeOtherImesInLanguageSwitchList = + (CheckBoxPreference)findPreference(PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST); + includeOtherImesInLanguageSwitchList.setEnabled( + !SettingsValues.isLanguageSwitchKeySupressed(prefs)); + mKeyPreviewPopupDismissDelay = (ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY); final String[] entries = new String[] { @@ -316,6 +324,12 @@ public class Settings extends InputMethodSettingsActivity if (null != popupDismissDelay) { popupDismissDelay.setEnabled(prefs.getBoolean(PREF_POPUP_ON, true)); } + } else if (key.equals(PREF_SUPPRESS_LANGUAGE_SWITCH_KEY)) { + final CheckBoxPreference includeOtherImesInLanguageSwicthList = + (CheckBoxPreference)findPreference( + PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST); + includeOtherImesInLanguageSwicthList.setEnabled( + !SettingsValues.isLanguageSwitchKeySupressed(prefs)); } ensureConsistencyOfAutoCorrectionSettings(); mVoiceOn = !(prefs.getString(PREF_VOICE_MODE, mVoiceModeOff) diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java index 6d65a74c8..69e45f619 100644 --- a/java/src/com/android/inputmethod/latin/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/SettingsValues.java @@ -23,11 +23,14 @@ import android.os.Build; import android.util.Log; import android.view.inputmethod.EditorInfo; +import com.android.inputmethod.compat.InputMethodInfoCompatWrapper; import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.compat.VibratorCompatWrapper; import com.android.inputmethod.keyboard.internal.KeySpecParser; import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.Locale; public class SettingsValues { @@ -55,6 +58,8 @@ public class SettingsValues { public final String mShowSuggestionsSetting; @SuppressWarnings("unused") // TODO: Use this private final boolean mUsabilityStudyMode; + public final boolean mIncludesOtherImesInLanguageSwitchList; + public final boolean mIsLanguageSwitchKeySuppressed; @SuppressWarnings("unused") // TODO: Use this private final String mKeyPreviewPopupDismissDelayRawValue; public final boolean mUseContactsDict; @@ -127,6 +132,9 @@ public class SettingsValues { mShowSuggestionsSetting = prefs.getString(Settings.PREF_SHOW_SUGGESTIONS_SETTING, res.getString(R.string.prefs_suggestion_visibility_default_value)); mUsabilityStudyMode = getUsabilityStudyMode(prefs); + mIncludesOtherImesInLanguageSwitchList = prefs.getBoolean( + Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, false); + mIsLanguageSwitchKeySuppressed = isLanguageSwitchKeySupressed(prefs); mKeyPreviewPopupDismissDelayRawValue = prefs.getString( Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY, Integer.toString(res.getInteger(R.integer.config_key_preview_linger_timeout))); @@ -309,6 +317,22 @@ public class SettingsValues { return mVoiceKeyOnMain; } + public static boolean isLanguageSwitchKeySupressed(SharedPreferences sp) { + return sp.getBoolean(Settings.PREF_SUPPRESS_LANGUAGE_SWITCH_KEY, false); + } + + public boolean isLanguageSwitchKeyEnabled(Context context) { + if (mIsLanguageSwitchKeySuppressed) { + return false; + } + if (mIncludesOtherImesInLanguageSwitchList) { + return Utils.hasMultipleEnabledIMEsOrSubtypes(/* include aux subtypes */false); + } else { + return Utils.hasMultipleEnabledSubtypesInThisIme( + context, /* include aux subtypes */false); + } + } + public boolean isFullscreenModeAllowed(Resources res) { return res.getBoolean(R.bool.config_use_fullscreen_mode); } diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index 33d4b877e..a8679e07a 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -52,6 +52,7 @@ import java.io.PrintWriter; import java.nio.channels.FileChannel; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; @@ -117,16 +118,51 @@ public class Utils { } } + // TODO: Move InputMethodSubtype related utility methods to its own utility class. + // TODO: Cache my InputMethodInfo and/or InputMethodSubtype list. + public static boolean checkIfSubtypeBelongsToThisIme(Context context, + InputMethodSubtypeCompatWrapper ims) { + final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); + if (imm == null) return false; + + final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo( + context.getPackageName()); + final List subtypes = + imm.getEnabledInputMethodSubtypeList(myImi, true); + for (final InputMethodSubtypeCompatWrapper subtype : subtypes) { + if (subtype.equals(ims)) { + return true; + } + } + return false; + } + public static boolean hasMultipleEnabledIMEsOrSubtypes( final boolean shouldIncludeAuxiliarySubtypes) { final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); if (imm == null) return false; + final List enabledImis = imm.getEnabledInputMethodList(); + return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, enabledImis); + } + + public static boolean hasMultipleEnabledSubtypesInThisIme(Context context, + final boolean shouldIncludeAuxiliarySubtypes) { + final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo( + context.getPackageName()); + final List imiList = Collections.singletonList(myImi); + return Utils.hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, imiList); + } + + private static boolean hasMultipleEnabledSubtypes(final boolean shouldIncludeAuxiliarySubtypes, + List imiList) { + final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); + if (imm == null) return false; // Number of the filtered IMEs int filteredImisCount = 0; - for (InputMethodInfoCompatWrapper imi : enabledImis) { + for (InputMethodInfoCompatWrapper imi : imiList) { // We can return true immediately after we find two or more filtered IMEs. if (filteredImisCount > 1) return true; final List subtypes = @@ -564,6 +600,7 @@ public class Utils { } } + // TODO: Move this method to KeyboardSet class. public static int getKeyboardMode(EditorInfo editorInfo) { if (editorInfo == null) return KeyboardId.MODE_TEXT; -- cgit v1.2.3-83-g751a From cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Thu, 8 Mar 2012 17:07:02 +0900 Subject: Split Utils class to StringUtils, SubtypeUtils, and JniUtils Change-Id: I09e91675fe7d573dad8c933ad513b21d7e409144 --- .../compat/InputMethodManagerCompatWrapper.java | 7 +- .../android/inputmethod/deprecated/VoiceProxy.java | 6 +- .../languageswitcher/InputLanguageSelection.java | 24 +- .../deprecated/voice/RecognitionView.java | 10 +- java/src/com/android/inputmethod/keyboard/Key.java | 10 +- .../android/inputmethod/keyboard/KeyboardSet.java | 52 ++- .../android/inputmethod/keyboard/KeyboardView.java | 4 +- .../inputmethod/keyboard/LatinKeyboardView.java | 13 +- .../inputmethod/keyboard/MoreKeysKeyboard.java | 4 +- .../inputmethod/keyboard/ProximityInfo.java | 4 +- .../keyboard/internal/KeySpecParser.java | 12 +- .../inputmethod/latin/BinaryDictionary.java | 2 +- .../inputmethod/latin/DictionaryFactory.java | 14 +- .../com/android/inputmethod/latin/JniUtils.java | 41 +++ .../com/android/inputmethod/latin/LatinIME.java | 23 +- .../com/android/inputmethod/latin/Settings.java | 2 +- .../android/inputmethod/latin/SettingsValues.java | 4 +- .../com/android/inputmethod/latin/StringUtils.java | 198 ++++++++++ .../android/inputmethod/latin/SubtypeSwitcher.java | 2 +- .../android/inputmethod/latin/SubtypeUtils.java | 135 +++++++ .../src/com/android/inputmethod/latin/Suggest.java | 50 ++- java/src/com/android/inputmethod/latin/Utils.java | 398 +-------------------- .../spellcheck/AndroidSpellCheckerService.java | 10 +- 23 files changed, 551 insertions(+), 474 deletions(-) create mode 100644 java/src/com/android/inputmethod/latin/JniUtils.java create mode 100644 java/src/com/android/inputmethod/latin/StringUtils.java create mode 100644 java/src/com/android/inputmethod/latin/SubtypeUtils.java (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java index 9dd0a599d..bf5f20158 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -32,7 +32,7 @@ import android.view.inputmethod.InputMethodManager; import com.android.inputmethod.deprecated.LanguageSwitcherProxy; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SubtypeSwitcher; -import com.android.inputmethod.latin.Utils; +import com.android.inputmethod.latin.SubtypeUtils; import java.lang.reflect.Method; import java.util.ArrayList; @@ -163,7 +163,7 @@ public class InputMethodManagerCompatWrapper { private InputMethodInfoCompatWrapper getLatinImeInputMethodInfo() { if (TextUtils.isEmpty(mLatinImePackageName)) return null; - return Utils.getInputMethodInfo(mLatinImePackageName); + return SubtypeUtils.getInputMethodInfo(mLatinImePackageName); } private static InputMethodSubtypeCompatWrapper getLastResortSubtype(String mode) { @@ -260,7 +260,8 @@ public class InputMethodManagerCompatWrapper { // The code below are based on {@link InputMethodManager#showInputMethodMenuInternal}. - final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo(mLatinImePackageName); + final InputMethodInfoCompatWrapper myImi = SubtypeUtils.getInputMethodInfo( + mLatinImePackageName); final List myImsList = getEnabledInputMethodSubtypeList( myImi, true); final InputMethodSubtypeCompatWrapper currentIms = getCurrentInputMethodSubtype(); diff --git a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java index c1c6d31cd..87d1c118b 100644 --- a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java +++ b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java @@ -61,8 +61,8 @@ import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinIME.UIHandler; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.StringUtils; import com.android.inputmethod.latin.SubtypeSwitcher; -import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.Utils; import java.util.ArrayList; @@ -662,9 +662,9 @@ public class VoiceProxy implements VoiceInput.UiListener { private boolean shouldShowVoiceButton(FieldContext fieldContext, EditorInfo editorInfo) { @SuppressWarnings("deprecation") - final boolean noMic = Utils.inPrivateImeOptions(null, + final boolean noMic = StringUtils.inPrivateImeOptions(null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo) - || Utils.inPrivateImeOptions(mService.getPackageName(), + || StringUtils.inPrivateImeOptions(mService.getPackageName(), LatinIME.IME_OPTION_NO_MICROPHONE, editorInfo); return ENABLE_VOICE_BUTTON && fieldCanDoVoice(fieldContext) && !noMic && SpeechRecognizer.isRecognitionAvailable(mService); diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java index e75e14861..421ee6529 100644 --- a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java +++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java @@ -16,16 +16,6 @@ package com.android.inputmethod.deprecated.languageswitcher; -import com.android.inputmethod.compat.SharedPreferencesCompat; -import com.android.inputmethod.keyboard.KeyboardSet; -import com.android.inputmethod.latin.DictionaryFactory; -import com.android.inputmethod.latin.LocaleUtils; -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.Settings; -import com.android.inputmethod.latin.Utils; - -import org.xmlpull.v1.XmlPullParserException; - import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.res.Resources; @@ -37,6 +27,16 @@ import android.preference.PreferenceManager; import android.text.TextUtils; import android.util.Pair; +import com.android.inputmethod.compat.SharedPreferencesCompat; +import com.android.inputmethod.keyboard.KeyboardSet; +import com.android.inputmethod.latin.DictionaryFactory; +import com.android.inputmethod.latin.LocaleUtils; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.Settings; +import com.android.inputmethod.latin.StringUtils; + +import org.xmlpull.v1.XmlPullParserException; + import java.io.IOException; import java.text.Collator; import java.util.ArrayList; @@ -237,12 +237,12 @@ public class InputLanguageSelection extends PreferenceActivity { if (finalSize == 0) { preprocess[finalSize++] = - new LocaleEntry(Utils.getFullDisplayName(l, false), l); + new LocaleEntry(StringUtils.getFullDisplayName(l, false), l); } else { if (s.equals("zz_ZZ")) { // ignore this locale } else { - final String displayName = Utils.getFullDisplayName(l, false); + final String displayName = StringUtils.getFullDisplayName(l, false); preprocess[finalSize++] = new LocaleEntry(displayName, l); } } diff --git a/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java b/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java index 71d15dc3d..ff8b1abce 100644 --- a/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java +++ b/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java @@ -16,10 +16,6 @@ package com.android.inputmethod.deprecated.voice; -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.SubtypeSwitcher; -import com.android.inputmethod.latin.Utils; - import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; @@ -39,6 +35,10 @@ import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.StringUtils; +import com.android.inputmethod.latin.SubtypeSwitcher; + import java.io.ByteArrayOutputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -222,7 +222,7 @@ public class RecognitionView { Locale locale = SubtypeSwitcher.getInstance().getInputLocale(); mLanguage.setVisibility(View.VISIBLE); - mLanguage.setText(Utils.getFullDisplayName(locale, true)); + mLanguage.setText(StringUtils.getFullDisplayName(locale, true)); mPopupLayout.setBackgroundDrawable(mListeningBorder); break; diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index f3923834b..6b4de184f 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -30,7 +30,7 @@ import com.android.inputmethod.keyboard.internal.KeyStyles; import com.android.inputmethod.keyboard.internal.KeyStyles.KeyStyle; import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.Utils; +import com.android.inputmethod.latin.StringUtils; import com.android.inputmethod.latin.XmlParseUtils; import org.xmlpull.v1.XmlPullParser; @@ -293,7 +293,7 @@ public class Key { // Choose the first letter of the label as primary code if not specified. if (code == Keyboard.CODE_UNSPECIFIED && TextUtils.isEmpty(outputText) && !TextUtils.isEmpty(mLabel)) { - if (Utils.codePointCount(mLabel) == 1) { + if (StringUtils.codePointCount(mLabel) == 1) { // Use the first letter of the hint label if shiftedLetterActivated flag is // specified. if (hasShiftedLetterHint() && isShiftedLetterActivated() @@ -309,7 +309,7 @@ public class Key { mCode = Keyboard.CODE_OUTPUT_TEXT; } } else if (code == Keyboard.CODE_UNSPECIFIED && outputText != null) { - if (Utils.codePointCount(outputText) == 1) { + if (StringUtils.codePointCount(outputText) == 1) { mCode = outputText.codePointAt(0); outputText = null; } else { @@ -336,7 +336,7 @@ public class Key { if (!Keyboard.isLetterCode(code) || preserveCase) return code; final String text = new String(new int[] { code } , 0, 1); final String casedText = adjustCaseOfStringForKeyboardId(text, preserveCase, id); - return Utils.codePointCount(casedText) == 1 + return StringUtils.codePointCount(casedText) == 1 ? casedText.codePointAt(0) : Keyboard.CODE_UNSPECIFIED; } @@ -484,7 +484,7 @@ public class Key { } public int selectTextSize(int letter, int largeLetter, int label, int hintLabel) { - if (Utils.codePointCount(mLabel) > 1 + if (StringUtils.codePointCount(mLabel) > 1 && (mLabelFlags & (LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO | LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO)) == 0) { return label; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java index 731aaf7c5..5ac6d03a8 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java @@ -21,16 +21,18 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; +import android.text.InputType; import android.util.Log; import android.util.Xml; import android.view.inputmethod.EditorInfo; import com.android.inputmethod.compat.EditorInfoCompatUtils; +import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.LocaleUtils; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.Utils; +import com.android.inputmethod.latin.StringUtils; import com.android.inputmethod.latin.XmlParseUtils; import org.xmlpull.v1.XmlPullParser; @@ -215,9 +217,9 @@ public class KeyboardSet { mEditorInfo = editorInfo; final Params params = mParams; - params.mMode = Utils.getKeyboardMode(editorInfo); + params.mMode = getKeyboardMode(editorInfo); params.mEditorInfo = (editorInfo != null) ? editorInfo : EMPTY_EDITOR_INFO; - params.mNoSettingsKey = Utils.inPrivateImeOptions( + params.mNoSettingsKey = StringUtils.inPrivateImeOptions( mPackageName, LatinIME.IME_OPTION_NO_SETTINGS_KEY, mEditorInfo); } @@ -230,7 +232,7 @@ public class KeyboardSet { // TODO: Use InputMethodSubtype object as argument. public Builder setSubtype(Locale inputLocale, boolean asciiCapable, boolean touchPositionCorrectionEnabled) { - final boolean deprecatedForceAscii = Utils.inPrivateImeOptions( + final boolean deprecatedForceAscii = StringUtils.inPrivateImeOptions( mPackageName, LatinIME.IME_OPTION_FORCE_ASCII, mEditorInfo); final boolean forceAscii = EditorInfoCompatUtils.hasFlagForceAscii( mParams.mEditorInfo.imeOptions) @@ -243,9 +245,9 @@ public class KeyboardSet { public Builder setOptions(boolean voiceKeyEnabled, boolean voiceKeyOnMain, boolean languageSwitchKeyEnabled) { @SuppressWarnings("deprecation") - final boolean deprecatedNoMicrophone = Utils.inPrivateImeOptions( + final boolean deprecatedNoMicrophone = StringUtils.inPrivateImeOptions( null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, mEditorInfo); - final boolean noMicrophone = Utils.inPrivateImeOptions( + final boolean noMicrophone = StringUtils.inPrivateImeOptions( mPackageName, LatinIME.IME_OPTION_NO_MICROPHONE, mEditorInfo) || deprecatedNoMicrophone; mParams.mVoiceKeyEnabled = voiceKeyEnabled && !noMicrophone; @@ -337,6 +339,44 @@ public class KeyboardSet { a.recycle(); } } + + private static int getKeyboardMode(EditorInfo editorInfo) { + if (editorInfo == null) + return KeyboardId.MODE_TEXT; + + final int inputType = editorInfo.inputType; + final int variation = inputType & InputType.TYPE_MASK_VARIATION; + + switch (inputType & InputType.TYPE_MASK_CLASS) { + case InputType.TYPE_CLASS_NUMBER: + return KeyboardId.MODE_NUMBER; + case InputType.TYPE_CLASS_DATETIME: + switch (variation) { + case InputType.TYPE_DATETIME_VARIATION_DATE: + return KeyboardId.MODE_DATE; + case InputType.TYPE_DATETIME_VARIATION_TIME: + return KeyboardId.MODE_TIME; + default: // InputType.TYPE_DATETIME_VARIATION_NORMAL + return KeyboardId.MODE_DATETIME; + } + case InputType.TYPE_CLASS_PHONE: + return KeyboardId.MODE_PHONE; + case InputType.TYPE_CLASS_TEXT: + if (InputTypeCompatUtils.isEmailVariation(variation)) { + return KeyboardId.MODE_EMAIL; + } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) { + return KeyboardId.MODE_URL; + } else if (variation == InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { + return KeyboardId.MODE_IM; + } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) { + return KeyboardId.MODE_TEXT; + } else { + return KeyboardId.MODE_TEXT; + } + default: + return KeyboardId.MODE_TEXT; + } + } } public static String parseKeyboardLocale(Resources res, int resId) diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index 78e0ee230..decd73d45 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -41,7 +41,7 @@ import com.android.inputmethod.compat.FrameLayoutCompatUtils; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StaticInnerHandlerWrapper; -import com.android.inputmethod.latin.Utils; +import com.android.inputmethod.latin.StringUtils; import java.util.HashMap; @@ -853,7 +853,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { if (key.mLabel != null) { // TODO Should take care of temporaryShiftLabel here. previewText.setCompoundDrawables(null, null, null, null); - if (Utils.codePointCount(key.mLabel) > 1) { + if (StringUtils.codePointCount(key.mLabel) > 1) { previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mKeyLetterSize); previewText.setTypeface(Typeface.DEFAULT_BOLD); } else { diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index afc4932e9..0a0307500 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -46,6 +46,8 @@ import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StaticInnerHandlerWrapper; +import com.android.inputmethod.latin.StringUtils; +import com.android.inputmethod.latin.SubtypeUtils; import com.android.inputmethod.latin.Utils; import com.android.inputmethod.latin.Utils.UsabilityStudyLogUtils; @@ -779,12 +781,13 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke // Whether space key needs to show the "..." popup hint for special purposes if (mIsSpacebarTriggeringPopupByLongPress - && Utils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) { + && SubtypeUtils.hasMultipleEnabledIMEsOrSubtypes( + true /* include aux subtypes */)) { drawKeyPopupHint(key, canvas, paint, params); } } else if (key.mCode == Keyboard.CODE_LANGUAGE_SWITCH) { super.onDrawKeyTopVisuals(key, canvas, paint, params); - if (Utils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) { + if (SubtypeUtils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) { drawKeyPopupHint(key, canvas, paint, params); } } else { @@ -810,7 +813,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke paint.setTextAlign(Align.CENTER); paint.setTypeface(Typeface.DEFAULT); // Estimate appropriate language name text size to fit in maxTextWidth. - String language = Utils.getFullDisplayName(locale, true); + String language = StringUtils.getFullDisplayName(locale, true); int textWidth = getTextWidth(paint, language, origTextSize); // Assuming text width and text size are proportional to each other. float textSize = origTextSize * Math.min(width / textWidth, 1.0f); @@ -822,7 +825,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke final boolean useShortName; if (useMiddleName) { - language = Utils.getMiddleDisplayLanguage(locale); + language = StringUtils.getMiddleDisplayLanguage(locale); textWidth = getTextWidth(paint, language, origTextSize); textSize = origTextSize * Math.min(width / textWidth, 1.0f); useShortName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME) @@ -832,7 +835,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke } if (useShortName) { - language = Utils.getShortDisplayLanguage(locale); + language = StringUtils.getShortDisplayLanguage(locale); textWidth = getTextWidth(paint, language, origTextSize); textSize = origTextSize * Math.min(width / textWidth, 1.0f); } diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java index 9f735cff7..904a81de4 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java @@ -22,7 +22,7 @@ import android.graphics.drawable.Drawable; import com.android.inputmethod.keyboard.internal.KeySpecParser; import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.Utils; +import com.android.inputmethod.latin.StringUtils; public class MoreKeysKeyboard extends Keyboard { private final int mDefaultKeyCoordX; @@ -301,7 +301,7 @@ public class MoreKeysKeyboard extends Keyboard { for (String moreKeySpec : parentKey.mMoreKeys) { final String label = KeySpecParser.getLabel(moreKeySpec); // If the label is single letter, minKeyWidth is enough to hold the label. - if (label != null && Utils.codePointCount(label) > 1) { + if (label != null && StringUtils.codePointCount(label) > 1) { if (paint == null) { paint = new Paint(); paint.setAntiAlias(true); diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java index f96f71e8a..582509324 100644 --- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java @@ -19,7 +19,7 @@ package com.android.inputmethod.keyboard; import android.graphics.Rect; import com.android.inputmethod.keyboard.Keyboard.Params.TouchPositionCorrection; -import com.android.inputmethod.latin.Utils; +import com.android.inputmethod.latin.JniUtils; import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo; import java.util.Arrays; @@ -81,7 +81,7 @@ public class ProximityInfo { private long mNativeProximityInfo; static { - Utils.loadNativeLibrary(); + JniUtils.loadNativeLibrary(); } private native long setProximityInfoNative(int maxProximityCharsSize, int displayWidth, diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java index e3fea3dce..0aba813b2 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java @@ -22,7 +22,7 @@ import android.text.TextUtils; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.Utils; +import com.android.inputmethod.latin.StringUtils; import java.util.ArrayList; import java.util.Arrays; @@ -150,7 +150,7 @@ public class KeySpecParser { } final String outputText = getOutputTextInternal(moreKeySpec); if (outputText != null) { - if (Utils.codePointCount(outputText) == 1) { + if (StringUtils.codePointCount(outputText) == 1) { // If output text is one code point, it should be treated as a code. // See {@link #getCode(Resources, String)}. return null; @@ -165,7 +165,7 @@ public class KeySpecParser { throw new KeySpecParserError("Empty label: " + moreKeySpec); } // Code is automatically generated for one letter label. See {@link getCode()}. - return (Utils.codePointCount(label) == 1) ? null : label; + return (StringUtils.codePointCount(label) == 1) ? null : label; } public static int getCode(Resources res, String moreKeySpec) { @@ -184,14 +184,14 @@ public class KeySpecParser { if (outputText != null) { // If output text is one code point, it should be treated as a code. // See {@link #getOutputText(String)}. - if (Utils.codePointCount(outputText) == 1) { + if (StringUtils.codePointCount(outputText) == 1) { return outputText.codePointAt(0); } return Keyboard.CODE_OUTPUT_TEXT; } final String label = getLabel(moreKeySpec); // Code is automatically generated for one letter label. - if (Utils.codePointCount(label) == 1) { + if (StringUtils.codePointCount(label) == 1) { return label.codePointAt(0); } return Keyboard.CODE_OUTPUT_TEXT; @@ -393,7 +393,7 @@ public class KeySpecParser { if (size == 0) { return null; } - if (Utils.codePointCount(text) == 1) { + if (StringUtils.codePointCount(text) == 1) { return text.codePointAt(0) == COMMA ? null : new String[] { text }; } diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 90ced6028..31ff4e7b4 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -104,7 +104,7 @@ public class BinaryDictionary extends Dictionary { } static { - Utils.loadNativeLibrary(); + JniUtils.loadNativeLibrary(); } private native long openNative(String sourceDir, long dictOffset, long dictSize, diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java index 1607f86a8..7a81f7bd5 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -164,7 +164,7 @@ public class DictionaryFactory { final Resources res = context.getResources(); final Locale saveLocale = LocaleUtils.setSystemLocale(res, locale); - final int resourceId = Utils.getMainDictionaryResourceId(res); + final int resourceId = getMainDictionaryResourceId(res); final AssetFileDescriptor afd = res.openRawResourceFd(resourceId); final boolean hasDictionary = isFullDictionary(afd); try { @@ -182,7 +182,7 @@ public class DictionaryFactory { final Resources res = context.getResources(); final Locale saveLocale = LocaleUtils.setSystemLocale(res, locale); - final int resourceId = Utils.getMainDictionaryResourceId(res); + final int resourceId = getMainDictionaryResourceId(res); final AssetFileDescriptor afd = res.openRawResourceFd(resourceId); final Long size = (afd != null && afd.getLength() > PLACEHOLDER_LENGTH) ? afd.getLength() @@ -209,4 +209,14 @@ public class DictionaryFactory { protected static boolean isFullDictionary(final AssetFileDescriptor afd) { return (afd != null && afd.getLength() > PLACEHOLDER_LENGTH); } + + /** + * Returns a main dictionary resource id + * @return main dictionary resource id + */ + public static int getMainDictionaryResourceId(Resources res) { + final String MAIN_DIC_NAME = "main"; + String packageName = LatinIME.class.getPackage().getName(); + return res.getIdentifier(MAIN_DIC_NAME, "raw", packageName); + } } diff --git a/java/src/com/android/inputmethod/latin/JniUtils.java b/java/src/com/android/inputmethod/latin/JniUtils.java new file mode 100644 index 000000000..4808b867a --- /dev/null +++ b/java/src/com/android/inputmethod/latin/JniUtils.java @@ -0,0 +1,41 @@ +/* + * 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.util.Log; + +import com.android.inputmethod.latin.define.JniLibName; + +public class JniUtils { + private static final String TAG = JniUtils.class.getSimpleName(); + + private JniUtils() { + // This utility class is not publicly instantiable. + } + + public static void loadNativeLibrary() { + try { + System.loadLibrary(JniLibName.JNI_LIB_NAME); + } catch (UnsatisfiedLinkError ule) { + Log.e(TAG, "Could not load native library " + JniLibName.JNI_LIB_NAME); + if (LatinImeLogger.sDBG) { + throw new RuntimeException( + "Could not load native library " + JniLibName.JNI_LIB_NAME); + } + } + } +} diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 1858db949..c16a34fac 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -44,8 +44,8 @@ import android.view.HapticFeedbackConstants; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; -import android.view.ViewParent; import android.view.ViewGroup.LayoutParams; +import android.view.ViewParent; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.ExtractedText; @@ -576,7 +576,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar oldContactsDictionary = null; } - int mainDicResId = Utils.getMainDictionaryResourceId(res); + int mainDicResId = DictionaryFactory.getMainDictionaryResourceId(res); mSuggest = new Suggest(this, mainDicResId, keyboardLocale); if (mSettingsValues.mAutoCorrectEnabled) { mSuggest.setAutoCorrectionThreshold(mSettingsValues.mAutoCorrectionThreshold); @@ -636,7 +636,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar /* package private */ void resetSuggestMainDict() { final String localeStr = mSubtypeSwitcher.getInputLocaleStr(); final Locale keyboardLocale = LocaleUtils.constructLocaleFromString(localeStr); - int mainDicResId = Utils.getMainDictionaryResourceId(mResources); + int mainDicResId = DictionaryFactory.getMainDictionaryResourceId(mResources); mSuggest.resetMainDict(this, mainDicResId, keyboardLocale); } @@ -745,12 +745,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar + String.format("inputType=0x%08x imeOptions=0x%08x", editorInfo.inputType, editorInfo.imeOptions)); } - if (Utils.inPrivateImeOptions(null, IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo)) { + if (StringUtils.inPrivateImeOptions(null, IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo)) { Log.w(TAG, "Deprecated private IME option specified: " + editorInfo.privateImeOptions); Log.w(TAG, "Use " + getPackageName() + "." + IME_OPTION_NO_MICROPHONE + " instead"); } - if (Utils.inPrivateImeOptions(getPackageName(), IME_OPTION_FORCE_ASCII, editorInfo)) { + if (StringUtils.inPrivateImeOptions(getPackageName(), IME_OPTION_FORCE_ASCII, editorInfo)) { Log.w(TAG, "Deprecated private IME option specified: " + editorInfo.privateImeOptions); Log.w(TAG, "Use EditorInfo.IME_FLAG_FORCE_ASCII flag instead"); @@ -1207,7 +1207,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (ic == null) return false; final CharSequence lastThree = ic.getTextBeforeCursor(3, 0); if (lastThree != null && lastThree.length() == 3 - && Utils.canBeFollowedByPeriod(lastThree.charAt(0)) + && StringUtils.canBeFollowedByPeriod(lastThree.charAt(0)) && lastThree.charAt(1) == Keyboard.CODE_SPACE && lastThree.charAt(2) == Keyboard.CODE_SPACE && mHandler.isAcceptingDoubleSpaces()) { @@ -1247,7 +1247,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (isShowingOptionDialog()) return; if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) { showSubtypeSelectorAndSettings(); - } else if (Utils.hasMultipleEnabledIMEsOrSubtypes(false /* exclude aux subtypes */)) { + } else if (SubtypeUtils.hasMultipleEnabledIMEsOrSubtypes( + false /* exclude aux subtypes */)) { showOptionsMenu(); } else { launchSettings(); @@ -1263,7 +1264,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (isShowingOptionDialog()) return false; switch (requestCode) { case CODE_SHOW_INPUT_METHOD_PICKER: - if (Utils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) { + if (SubtypeUtils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) { mImm.showInputMethodPicker(); return true; } @@ -1295,7 +1296,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar final IBinder token = getWindow().getWindow().getAttributes().token; if (mShouldSwitchToLastSubtype) { final InputMethodSubtypeCompatWrapper lastSubtype = mImm.getLastInputMethodSubtype(); - final boolean lastSubtypeBelongsToThisIme = Utils.checkIfSubtypeBelongsToThisIme( + final boolean lastSubtypeBelongsToThisIme = SubtypeUtils.checkIfSubtypeBelongsToThisIme( this, lastSubtype); if ((includesOtherImes || lastSubtypeBelongsToThisIme) && mImm.switchToLastInputMethod(token)) { @@ -1884,7 +1885,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions); } } - if (Utils.shouldBlockAutoCorrectionBySafetyNet(builder, mSuggest)) { + if (Suggest.shouldBlockAutoCorrectionBySafetyNet(builder, mSuggest)) { builder.setShouldBlockAutoCorrectionBySafetyNet(); } showSuggestions(builder.build(), typedWord); @@ -2486,7 +2487,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar switch (position) { case 0: Intent intent = CompatUtils.getInputLanguageSelectionIntent( - Utils.getInputMethodId(getPackageName()), + SubtypeUtils.getInputMethodId(getPackageName()), Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP); diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index 305cef22d..72391f31e 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -343,7 +343,7 @@ public class Settings extends InputMethodSettingsActivity @Override public boolean onPreferenceClick(Preference pref) { if (pref == mInputLanguageSelection) { - final String imeId = Utils.getInputMethodId( + final String imeId = SubtypeUtils.getInputMethodId( getActivityInternal().getApplicationInfo().packageName); startActivity(CompatUtils.getInputLanguageSelectionIntent(imeId, 0)); return true; diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java index 69e45f619..abd1dc692 100644 --- a/java/src/com/android/inputmethod/latin/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/SettingsValues.java @@ -326,9 +326,9 @@ public class SettingsValues { return false; } if (mIncludesOtherImesInLanguageSwitchList) { - return Utils.hasMultipleEnabledIMEsOrSubtypes(/* include aux subtypes */false); + return SubtypeUtils.hasMultipleEnabledIMEsOrSubtypes(/* include aux subtypes */false); } else { - return Utils.hasMultipleEnabledSubtypesInThisIme( + return SubtypeUtils.hasMultipleEnabledSubtypesInThisIme( context, /* include aux subtypes */false); } } diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/StringUtils.java new file mode 100644 index 000000000..81c3b4edf --- /dev/null +++ b/java/src/com/android/inputmethod/latin/StringUtils.java @@ -0,0 +1,198 @@ +/* + * 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.text.TextUtils; +import android.view.inputmethod.EditorInfo; + +import com.android.inputmethod.keyboard.Keyboard; + +import java.util.ArrayList; +import java.util.Locale; + +public class StringUtils { + private StringUtils() { + // This utility class is not publicly instantiable. + } + + public static boolean canBeFollowedByPeriod(final int codePoint) { + // TODO: Check again whether there really ain't a better way to check this. + // TODO: This should probably be language-dependant... + return Character.isLetterOrDigit(codePoint) + || codePoint == Keyboard.CODE_SINGLE_QUOTE + || codePoint == Keyboard.CODE_DOUBLE_QUOTE + || codePoint == Keyboard.CODE_CLOSING_PARENTHESIS + || codePoint == Keyboard.CODE_CLOSING_SQUARE_BRACKET + || codePoint == Keyboard.CODE_CLOSING_CURLY_BRACKET + || codePoint == Keyboard.CODE_CLOSING_ANGLE_BRACKET; + } + + public static int codePointCount(String text) { + if (TextUtils.isEmpty(text)) return 0; + return text.codePointCount(0, text.length()); + } + + public static boolean containsInCsv(String key, String csv) { + if (csv == null) + return false; + for (String option : csv.split(",")) { + if (option.equals(key)) + return true; + } + return false; + } + + public static boolean inPrivateImeOptions(String packageName, String key, + EditorInfo editorInfo) { + if (editorInfo == null) + return false; + return containsInCsv(packageName != null ? packageName + "." + key : key, + editorInfo.privateImeOptions); + } + + /** + * Returns true if a and b are equal ignoring the case of the character. + * @param a first character to check + * @param b second character to check + * @return {@code true} if a and b are equal, {@code false} otherwise. + */ + public static boolean equalsIgnoreCase(char a, char b) { + // Some language, such as Turkish, need testing both cases. + return a == b + || Character.toLowerCase(a) == Character.toLowerCase(b) + || Character.toUpperCase(a) == Character.toUpperCase(b); + } + + /** + * Returns true if a and b are equal ignoring the case of the characters, including if they are + * both null. + * @param a first CharSequence to check + * @param b second CharSequence to check + * @return {@code true} if a and b are equal, {@code false} otherwise. + */ + public static boolean equalsIgnoreCase(CharSequence a, CharSequence b) { + if (a == b) + return true; // including both a and b are null. + if (a == null || b == null) + return false; + final int length = a.length(); + if (length != b.length()) + return false; + for (int i = 0; i < length; i++) { + if (!equalsIgnoreCase(a.charAt(i), b.charAt(i))) + return false; + } + return true; + } + + /** + * Returns true if a and b are equal ignoring the case of the characters, including if a is null + * and b is zero length. + * @param a CharSequence to check + * @param b character array to check + * @param offset start offset of array b + * @param length length of characters in array b + * @return {@code true} if a and b are equal, {@code false} otherwise. + * @throws IndexOutOfBoundsException + * if {@code offset < 0 || length < 0 || offset + length > data.length}. + * @throws NullPointerException if {@code b == null}. + */ + public static boolean equalsIgnoreCase(CharSequence a, char[] b, int offset, int length) { + if (offset < 0 || length < 0 || length > b.length - offset) + throw new IndexOutOfBoundsException("array.length=" + b.length + " offset=" + offset + + " length=" + length); + if (a == null) + return length == 0; // including a is null and b is zero length. + if (a.length() != length) + return false; + for (int i = 0; i < length; i++) { + if (!equalsIgnoreCase(a.charAt(i), b[offset + i])) + return false; + } + return true; + } + + /** + * Remove duplicates from an array of strings. + * + * This method will always keep the first occurence of all strings at their position + * in the array, removing the subsequent ones. + */ + public static void removeDupes(final ArrayList suggestions) { + if (suggestions.size() < 2) return; + int i = 1; + // Don't cache suggestions.size(), since we may be removing items + while (i < suggestions.size()) { + final CharSequence cur = suggestions.get(i); + // Compare each suggestion with each previous suggestion + for (int j = 0; j < i; j++) { + CharSequence previous = suggestions.get(j); + if (TextUtils.equals(cur, previous)) { + removeFromSuggestions(suggestions, i); + i--; + break; + } + } + i++; + } + } + + private static void removeFromSuggestions(final ArrayList suggestions, + final int index) { + final CharSequence garbage = suggestions.remove(index); + if (garbage instanceof StringBuilder) { + StringBuilderPool.recycle((StringBuilder)garbage); + } + } + + public static String getFullDisplayName(Locale locale, boolean returnsNameInThisLocale) { + if (returnsNameInThisLocale) { + return toTitleCase(SubtypeLocale.getFullDisplayName(locale), locale); + } else { + return toTitleCase(locale.getDisplayName(), locale); + } + } + + public static String getDisplayLanguage(Locale locale) { + return toTitleCase(SubtypeLocale.getFullDisplayName(locale), locale); + } + + public static String getMiddleDisplayLanguage(Locale locale) { + return toTitleCase((LocaleUtils.constructLocaleFromString( + locale.getLanguage()).getDisplayLanguage(locale)), locale); + } + + public static String getShortDisplayLanguage(Locale locale) { + return toTitleCase(locale.getLanguage(), locale); + } + + public static String toTitleCase(String s, Locale locale) { + if (s.length() <= 1) { + // TODO: is this really correct? Shouldn't this be s.toUpperCase()? + return s; + } + // TODO: fix the bugs below + // - This does not work for Greek, because it returns upper case instead of title case. + // - It does not work for Serbian, because it fails to account for the "lj" character, + // which should be "Lj" in title case and "LJ" in upper case. + // - It does not work for Dutch, because it fails to account for the "ij" digraph, which + // are two different characters but both should be capitalized as "IJ" as if they were + // a single letter. + // - It also does not work with unicode surrogate code points. + return s.toUpperCase(locale).charAt(0) + s.substring(1); + } +} diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index f5778167a..ffbbf9bb8 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -512,7 +512,7 @@ public class SubtypeSwitcher { } public String getInputLanguageName() { - return Utils.getDisplayLanguage(getInputLocale()); + return StringUtils.getDisplayLanguage(getInputLocale()); } ///////////////////////////// diff --git a/java/src/com/android/inputmethod/latin/SubtypeUtils.java b/java/src/com/android/inputmethod/latin/SubtypeUtils.java new file mode 100644 index 000000000..cb2bcf43f --- /dev/null +++ b/java/src/com/android/inputmethod/latin/SubtypeUtils.java @@ -0,0 +1,135 @@ +/* + * 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 com.android.inputmethod.compat.InputMethodInfoCompatWrapper; +import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; +import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; + +import java.util.Collections; +import java.util.List; + +public class SubtypeUtils { + private SubtypeUtils() { + // This utility class is not publicly instantiable. + } + + // TODO: Cache my InputMethodInfo and/or InputMethodSubtype list. + public static boolean checkIfSubtypeBelongsToThisIme(Context context, + InputMethodSubtypeCompatWrapper ims) { + final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); + if (imm == null) return false; + + final InputMethodInfoCompatWrapper myImi = getInputMethodInfo(context.getPackageName()); + final List subtypes = + imm.getEnabledInputMethodSubtypeList(myImi, true); + for (final InputMethodSubtypeCompatWrapper subtype : subtypes) { + if (subtype.equals(ims)) { + return true; + } + } + return false; + } + + public static boolean hasMultipleEnabledIMEsOrSubtypes( + final boolean shouldIncludeAuxiliarySubtypes) { + final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); + if (imm == null) return false; + + final List enabledImis = imm.getEnabledInputMethodList(); + return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, enabledImis); + } + + public static boolean hasMultipleEnabledSubtypesInThisIme(Context context, + final boolean shouldIncludeAuxiliarySubtypes) { + final InputMethodInfoCompatWrapper myImi = getInputMethodInfo(context.getPackageName()); + final List imiList = Collections.singletonList(myImi); + return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, imiList); + } + + private static boolean hasMultipleEnabledSubtypes(final boolean shouldIncludeAuxiliarySubtypes, + List imiList) { + final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); + if (imm == null) return false; + + // Number of the filtered IMEs + int filteredImisCount = 0; + + for (InputMethodInfoCompatWrapper imi : imiList) { + // We can return true immediately after we find two or more filtered IMEs. + if (filteredImisCount > 1) return true; + final List subtypes = + imm.getEnabledInputMethodSubtypeList(imi, true); + // IMEs that have no subtypes should be counted. + if (subtypes.isEmpty()) { + ++filteredImisCount; + continue; + } + + int auxCount = 0; + for (InputMethodSubtypeCompatWrapper subtype : subtypes) { + if (subtype.isAuxiliary()) { + ++auxCount; + } + } + final int nonAuxCount = subtypes.size() - auxCount; + + // IMEs that have one or more non-auxiliary subtypes should be counted. + // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary + // subtypes should be counted as well. + if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) { + ++filteredImisCount; + continue; + } + } + + if (filteredImisCount > 1) { + return true; + } + final List subtypes = + imm.getEnabledInputMethodSubtypeList(null, true); + int keyboardCount = 0; + // imm.getEnabledInputMethodSubtypeList(null, true) will return the current IME's + // both explicitly and implicitly enabled input method subtype. + // (The current IME should be LatinIME.) + for (InputMethodSubtypeCompatWrapper subtype : subtypes) { + if (SubtypeSwitcher.KEYBOARD_MODE.equals(subtype.getMode())) { + ++keyboardCount; + } + } + return keyboardCount > 1; + } + + public static String getInputMethodId(String packageName) { + return getInputMethodInfo(packageName).getId(); + } + + public static InputMethodInfoCompatWrapper getInputMethodInfo(String packageName) { + final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); + if (imm == null) { + throw new RuntimeException("Input method manager not found"); + } + + for (final InputMethodInfoCompatWrapper imi : imm.getEnabledInputMethodList()) { + if (imi.getPackageName().equals(packageName)) + return imi; + } + throw new RuntimeException("Can not find input method id for " + packageName); + } +} diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 298ead665..671fb905d 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -108,6 +108,8 @@ public class Suggest implements Dictionary.WordCallback { private boolean mIsAllUpperCase; private int mTrailingSingleQuotesCount; + private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4; + public Suggest(final Context context, final int dictionaryResId, final Locale locale) { initAsynchronously(context, dictionaryResId, locale); } @@ -383,7 +385,7 @@ public class Suggest implements Dictionary.WordCallback { if (typedWord != null) { mSuggestions.add(0, typedWord.toString()); } - Utils.removeDupes(mSuggestions); + StringUtils.removeDupes(mSuggestions); if (DBG) { double normalizedScore = mAutoCorrection.getNormalizedScore(); @@ -434,7 +436,7 @@ public class Suggest implements Dictionary.WordCallback { int pos = 0; // Check if it's the same word, only caps are different - if (Utils.equalsIgnoreCase(mConsideredWord, word, offset, length)) { + if (StringUtils.equalsIgnoreCase(mConsideredWord, word, offset, length)) { // TODO: remove this surrounding if clause and move this logic to // getSuggestedWordBuilder. if (suggestions.size() > 0) { @@ -443,7 +445,7 @@ public class Suggest implements Dictionary.WordCallback { // 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 (Utils.equalsIgnoreCase(currentHighestWord, word, offset, length) + if (StringUtils.equalsIgnoreCase(currentHighestWord, word, offset, length) && score <= sortedScores[0]) { pos = 1; } @@ -558,4 +560,46 @@ public class Suggest implements Dictionary.WordCallback { } mMainDict = null; } + + // TODO: Resolve the inconsistencies between the native auto correction algorithms and + // this safety net + public static boolean shouldBlockAutoCorrectionBySafetyNet( + SuggestedWords.Builder suggestedWordsBuilder, Suggest suggest) { + // Safety net for auto correction. + // Actually if we hit this safety net, it's actually a bug. + if (suggestedWordsBuilder.size() <= 1 || suggestedWordsBuilder.isTypedWordValid()) { + return false; + } + // If user selected aggressive auto correction mode, there is no need to use the safety + // net. + if (suggest.isAggressiveAutoCorrectionMode()) { + return false; + } + final CharSequence typedWord = suggestedWordsBuilder.getWord(0); + // If the length of typed word is less than MINIMUM_SAFETY_NET_CHAR_LENGTH, + // we should not use net because relatively edit distance can be big. + if (typedWord.length() < Suggest.MINIMUM_SAFETY_NET_CHAR_LENGTH) { + return false; + } + final CharSequence suggestionWord = suggestedWordsBuilder.getWord(1); + final int typedWordLength = typedWord.length(); + final int maxEditDistanceOfNativeDictionary = + (typedWordLength < 5 ? 2 : typedWordLength / 2) + 1; + final int distance = BinaryDictionary.editDistance( + typedWord.toString(), suggestionWord.toString()); + if (DBG) { + Log.d(TAG, "Autocorrected edit distance = " + distance + + ", " + maxEditDistanceOfNativeDictionary); + } + if (distance > maxEditDistanceOfNativeDictionary) { + if (DBG) { + Log.e(TAG, "Safety net: before = " + typedWord + ", after = " + suggestionWord); + Log.e(TAG, "(Error) The edit distance of this correction exceeds limit. " + + "Turning off auto-correction."); + } + return true; + } else { + return false; + } + } } diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index a8679e07a..f8dd5ae42 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -19,7 +19,6 @@ package com.android.inputmethod.latin; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; -import android.content.res.Resources; import android.inputmethodservice.InputMethodService; import android.net.Uri; import android.os.AsyncTask; @@ -27,19 +26,9 @@ import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; import android.os.Process; -import android.text.InputType; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.Log; -import android.view.inputmethod.EditorInfo; - -import com.android.inputmethod.compat.InputMethodInfoCompatWrapper; -import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; -import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; -import com.android.inputmethod.compat.InputTypeCompatUtils; -import com.android.inputmethod.keyboard.Keyboard; -import com.android.inputmethod.keyboard.KeyboardId; -import com.android.inputmethod.latin.define.JniLibName; import java.io.BufferedReader; import java.io.File; @@ -51,20 +40,11 @@ import java.io.IOException; import java.io.PrintWriter; import java.nio.channels.FileChannel; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; import java.util.Date; -import java.util.List; -import java.util.Locale; public class Utils { - private static final String TAG = Utils.class.getSimpleName(); - private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4; - private static boolean DBG = LatinImeLogger.sDBG; - private static boolean DBG_EDIT_DISTANCE = false; - private Utils() { - // Intentional empty constructor for utility class. + // This utility class is not publicly instantiable. } /** @@ -118,166 +98,6 @@ public class Utils { } } - // TODO: Move InputMethodSubtype related utility methods to its own utility class. - // TODO: Cache my InputMethodInfo and/or InputMethodSubtype list. - public static boolean checkIfSubtypeBelongsToThisIme(Context context, - InputMethodSubtypeCompatWrapper ims) { - final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); - if (imm == null) return false; - - final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo( - context.getPackageName()); - final List subtypes = - imm.getEnabledInputMethodSubtypeList(myImi, true); - for (final InputMethodSubtypeCompatWrapper subtype : subtypes) { - if (subtype.equals(ims)) { - return true; - } - } - return false; - } - - public static boolean hasMultipleEnabledIMEsOrSubtypes( - final boolean shouldIncludeAuxiliarySubtypes) { - final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); - if (imm == null) return false; - - final List enabledImis = imm.getEnabledInputMethodList(); - return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, enabledImis); - } - - public static boolean hasMultipleEnabledSubtypesInThisIme(Context context, - final boolean shouldIncludeAuxiliarySubtypes) { - final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo( - context.getPackageName()); - final List imiList = Collections.singletonList(myImi); - return Utils.hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, imiList); - } - - private static boolean hasMultipleEnabledSubtypes(final boolean shouldIncludeAuxiliarySubtypes, - List imiList) { - final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); - if (imm == null) return false; - - // Number of the filtered IMEs - int filteredImisCount = 0; - - for (InputMethodInfoCompatWrapper imi : imiList) { - // We can return true immediately after we find two or more filtered IMEs. - if (filteredImisCount > 1) return true; - final List subtypes = - imm.getEnabledInputMethodSubtypeList(imi, true); - // IMEs that have no subtypes should be counted. - if (subtypes.isEmpty()) { - ++filteredImisCount; - continue; - } - - int auxCount = 0; - for (InputMethodSubtypeCompatWrapper subtype : subtypes) { - if (subtype.isAuxiliary()) { - ++auxCount; - } - } - final int nonAuxCount = subtypes.size() - auxCount; - - // IMEs that have one or more non-auxiliary subtypes should be counted. - // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary - // subtypes should be counted as well. - if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) { - ++filteredImisCount; - continue; - } - } - - if (filteredImisCount > 1) { - return true; - } - final List subtypes = - imm.getEnabledInputMethodSubtypeList(null, true); - int keyboardCount = 0; - // imm.getEnabledInputMethodSubtypeList(null, true) will return the current IME's - // both explicitly and implicitly enabled input method subtype. - // (The current IME should be LatinIME.) - for (InputMethodSubtypeCompatWrapper subtype : subtypes) { - if (SubtypeSwitcher.KEYBOARD_MODE.equals(subtype.getMode())) { - ++keyboardCount; - } - } - return keyboardCount > 1; - } - - public static String getInputMethodId(String packageName) { - return getInputMethodInfo(packageName).getId(); - } - - public static InputMethodInfoCompatWrapper getInputMethodInfo(String packageName) { - final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); - if (imm == null) { - throw new RuntimeException("Input method manager not found"); - } - - for (final InputMethodInfoCompatWrapper imi : imm.getEnabledInputMethodList()) { - if (imi.getPackageName().equals(packageName)) - return imi; - } - throw new RuntimeException("Can not find input method id for " + packageName); - } - - // TODO: Resolve the inconsistencies between the native auto correction algorithms and - // this safety net - public static boolean shouldBlockAutoCorrectionBySafetyNet( - SuggestedWords.Builder suggestedWordsBuilder, Suggest suggest) { - // Safety net for auto correction. - // Actually if we hit this safety net, it's actually a bug. - if (suggestedWordsBuilder.size() <= 1 || suggestedWordsBuilder.isTypedWordValid()) { - return false; - } - // If user selected aggressive auto correction mode, there is no need to use the safety - // net. - if (suggest.isAggressiveAutoCorrectionMode()) { - return false; - } - final CharSequence typedWord = suggestedWordsBuilder.getWord(0); - // If the length of typed word is less than MINIMUM_SAFETY_NET_CHAR_LENGTH, - // we should not use net because relatively edit distance can be big. - if (typedWord.length() < MINIMUM_SAFETY_NET_CHAR_LENGTH) { - return false; - } - final CharSequence suggestionWord = suggestedWordsBuilder.getWord(1); - final int typedWordLength = typedWord.length(); - final int maxEditDistanceOfNativeDictionary = - (typedWordLength < 5 ? 2 : typedWordLength / 2) + 1; - final int distance = BinaryDictionary.editDistance( - typedWord.toString(), suggestionWord.toString()); - if (DBG) { - Log.d(TAG, "Autocorrected edit distance = " + distance - + ", " + maxEditDistanceOfNativeDictionary); - } - if (distance > maxEditDistanceOfNativeDictionary) { - if (DBG) { - Log.e(TAG, "Safety net: before = " + typedWord + ", after = " + suggestionWord); - Log.e(TAG, "(Error) The edit distance of this correction exceeds limit. " - + "Turning off auto-correction."); - } - return true; - } else { - return false; - } - } - - public static boolean canBeFollowedByPeriod(final int codePoint) { - // TODO: Check again whether there really ain't a better way to check this. - // TODO: This should probably be language-dependant... - return Character.isLetterOrDigit(codePoint) - || codePoint == Keyboard.CODE_SINGLE_QUOTE - || codePoint == Keyboard.CODE_DOUBLE_QUOTE - || codePoint == Keyboard.CODE_CLOSING_PARENTHESIS - || codePoint == Keyboard.CODE_CLOSING_SQUARE_BRACKET - || codePoint == Keyboard.CODE_CLOSING_CURLY_BRACKET - || codePoint == Keyboard.CODE_CLOSING_ANGLE_BRACKET; - } - /* package */ static class RingCharBuffer { private static RingCharBuffer sRingCharBuffer = new RingCharBuffer(); private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC'; @@ -600,147 +420,6 @@ public class Utils { } } - // TODO: Move this method to KeyboardSet class. - public static int getKeyboardMode(EditorInfo editorInfo) { - if (editorInfo == null) - return KeyboardId.MODE_TEXT; - - final int inputType = editorInfo.inputType; - final int variation = inputType & InputType.TYPE_MASK_VARIATION; - - switch (inputType & InputType.TYPE_MASK_CLASS) { - case InputType.TYPE_CLASS_NUMBER: - return KeyboardId.MODE_NUMBER; - case InputType.TYPE_CLASS_DATETIME: - switch (variation) { - case InputType.TYPE_DATETIME_VARIATION_DATE: - return KeyboardId.MODE_DATE; - case InputType.TYPE_DATETIME_VARIATION_TIME: - return KeyboardId.MODE_TIME; - default: // InputType.TYPE_DATETIME_VARIATION_NORMAL - return KeyboardId.MODE_DATETIME; - } - case InputType.TYPE_CLASS_PHONE: - return KeyboardId.MODE_PHONE; - case InputType.TYPE_CLASS_TEXT: - if (InputTypeCompatUtils.isEmailVariation(variation)) { - return KeyboardId.MODE_EMAIL; - } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) { - return KeyboardId.MODE_URL; - } else if (variation == InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { - return KeyboardId.MODE_IM; - } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) { - return KeyboardId.MODE_TEXT; - } else { - return KeyboardId.MODE_TEXT; - } - default: - return KeyboardId.MODE_TEXT; - } - } - - public static boolean containsInCsv(String key, String csv) { - if (csv == null) - return false; - for (String option : csv.split(",")) { - if (option.equals(key)) - return true; - } - return false; - } - - public static boolean inPrivateImeOptions(String packageName, String key, - EditorInfo editorInfo) { - if (editorInfo == null) - return false; - return containsInCsv(packageName != null ? packageName + "." + key : key, - editorInfo.privateImeOptions); - } - - /** - * Returns a main dictionary resource id - * @return main dictionary resource id - */ - public static int getMainDictionaryResourceId(Resources res) { - final String MAIN_DIC_NAME = "main"; - String packageName = LatinIME.class.getPackage().getName(); - return res.getIdentifier(MAIN_DIC_NAME, "raw", packageName); - } - - public static void loadNativeLibrary() { - try { - System.loadLibrary(JniLibName.JNI_LIB_NAME); - } catch (UnsatisfiedLinkError ule) { - Log.e(TAG, "Could not load native library " + JniLibName.JNI_LIB_NAME); - if (LatinImeLogger.sDBG) { - throw new RuntimeException( - "Could not load native library " + JniLibName.JNI_LIB_NAME); - } - } - } - - /** - * Returns true if a and b are equal ignoring the case of the character. - * @param a first character to check - * @param b second character to check - * @return {@code true} if a and b are equal, {@code false} otherwise. - */ - public static boolean equalsIgnoreCase(char a, char b) { - // Some language, such as Turkish, need testing both cases. - return a == b - || Character.toLowerCase(a) == Character.toLowerCase(b) - || Character.toUpperCase(a) == Character.toUpperCase(b); - } - - /** - * Returns true if a and b are equal ignoring the case of the characters, including if they are - * both null. - * @param a first CharSequence to check - * @param b second CharSequence to check - * @return {@code true} if a and b are equal, {@code false} otherwise. - */ - public static boolean equalsIgnoreCase(CharSequence a, CharSequence b) { - if (a == b) - return true; // including both a and b are null. - if (a == null || b == null) - return false; - final int length = a.length(); - if (length != b.length()) - return false; - for (int i = 0; i < length; i++) { - if (!equalsIgnoreCase(a.charAt(i), b.charAt(i))) - return false; - } - return true; - } - - /** - * Returns true if a and b are equal ignoring the case of the characters, including if a is null - * and b is zero length. - * @param a CharSequence to check - * @param b character array to check - * @param offset start offset of array b - * @param length length of characters in array b - * @return {@code true} if a and b are equal, {@code false} otherwise. - * @throws IndexOutOfBoundsException - * if {@code offset < 0 || length < 0 || offset + length > data.length}. - * @throws NullPointerException if {@code b == null}. - */ - public static boolean equalsIgnoreCase(CharSequence a, char[] b, int offset, int length) { - if (offset < 0 || length < 0 || length > b.length - offset) - throw new IndexOutOfBoundsException("array.length=" + b.length + " offset=" + offset - + " length=" + length); - if (a == null) - return length == 0; // including a is null and b is zero length. - if (a.length() != length) - return false; - for (int i = 0; i < length; i++) { - if (!equalsIgnoreCase(a.charAt(i), b[offset + i])) - return false; - } - return true; - } - public static float getDipScale(Context context) { final float scale = context.getResources().getDisplayMetrics().density; return scale; @@ -751,76 +430,6 @@ public class Utils { return (int) (dip * scale + 0.5); } - /** - * Remove duplicates from an array of strings. - * - * This method will always keep the first occurence of all strings at their position - * in the array, removing the subsequent ones. - */ - public static void removeDupes(final ArrayList suggestions) { - if (suggestions.size() < 2) return; - int i = 1; - // Don't cache suggestions.size(), since we may be removing items - while (i < suggestions.size()) { - final CharSequence cur = suggestions.get(i); - // Compare each suggestion with each previous suggestion - for (int j = 0; j < i; j++) { - CharSequence previous = suggestions.get(j); - if (TextUtils.equals(cur, previous)) { - removeFromSuggestions(suggestions, i); - i--; - break; - } - } - i++; - } - } - - private static void removeFromSuggestions(final ArrayList suggestions, - final int index) { - final CharSequence garbage = suggestions.remove(index); - if (garbage instanceof StringBuilder) { - StringBuilderPool.recycle((StringBuilder)garbage); - } - } - - public static String getFullDisplayName(Locale locale, boolean returnsNameInThisLocale) { - if (returnsNameInThisLocale) { - return toTitleCase(SubtypeLocale.getFullDisplayName(locale), locale); - } else { - return toTitleCase(locale.getDisplayName(), locale); - } - } - - public static String getDisplayLanguage(Locale locale) { - return toTitleCase(SubtypeLocale.getFullDisplayName(locale), locale); - } - - public static String getMiddleDisplayLanguage(Locale locale) { - return toTitleCase((LocaleUtils.constructLocaleFromString( - locale.getLanguage()).getDisplayLanguage(locale)), locale); - } - - public static String getShortDisplayLanguage(Locale locale) { - return toTitleCase(locale.getLanguage(), locale); - } - - public static String toTitleCase(String s, Locale locale) { - if (s.length() <= 1) { - // TODO: is this really correct? Shouldn't this be s.toUpperCase()? - return s; - } - // TODO: fix the bugs below - // - This does not work for Greek, because it returns upper case instead of title case. - // - It does not work for Serbian, because it fails to account for the "lj" character, - // which should be "Lj" in title case and "LJ" in upper case. - // - It does not work for Dutch, because it fails to account for the "ij" digraph, which - // are two different characters but both should be capitalized as "IJ" as if they were - // a single letter. - // - It also does not work with unicode surrogate code points. - return s.toUpperCase(locale).charAt(0) + s.substring(1); - } - public static class Stats { public static void onNonSeparator(final char code, final int x, final int y) { @@ -845,9 +454,4 @@ public class Utils { LatinImeLogger.logOnAutoCorrectionCancelled(); } } - - public static int codePointCount(String text) { - if (TextUtils.isEmpty(text)) return 0; - return text.codePointCount(0, text.length()); - } } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index 755c75b2e..35a5c0f52 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -37,9 +37,9 @@ import com.android.inputmethod.latin.DictionaryFactory; import com.android.inputmethod.latin.Flag; import com.android.inputmethod.latin.LocaleUtils; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.StringUtils; import com.android.inputmethod.latin.SynchronouslyLoadedContactsDictionary; import com.android.inputmethod.latin.SynchronouslyLoadedUserDictionary; -import com.android.inputmethod.latin.Utils; import com.android.inputmethod.latin.WhitelistDictionary; import com.android.inputmethod.latin.WordComposer; @@ -47,11 +47,11 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.TreeMap; -import java.util.HashSet; /** * Service for spell checking, using LatinIME's dictionaries and mechanisms. @@ -316,7 +316,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService } } Collections.reverse(mSuggestions); - Utils.removeDupes(mSuggestions); + StringUtils.removeDupes(mSuggestions); if (CAPITALIZE_ALL == capitalizeType) { for (int i = 0; i < mSuggestions.size(); ++i) { // get(i) returns a CharSequence which is actually a String so .toString() @@ -326,7 +326,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService } else if (CAPITALIZE_FIRST == capitalizeType) { for (int i = 0; i < mSuggestions.size(); ++i) { // Likewise - mSuggestions.set(i, Utils.toTitleCase(mSuggestions.get(i).toString(), + mSuggestions.set(i, StringUtils.toTitleCase(mSuggestions.get(i).toString(), locale)); } } @@ -396,7 +396,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService final ProximityInfo proximityInfo = ProximityInfo.createSpellCheckerProximityInfo( SpellCheckerProximityInfo.getProximityForScript(script)); final Resources resources = getResources(); - final int fallbackResourceId = Utils.getMainDictionaryResourceId(resources); + final int fallbackResourceId = DictionaryFactory.getMainDictionaryResourceId(resources); final DictionaryCollection dictionaryCollection = DictionaryFactory.createDictionaryFromManager(this, locale, fallbackResourceId, USE_FULL_EDIT_DISTANCE_FLAG_ARRAY); -- cgit v1.2.3-83-g751a From c61cd79229b1871d0f603a23389695d7f7751e66 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Thu, 29 Mar 2012 15:07:53 +0900 Subject: Fix some obvious compiler warnings Change-Id: I10a634f7492b45d5a72345f14d36cf341946387d --- .../inputmethod/compat/InputMethodManagerCompatWrapper.java | 9 +++++---- .../com/android/inputmethod/compat/SuggestionSpanUtils.java | 2 +- .../inputmethod/compat/SuggestionsInfoCompatUtils.java | 4 ++-- .../android/inputmethod/keyboard/KeyboardActionListener.java | 12 ++++++------ .../inputmethod/latin/BinaryDictionaryFileDumper.java | 2 +- java/src/com/android/inputmethod/latin/Dictionary.java | 2 +- java/src/com/android/inputmethod/latin/LatinIME.java | 1 - java/src/com/android/inputmethod/latin/LatinImeLogger.java | 1 - java/src/com/android/inputmethod/latin/ResearchLogger.java | 2 +- java/src/com/android/inputmethod/latin/WordComposer.java | 4 +--- 10 files changed, 18 insertions(+), 21 deletions(-) (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java index bf5f20158..a4ff8238c 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -267,12 +267,13 @@ public class InputMethodManagerCompatWrapper { final InputMethodSubtypeCompatWrapper currentIms = getCurrentInputMethodSubtype(); final List imiList = getEnabledInputMethodList(); imiList.remove(myImi); + final PackageManager pm = mPackageManager; Collections.sort(imiList, new Comparator() { @Override public int compare(InputMethodInfoCompatWrapper imi1, InputMethodInfoCompatWrapper imi2) { - final CharSequence imiId1 = imi1.loadLabel(mPackageManager) + "/" + imi1.getId(); - final CharSequence imiId2 = imi2.loadLabel(mPackageManager) + "/" + imi2.getId(); + final CharSequence imiId1 = imi1.loadLabel(pm) + "/" + imi1.getId(); + final CharSequence imiId2 = imi2.loadLabel(pm) + "/" + imi2.getId(); return imiId1.toString().compareTo(imiId2.toString()); } }); @@ -302,6 +303,7 @@ public class InputMethodManagerCompatWrapper { index++; } + final InputMethodServiceCompatWrapper service = mService; final OnClickListener buttonListener = new OnClickListener() { @Override public void onClick(DialogInterface di, int whichButton) { @@ -309,10 +311,9 @@ public class InputMethodManagerCompatWrapper { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP); - mService.startActivity(intent); + service.startActivity(intent); } }; - final InputMethodServiceCompatWrapper service = mService; final IBinder token = service.getWindow().getWindow().getAttributes().token; final OnClickListener selectionListener = new OnClickListener() { @Override diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java index a9e48404a..df55aee94 100644 --- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java +++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java @@ -129,7 +129,7 @@ public class SuggestionSpanUtils { // TODO: Share the implementation for checking typed word validity between the IME // and the spell checker. final int flag = (sameAsTyped && !suggestedWords.mTypedWordValid) - ? ((int)OBJ_FLAG_EASY_CORRECT | (int)OBJ_FLAG_MISSPELLED) + ? (OBJ_FLAG_EASY_CORRECT | OBJ_FLAG_MISSPELLED) : 0; final Object[] args = diff --git a/java/src/com/android/inputmethod/compat/SuggestionsInfoCompatUtils.java b/java/src/com/android/inputmethod/compat/SuggestionsInfoCompatUtils.java index 6a0d4dd9e..723ec2862 100644 --- a/java/src/com/android/inputmethod/compat/SuggestionsInfoCompatUtils.java +++ b/java/src/com/android/inputmethod/compat/SuggestionsInfoCompatUtils.java @@ -24,7 +24,7 @@ public class SuggestionsInfoCompatUtils { private static final Field FIELD_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS = CompatUtils.getField( SuggestionsInfo.class, "RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS"); private static final Integer OBJ_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS = (Integer) CompatUtils - .getFieldValue(null, null, FIELD_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS);; + .getFieldValue(null, null, FIELD_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS); private static final int RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS = OBJ_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS != null ? OBJ_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS : 0; @@ -34,7 +34,7 @@ public class SuggestionsInfoCompatUtils { /** * Returns the flag value of the attributes of the suggestions that can be obtained by - * {@link #getSuggestionsAttributes}: this tells that the text service thinks + * {@link SuggestionsInfo#getSuggestionsAttributes()}: this tells that the text service thinks * the result suggestions include highly recommended ones. */ public static int getValueOf_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS() { diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java index 16b4eafc9..275aacf36 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java @@ -42,13 +42,13 @@ public interface KeyboardActionListener { * * @param primaryCode this is the code of the key that was pressed * @param x x-coordinate pixel of touched event. If {@link #onCodeInput} is not called by - * {@link PointerTracker#onTouchEvent} or so, the value should be - * {@link #NOT_A_TOUCH_COORDINATE}. If it's called on insertion from the suggestion - * strip, it should be {@link #SUGGESTION_STRIP_COORDINATE}. + * {@link PointerTracker} or so, the value should be {@link #NOT_A_TOUCH_COORDINATE}. + * If it's called on insertion from the suggestion strip, it should be + * {@link #SUGGESTION_STRIP_COORDINATE}. * @param y y-coordinate pixel of touched event. If {@link #onCodeInput} is not called by - * {@link PointerTracker#onTouchEvent} or so, the value should be - * {@link #NOT_A_TOUCH_COORDINATE}. If it's called on insertion from the suggestion - * strip, it should be {@link #SUGGESTION_STRIP_COORDINATE}. + * {@link PointerTracker} or so, the value should be {@link #NOT_A_TOUCH_COORDINATE}. + * If it's called on insertion from the suggestion strip, it should be + * {@link #SUGGESTION_STRIP_COORDINATE}. */ public void onCodeInput(int primaryCode, int x, int y); diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java index 8ec440500..311d3dc9d 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java @@ -252,7 +252,7 @@ public class BinaryDictionaryFileDumper { * also apply. * * @param input the stream to be copied. - * @param outputFile an outputstream to copy the data to. + * @param output an output stream to copy the data to. */ private static void checkMagicAndCopyFileTo(final BufferedInputStream input, final FileOutputStream output) throws FileNotFoundException, IOException { diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java index 79bf33850..9d26a2343 100644 --- a/java/src/com/android/inputmethod/latin/Dictionary.java +++ b/java/src/com/android/inputmethod/latin/Dictionary.java @@ -38,7 +38,7 @@ public abstract class Dictionary { /** * Interface to be implemented by classes requesting words to be fetched from the dictionary. - * @see #getWords(WordComposer, WordCallback) + * @see #getWords(WordComposer, WordCallback, ProximityInfo) */ public interface WordCallback { /** diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 86c153958..9f9f6b87d 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -68,7 +68,6 @@ import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.KeyboardView; import com.android.inputmethod.keyboard.LatinKeyboardView; -import com.android.inputmethod.latin.Utils.UsabilityStudyLogUtils; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.suggestions.SuggestionsView; diff --git a/java/src/com/android/inputmethod/latin/LatinImeLogger.java b/java/src/com/android/inputmethod/latin/LatinImeLogger.java index 732efadd6..dc0868e7c 100644 --- a/java/src/com/android/inputmethod/latin/LatinImeLogger.java +++ b/java/src/com/android/inputmethod/latin/LatinImeLogger.java @@ -16,7 +16,6 @@ package com.android.inputmethod.latin; -import android.content.Context; import android.content.SharedPreferences; import android.view.inputmethod.EditorInfo; diff --git a/java/src/com/android/inputmethod/latin/ResearchLogger.java b/java/src/com/android/inputmethod/latin/ResearchLogger.java index 0694ffe77..7f3be8584 100644 --- a/java/src/com/android/inputmethod/latin/ResearchLogger.java +++ b/java/src/com/android/inputmethod/latin/ResearchLogger.java @@ -178,8 +178,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang } if (prefs != null) { sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false); + prefs.registerOnSharedPreferenceChangeListener(this); } - prefs.registerOnSharedPreferenceChangeListener(this); } /** diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index 555a49ef4..bd8532ebd 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -144,9 +144,7 @@ public class WordComposer { } /** - * Add a new keystroke, with codes[0] containing the pressed key's unicode and the rest of - * the array containing unicode for adjacent keys, sorted by reducing probability/proximity. - * @param codes the array of unicode values + * Add a new keystroke, with the pressed key's code point with the touch point coordinates. */ private void add(int primaryCode, int keyX, int keyY) { final int newIndex = size(); -- cgit v1.2.3-83-g751a From 911b8f9d19c1c4903eeef29b43176cfeaa0e5d0c Mon Sep 17 00:00:00 2001 From: Ken Wakasa Date: Fri, 30 Mar 2012 16:08:11 +0900 Subject: Remove the "deprecated" classes bug: 6129704 Change-Id: Ib27f2774444e1f084b19be3fe6f56d25dffa7084 --- java/res/values/attrs.xml | 6 - java/res/values/strings.xml | 72 -- java/res/xml-ar/keyboard_set.xml | 3 +- java/res/xml-be/keyboard_set.xml | 3 +- java/res/xml-bg/keyboard_set.xml | 3 +- java/res/xml-cs/keyboard_set.xml | 3 +- java/res/xml-da/keyboard_set.xml | 3 +- java/res/xml-de-rZZ/keyboard_set.xml | 3 +- java/res/xml-de/keyboard_set.xml | 3 +- java/res/xml-el/keyboard_set.xml | 3 +- java/res/xml-es/keyboard_set.xml | 3 +- java/res/xml-et/keyboard_set.xml | 3 +- java/res/xml-fa/keyboard_set.xml | 3 +- java/res/xml-fi/keyboard_set.xml | 3 +- java/res/xml-fr-rCA/keyboard_set.xml | 3 +- java/res/xml-fr-rCH/keyboard_set.xml | 3 +- java/res/xml-fr/keyboard_set.xml | 3 +- java/res/xml-hi/keyboard_set.xml | 3 +- java/res/xml-hr/keyboard_set.xml | 3 +- java/res/xml-hu/keyboard_set.xml | 3 +- java/res/xml-is/keyboard_set.xml | 3 +- java/res/xml-iw/keyboard_set.xml | 3 +- java/res/xml-ka/keyboard_set.xml | 3 +- java/res/xml-ky/keyboard_set.xml | 3 +- java/res/xml-mk/keyboard_set.xml | 3 +- java/res/xml-nb/keyboard_set.xml | 3 +- java/res/xml-pl/keyboard_set.xml | 3 +- java/res/xml-pt/keyboard_set.xml | 3 +- java/res/xml-ro/keyboard_set.xml | 3 +- java/res/xml-ru/keyboard_set.xml | 3 +- java/res/xml-sk/keyboard_set.xml | 3 +- java/res/xml-sl/keyboard_set.xml | 3 +- java/res/xml-sr/keyboard_set.xml | 3 +- java/res/xml-sv/keyboard_set.xml | 3 +- java/res/xml-th/keyboard_set.xml | 3 +- java/res/xml-tr/keyboard_set.xml | 3 +- java/res/xml-uk/keyboard_set.xml | 3 +- java/res/xml-vi/keyboard_set.xml | 3 +- java/res/xml/keyboard_set.xml | 3 +- .../compat/InputMethodManagerCompatWrapper.java | 119 +-- .../compat/InputMethodServiceCompatWrapper.java | 4 - .../deprecated/LanguageSwitcherProxy.java | 90 --- .../android/inputmethod/deprecated/VoiceProxy.java | 854 --------------------- .../compat/VoiceInputLoggerCompatUtils.java | 36 - .../languageswitcher/InputLanguageSelection.java | 255 ------ .../languageswitcher/LanguageSwitcher.java | 234 ------ .../inputmethod/deprecated/voice/FieldContext.java | 104 --- .../inputmethod/deprecated/voice/Hints.java | 188 ----- .../deprecated/voice/RecognitionView.java | 355 --------- .../inputmethod/deprecated/voice/SettingsUtil.java | 110 --- .../deprecated/voice/SoundIndicator.java | 155 ---- .../inputmethod/deprecated/voice/VoiceInput.java | 692 ----------------- .../deprecated/voice/VoiceInputLogger.java | 266 ------- .../deprecated/voice/WaveformImage.java | 92 --- .../inputmethod/deprecated/voice/Whitelist.java | 68 -- .../android/inputmethod/keyboard/KeyboardSet.java | 26 - .../inputmethod/keyboard/LatinKeyboardView.java | 7 - .../com/android/inputmethod/latin/LatinIME.java | 106 +-- .../com/android/inputmethod/latin/Settings.java | 88 +-- .../android/inputmethod/latin/SubtypeSwitcher.java | 75 +- 60 files changed, 44 insertions(+), 4069 deletions(-) delete mode 100644 java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java delete mode 100644 java/src/com/android/inputmethod/deprecated/VoiceProxy.java delete mode 100644 java/src/com/android/inputmethod/deprecated/compat/VoiceInputLoggerCompatUtils.java delete mode 100644 java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java delete mode 100644 java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java delete mode 100644 java/src/com/android/inputmethod/deprecated/voice/FieldContext.java delete mode 100644 java/src/com/android/inputmethod/deprecated/voice/Hints.java delete mode 100644 java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java delete mode 100644 java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java delete mode 100644 java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java delete mode 100644 java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java delete mode 100644 java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java delete mode 100644 java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java delete mode 100644 java/src/com/android/inputmethod/deprecated/voice/Whitelist.java (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml index 3d4e776a7..86f2abe72 100644 --- a/java/res/values/attrs.xml +++ b/java/res/values/attrs.xml @@ -403,12 +403,6 @@ - - - - - - diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml index e1ac387fa..4f038e1a5 100644 --- a/java/res/values/strings.xml +++ b/java/res/values/strings.xml @@ -207,75 +207,6 @@ Phone symbols mode - - - - Voice input - - - Voice input is not currently supported for your language, but does work in English. - - - Voice input uses Google\'s speech recognition. The Mobile Privacy Policy applies. - - - To turn off voice input, go to input method settings. - - - To use voice input, press the microphone button. - - - Speak now - - - Working - - - - - - Error. Please try again. - - - Couldn\'t connect - - - Error, too much speech. - - - Audio problem - - - Server error - - - No speech heard - - - No matches found - - - Voice search not installed - - - Hint: Swipe across keyboard to speak - - - Hint: Next time, try speaking punctuation like \"period\", \"comma\", or \"question mark\". - - - Cancel - - - OK - Voice input key @@ -294,9 +225,6 @@ Voice input is disabled - - Select input method - Configure input methods diff --git a/java/res/xml-ar/keyboard_set.xml b/java/res/xml-ar/keyboard_set.xml index c37d128d7..88d320144 100644 --- a/java/res/xml-ar/keyboard_set.xml +++ b/java/res/xml-ar/keyboard_set.xml @@ -19,8 +19,7 @@ --> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> + xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"> getEnabledInputMethodSubtypeList( InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) { - if (!SUBTYPE_SUPPORTED) { - String[] languages = mLanguageSwitcherProxy.getEnabledLanguages( - allowsImplicitlySelectedSubtypes); - List subtypeList = - new ArrayList(); - for (String lang: languages) { - subtypeList.add(new InputMethodSubtypeCompatWrapper(0, 0, lang, KEYBOARD_MODE, "")); - } - return subtypeList; - } Object retval = CompatUtils.invoke(mImm, null, METHOD_getEnabledInputMethodSubtypeList, (imi != null ? imi.getInputMethodInfo() : null), allowsImplicitlySelectedSubtypes); if (retval == null || !(retval instanceof List) || ((List)retval).isEmpty()) { @@ -228,16 +199,10 @@ public class InputMethodManagerCompatWrapper { } public boolean switchToLastInputMethod(IBinder token) { - if (SubtypeSwitcher.getInstance().isDummyVoiceMode()) { - return true; - } return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToLastInputMethod, token); } public boolean switchToNextInputMethod(IBinder token, boolean onlyCurrentIme) { - if (SubtypeSwitcher.getInstance().isDummyVoiceMode()) { - return true; - } return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToNextInputMethod, token, onlyCurrentIme); } @@ -253,88 +218,6 @@ public class InputMethodManagerCompatWrapper { public void showInputMethodPicker() { if (mImm == null) return; - if (SUBTYPE_SUPPORTED) { - mImm.showInputMethodPicker(); - return; - } - - // The code below are based on {@link InputMethodManager#showInputMethodMenuInternal}. - - final InputMethodInfoCompatWrapper myImi = SubtypeUtils.getInputMethodInfo( - mLatinImePackageName); - final List myImsList = getEnabledInputMethodSubtypeList( - myImi, true); - final InputMethodSubtypeCompatWrapper currentIms = getCurrentInputMethodSubtype(); - final List imiList = getEnabledInputMethodList(); - imiList.remove(myImi); - final PackageManager pm = mPackageManager; - Collections.sort(imiList, new Comparator() { - @Override - public int compare(InputMethodInfoCompatWrapper imi1, - InputMethodInfoCompatWrapper imi2) { - final CharSequence imiId1 = imi1.loadLabel(pm) + "/" + imi1.getId(); - final CharSequence imiId2 = imi2.loadLabel(pm) + "/" + imi2.getId(); - return imiId1.toString().compareTo(imiId2.toString()); - } - }); - - final int myImsCount = myImsList.size(); - final int imiCount = imiList.size(); - final CharSequence[] items = new CharSequence[myImsCount + imiCount]; - - int checkedItem = 0; - int index = 0; - final CharSequence myImiLabel = myImi.loadLabel(mPackageManager); - for (int i = 0; i < myImsCount; i++) { - InputMethodSubtypeCompatWrapper ims = myImsList.get(i); - if (currentIms.equals(ims)) - checkedItem = index; - final CharSequence title = TextUtils.concat( - ims.getDisplayName(mService, mLatinImePackageName, mApplicationInfo), - " (" + myImiLabel, ")"); - items[index] = title; - index++; - } - - for (int i = 0; i < imiCount; i++) { - final InputMethodInfoCompatWrapper imi = imiList.get(i); - final CharSequence title = imi.loadLabel(mPackageManager); - items[index] = title; - index++; - } - - final InputMethodServiceCompatWrapper service = mService; - final OnClickListener buttonListener = new OnClickListener() { - @Override - public void onClick(DialogInterface di, int whichButton) { - final Intent intent = new Intent("android.settings.INPUT_METHOD_SETTINGS"); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED - | Intent.FLAG_ACTIVITY_CLEAR_TOP); - service.startActivity(intent); - } - }; - final IBinder token = service.getWindow().getWindow().getAttributes().token; - final OnClickListener selectionListener = new OnClickListener() { - @Override - public void onClick(DialogInterface di, int which) { - di.dismiss(); - if (which < myImsCount) { - final int imsIndex = which; - final InputMethodSubtypeCompatWrapper ims = myImsList.get(imsIndex); - service.notifyOnCurrentInputMethodSubtypeChanged(ims); - } else { - final int imiIndex = which - myImsCount; - final InputMethodInfoCompatWrapper imi = imiList.get(imiIndex); - setInputMethodAndSubtype(token, imi.getId(), null); - } - } - }; - - final AlertDialog.Builder builder = new AlertDialog.Builder(mService) - .setTitle(mService.getString(R.string.selectInputMethod)) - .setNeutralButton(R.string.configure_input_method, buttonListener) - .setSingleChoiceItems(items, checkedItem, selectionListener); - mService.showOptionDialogInternal(builder.create()); + mImm.showInputMethodPicker(); } } diff --git a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java index 8e2ee0f7a..7c15be300 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java @@ -23,7 +23,6 @@ import android.view.Window; import android.view.WindowManager; import android.view.inputmethod.InputMethodSubtype; -import com.android.inputmethod.deprecated.LanguageSwitcherProxy; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.latin.SubtypeSwitcher; @@ -87,9 +86,6 @@ public class InputMethodServiceCompatWrapper extends InputMethodService { if (subtype != null) { if (!InputMethodManagerCompatWrapper.FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES && !subtype.isDummy()) return; - if (!InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) { - LanguageSwitcherProxy.getInstance().setLocale(subtype.getLocale()); - } SubtypeSwitcher.getInstance().updateSubtype(subtype); } } diff --git a/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java deleted file mode 100644 index 290e6b554..000000000 --- a/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2011 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.deprecated; - -import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; -import com.android.inputmethod.deprecated.languageswitcher.LanguageSwitcher; -import com.android.inputmethod.latin.LatinIME; -import com.android.inputmethod.latin.Settings; - -import android.content.SharedPreferences; -import android.content.res.Configuration; - -import java.util.Locale; - -// This class is used only when the IME doesn't use method.xml for language switching. -public class LanguageSwitcherProxy implements SharedPreferences.OnSharedPreferenceChangeListener { - private static final LanguageSwitcherProxy sInstance = new LanguageSwitcherProxy(); - private LatinIME mService; - private LanguageSwitcher mLanguageSwitcher; - private SharedPreferences mPrefs; - - public static LanguageSwitcherProxy getInstance() { - if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return null; - return sInstance; - } - - public static void init(LatinIME service, SharedPreferences prefs) { - if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return; - final Configuration conf = service.getResources().getConfiguration(); - sInstance.mLanguageSwitcher = new LanguageSwitcher(service); - sInstance.mLanguageSwitcher.loadLocales(prefs, conf.locale); - sInstance.mPrefs = prefs; - sInstance.mService = service; - prefs.registerOnSharedPreferenceChangeListener(sInstance); - } - - public static void onConfigurationChanged(Configuration conf) { - if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return; - sInstance.mLanguageSwitcher.onConfigurationChanged(conf, sInstance.mPrefs); - } - - public static void loadSettings() { - if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return; - sInstance.mLanguageSwitcher.loadLocales(sInstance.mPrefs, null); - } - - public int getLocaleCount() { - return mLanguageSwitcher.getLocaleCount(); - } - - public String[] getEnabledLanguages(boolean allowImplicitlySelectedLanguages) { - return mLanguageSwitcher.getEnabledLanguages(allowImplicitlySelectedLanguages); - } - - public Locale getInputLocale() { - return mLanguageSwitcher.getInputLocale(); - } - - public void setLocale(String localeStr) { - mLanguageSwitcher.setLocale(localeStr); - mLanguageSwitcher.persist(mPrefs); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { - // PREF_SELECTED_LANGUAGES: enabled input subtypes - // PREF_INPUT_LANGUAGE: current input subtype - if (key.equals(Settings.PREF_SELECTED_LANGUAGES) - || key.equals(Settings.PREF_INPUT_LANGUAGE)) { - mLanguageSwitcher.loadLocales(prefs, null); - if (mService != null) { - mService.onRefreshKeyboard(); - } - } - } -} diff --git a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java deleted file mode 100644 index 87d1c118b..000000000 --- a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java +++ /dev/null @@ -1,854 +0,0 @@ -/* - * Copyright (C) 2010 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.deprecated; - -import android.app.AlertDialog; -import android.content.ContentResolver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Configuration; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.IBinder; -import android.preference.PreferenceManager; -import android.provider.Browser; -import android.speech.SpeechRecognizer; -import android.text.SpannableStringBuilder; -import android.text.Spanned; -import android.text.TextUtils; -import android.text.method.LinkMovementMethod; -import android.text.style.URLSpan; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewParent; -import android.view.Window; -import android.view.WindowManager; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.ExtractedTextRequest; -import android.view.inputmethod.InputConnection; -import android.widget.TextView; - -import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; -import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; -import com.android.inputmethod.compat.SharedPreferencesCompat; -import com.android.inputmethod.deprecated.voice.FieldContext; -import com.android.inputmethod.deprecated.voice.Hints; -import com.android.inputmethod.deprecated.voice.SettingsUtil; -import com.android.inputmethod.deprecated.voice.VoiceInput; -import com.android.inputmethod.keyboard.KeyboardSwitcher; -import com.android.inputmethod.keyboard.LatinKeyboardView; -import com.android.inputmethod.latin.EditingUtils; -import com.android.inputmethod.latin.LastComposedWord; -import com.android.inputmethod.latin.LatinIME; -import com.android.inputmethod.latin.LatinIME.UIHandler; -import com.android.inputmethod.latin.LatinImeLogger; -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.StringUtils; -import com.android.inputmethod.latin.SubtypeSwitcher; -import com.android.inputmethod.latin.Utils; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class VoiceProxy implements VoiceInput.UiListener { - private static final VoiceProxy sInstance = new VoiceProxy(); - - public static final boolean VOICE_INSTALLED = - !InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED; - private static final boolean ENABLE_VOICE_BUTTON = true; - private static final String PREF_VOICE_MODE = "voice_mode"; - // Whether or not the user has used voice input before (and thus, whether to show the - // first-run warning dialog or not). - private static final String PREF_HAS_USED_VOICE_INPUT = "has_used_voice_input"; - // Whether or not the user has used voice input from an unsupported locale UI before. - // For example, the user has a Chinese UI but activates voice input. - private static final String PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE = - "has_used_voice_input_unsupported_locale"; - private static final int RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO = 6; - // TODO: Adjusted on phones for now - private static final int RECOGNITIONVIEW_MINIMUM_HEIGHT_DIP = 244; - - private static final String TAG = VoiceProxy.class.getSimpleName(); - private static final boolean DEBUG = LatinImeLogger.sDBG; - - private boolean mAfterVoiceInput; - private boolean mConfigurationChanging; - private boolean mHasUsedVoiceInput; - private boolean mHasUsedVoiceInputUnsupportedLocale; - private boolean mImmediatelyAfterVoiceInput; - private boolean mIsShowingHint; - private boolean mLocaleSupportedForVoiceInput; - private boolean mPasswordText; - private boolean mRecognizing; - private boolean mShowingVoiceSuggestions; - private boolean mVoiceButtonEnabled; - private boolean mVoiceButtonOnPrimary; - private boolean mVoiceInputHighlighted; - - private int mMinimumVoiceRecognitionViewHeightPixel; - private InputMethodManagerCompatWrapper mImm; - private LatinIME mService; - private AlertDialog mVoiceWarningDialog; - private VoiceInput mVoiceInput; - private final VoiceResults mVoiceResults = new VoiceResults(); - private Hints mHints; - private UIHandler mHandler; - private SubtypeSwitcher mSubtypeSwitcher; - - // For each word, a list of potential replacements, usually from voice. - private final Map> mWordToSuggestions = - new HashMap>(); - - public static VoiceProxy init(LatinIME context, SharedPreferences prefs, UIHandler h) { - sInstance.initInternal(context, prefs, h); - return sInstance; - } - - public static VoiceProxy getInstance() { - return sInstance; - } - - private void initInternal(LatinIME service, SharedPreferences prefs, UIHandler h) { - if (!VOICE_INSTALLED) { - return; - } - mService = service; - mHandler = h; - mMinimumVoiceRecognitionViewHeightPixel = Utils.dipToPixel( - Utils.getDipScale(service), RECOGNITIONVIEW_MINIMUM_HEIGHT_DIP); - mImm = InputMethodManagerCompatWrapper.getInstance(); - mSubtypeSwitcher = SubtypeSwitcher.getInstance(); - mVoiceInput = new VoiceInput(service, this); - mHints = new Hints(service, prefs, new Hints.Display() { - @Override - public void showHint(int viewResource) { - View view = LayoutInflater.from(mService).inflate(viewResource, null); - mIsShowingHint = true; - } - }); - } - - private VoiceProxy() { - // Intentional empty constructor for singleton. - } - - public void resetVoiceStates(boolean isPasswordText) { - mAfterVoiceInput = false; - mImmediatelyAfterVoiceInput = false; - mShowingVoiceSuggestions = false; - mVoiceInputHighlighted = false; - mPasswordText = isPasswordText; - } - - public void flushVoiceInputLogs() { - if (!VOICE_INSTALLED) { - return; - } - if (!mConfigurationChanging) { - if (mAfterVoiceInput) { - mVoiceInput.flushAllTextModificationCounters(); - mVoiceInput.logInputEnded(); - } - mVoiceInput.flushLogs(); - mVoiceInput.cancel(); - } - } - - public void flushAndLogAllTextModificationCounters(int index, CharSequence suggestion, - String wordSeparators) { - if (!VOICE_INSTALLED) { - return; - } - if (mAfterVoiceInput && mShowingVoiceSuggestions) { - mVoiceInput.flushAllTextModificationCounters(); - // send this intent AFTER logging any prior aggregated edits. - mVoiceInput.logTextModifiedByChooseSuggestion(suggestion.toString(), index, - wordSeparators, mService.getCurrentInputConnection()); - } - } - - private void showVoiceWarningDialog(final boolean swipe, IBinder token) { - if (mVoiceWarningDialog != null && mVoiceWarningDialog.isShowing()) { - return; - } - AlertDialog.Builder builder = new UrlLinkAlertDialogBuilder(mService); - builder.setCancelable(true); - builder.setIcon(R.drawable.ic_mic_dialog); - builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int whichButton) { - mVoiceInput.logKeyboardWarningDialogOk(); - reallyStartListening(swipe); - } - }); - builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int whichButton) { - mVoiceInput.logKeyboardWarningDialogCancel(); - switchToLastInputMethod(); - } - }); - // When the dialog is dismissed by user's cancellation, switch back to the last input method - builder.setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface arg0) { - mVoiceInput.logKeyboardWarningDialogCancel(); - switchToLastInputMethod(); - } - }); - - final CharSequence message; - if (mLocaleSupportedForVoiceInput) { - message = TextUtils.concat( - mService.getText(R.string.voice_warning_may_not_understand), "\n\n", - mService.getText(R.string.voice_warning_how_to_turn_off)); - } else { - message = TextUtils.concat( - mService.getText(R.string.voice_warning_locale_not_supported), "\n\n", - mService.getText(R.string.voice_warning_may_not_understand), "\n\n", - mService.getText(R.string.voice_warning_how_to_turn_off)); - } - builder.setMessage(message); - builder.setTitle(R.string.voice_warning_title); - mVoiceWarningDialog = builder.create(); - final Window window = mVoiceWarningDialog.getWindow(); - final WindowManager.LayoutParams lp = window.getAttributes(); - lp.token = token; - lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; - window.setAttributes(lp); - window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); - mVoiceInput.logKeyboardWarningDialogShown(); - mVoiceWarningDialog.show(); - } - - private static class UrlLinkAlertDialogBuilder extends AlertDialog.Builder { - private AlertDialog mAlertDialog; - - public UrlLinkAlertDialogBuilder(Context context) { - super(context); - } - - @Override - public AlertDialog.Builder setMessage(CharSequence message) { - return super.setMessage(replaceURLSpan(message)); - } - - private Spanned replaceURLSpan(CharSequence message) { - // Replace all spans with the custom span - final SpannableStringBuilder ssb = new SpannableStringBuilder(message); - for (URLSpan span : ssb.getSpans(0, ssb.length(), URLSpan.class)) { - int spanStart = ssb.getSpanStart(span); - int spanEnd = ssb.getSpanEnd(span); - int spanFlags = ssb.getSpanFlags(span); - ssb.removeSpan(span); - ssb.setSpan(new ClickableSpan(span.getURL()), spanStart, spanEnd, spanFlags); - } - return ssb; - } - - @Override - public AlertDialog create() { - final AlertDialog dialog = super.create(); - - dialog.setOnShowListener(new DialogInterface.OnShowListener() { - @Override - public void onShow(DialogInterface dialogInterface) { - // Make URL in the dialog message click-able. - TextView textView = (TextView) mAlertDialog.findViewById(android.R.id.message); - if (textView != null) { - textView.setMovementMethod(LinkMovementMethod.getInstance()); - } - } - }); - mAlertDialog = dialog; - return dialog; - } - - class ClickableSpan extends URLSpan { - public ClickableSpan(String url) { - super(url); - } - - @Override - public void onClick(View widget) { - Uri uri = Uri.parse(getURL()); - Context context = widget.getContext(); - Intent intent = new Intent(Intent.ACTION_VIEW, uri); - // Add this flag to start an activity from service - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()); - // Dismiss the warning dialog and go back to the previous IME. - // TODO: If we can find a way to bring the new activity to front while keeping - // the warning dialog, we don't need to dismiss it here. - mAlertDialog.cancel(); - context.startActivity(intent); - } - } - } - - public void showPunctuationHintIfNecessary() { - if (!VOICE_INSTALLED) { - return; - } - InputConnection ic = mService.getCurrentInputConnection(); - if (!mImmediatelyAfterVoiceInput && mAfterVoiceInput && ic != null) { - if (mHints.showPunctuationHintIfNecessary(ic)) { - mVoiceInput.logPunctuationHintDisplayed(); - } - } - mImmediatelyAfterVoiceInput = false; - } - - public void hideVoiceWindow() { - if (!VOICE_INSTALLED) { - return; - } - if (!mConfigurationChanging) { - if (mAfterVoiceInput) - mVoiceInput.logInputEnded(); - if (mVoiceWarningDialog != null && mVoiceWarningDialog.isShowing()) { - mVoiceInput.logKeyboardWarningDialogDismissed(); - mVoiceWarningDialog.dismiss(); - mVoiceWarningDialog = null; - } - if (VOICE_INSTALLED & mRecognizing) { - mVoiceInput.cancel(); - } - } - mWordToSuggestions.clear(); - } - - public void setCursorAndSelection(int newSelEnd, int newSelStart) { - if (!VOICE_INSTALLED) { - return; - } - if (mAfterVoiceInput) { - mVoiceInput.setCursorPos(newSelEnd); - mVoiceInput.setSelectionSpan(newSelEnd - newSelStart); - } - } - - public void setVoiceInputHighlighted(boolean b) { - mVoiceInputHighlighted = b; - } - - public void setShowingVoiceSuggestions(boolean b) { - mShowingVoiceSuggestions = b; - } - - public boolean isVoiceButtonEnabled() { - return mVoiceButtonEnabled; - } - - public boolean isVoiceButtonOnPrimary() { - return mVoiceButtonOnPrimary; - } - - public boolean isVoiceInputHighlighted() { - return mVoiceInputHighlighted; - } - - public boolean isRecognizing() { - return mRecognizing; - } - - public boolean needsToShowWarningDialog() { - return !mHasUsedVoiceInput - || (!mLocaleSupportedForVoiceInput && !mHasUsedVoiceInputUnsupportedLocale); - } - - public boolean getAndResetIsShowingHint() { - boolean ret = mIsShowingHint; - mIsShowingHint = false; - return ret; - } - - private void revertVoiceInput() { - InputConnection ic = mService.getCurrentInputConnection(); - if (ic != null) ic.commitText("", 1); - mService.updateSuggestions(); - mVoiceInputHighlighted = false; - } - - public void commitVoiceInput() { - if (VOICE_INSTALLED && mVoiceInputHighlighted) { - InputConnection ic = mService.getCurrentInputConnection(); - if (ic != null) ic.finishComposingText(); - mService.updateSuggestions(); - mVoiceInputHighlighted = false; - } - } - - public boolean logAndRevertVoiceInput() { - if (!VOICE_INSTALLED) { - return false; - } - if (mVoiceInputHighlighted) { - mVoiceInput.incrementTextModificationDeleteCount( - mVoiceResults.candidates.get(0).toString().length()); - revertVoiceInput(); - return true; - } else { - return false; - } - } - - public void rememberReplacedWord(CharSequence suggestion,String wordSeparators) { - if (!VOICE_INSTALLED) { - return; - } - if (mShowingVoiceSuggestions) { - // Retain the replaced word in the alternatives array. - String wordToBeReplaced = EditingUtils.getWordAtCursor( - mService.getCurrentInputConnection(), wordSeparators); - if (!mWordToSuggestions.containsKey(wordToBeReplaced)) { - wordToBeReplaced = wordToBeReplaced.toLowerCase(); - } - if (mWordToSuggestions.containsKey(wordToBeReplaced)) { - List suggestions = mWordToSuggestions.get(wordToBeReplaced); - if (suggestions.contains(suggestion)) { - suggestions.remove(suggestion); - } - suggestions.add(wordToBeReplaced); - mWordToSuggestions.remove(wordToBeReplaced); - mWordToSuggestions.put(suggestion.toString(), suggestions); - } - } - } - - public void handleBackspace() { - if (!VOICE_INSTALLED) { - return; - } - if (mAfterVoiceInput) { - // Don't log delete if the user is pressing delete at - // the beginning of the text box (hence not deleting anything) - if (mVoiceInput.getCursorPos() > 0) { - // If anything was selected before the delete was pressed, increment the - // delete count by the length of the selection - int deleteLen = mVoiceInput.getSelectionSpan() > 0 ? - mVoiceInput.getSelectionSpan() : 1; - mVoiceInput.incrementTextModificationDeleteCount(deleteLen); - } - } - } - - public void handleCharacter() { - if (!VOICE_INSTALLED) { - return; - } - commitVoiceInput(); - if (mAfterVoiceInput) { - // Assume input length is 1. This assumption fails for smiley face insertions. - mVoiceInput.incrementTextModificationInsertCount(1); - } - } - - public void handleSeparator() { - if (!VOICE_INSTALLED) { - return; - } - commitVoiceInput(); - if (mAfterVoiceInput){ - // Assume input length is 1. This assumption fails for smiley face insertions. - mVoiceInput.incrementTextModificationInsertPunctuationCount(1); - } - } - - public void handleClose() { - if (!VOICE_INSTALLED) { - return; - } - if (mRecognizing) { - mVoiceInput.cancel(); - } - } - - - public void handleVoiceResults(boolean capitalizeFirstWord) { - if (!VOICE_INSTALLED) { - return; - } - mAfterVoiceInput = true; - mImmediatelyAfterVoiceInput = true; - - InputConnection ic = mService.getCurrentInputConnection(); - if (!mService.isFullscreenMode()) { - // Start listening for updates to the text from typing, etc. - if (ic != null) { - ExtractedTextRequest req = new ExtractedTextRequest(); - ic.getExtractedText(req, InputConnection.GET_EXTRACTED_TEXT_MONITOR); - } - } - mService.vibrate(); - - final List nBest = new ArrayList(); - for (String c : mVoiceResults.candidates) { - if (capitalizeFirstWord) { - c = Character.toUpperCase(c.charAt(0)) + c.substring(1, c.length()); - } - nBest.add(c); - } - if (nBest.size() == 0) { - return; - } - String bestResult = nBest.get(0).toString(); - mVoiceInput.logVoiceInputDelivered(bestResult.length()); - mHints.registerVoiceResult(bestResult); - - if (ic != null) ic.beginBatchEdit(); // To avoid extra updates on committing older text - mService.commitTyped(ic, LastComposedWord.NOT_A_SEPARATOR); - EditingUtils.appendText(ic, bestResult); - if (ic != null) ic.endBatchEdit(); - - mVoiceInputHighlighted = true; - mWordToSuggestions.putAll(mVoiceResults.alternatives); - onCancelVoice(); - } - - public void switchToRecognitionStatusView(final Configuration configuration) { - if (!VOICE_INSTALLED) { - return; - } - mHandler.post(new Runnable() { - @Override - public void run() { -// mService.setCandidatesViewShown(false); - mRecognizing = true; - mVoiceInput.newView(); - View v = mVoiceInput.getView(); - - ViewParent p = v.getParent(); - if (p != null && p instanceof ViewGroup) { - ((ViewGroup) p).removeView(v); - } - - View keyboardView = KeyboardSwitcher.getInstance().getKeyboardView(); - - // The full height of the keyboard is difficult to calculate - // as the dimension is expressed in "mm" and not in "pixel" - // As we add mm, we don't know how the rounding is going to work - // thus we may end up with few pixels extra (or less). - if (keyboardView != null) { - View popupLayout = v.findViewById(R.id.popup_layout); - final int displayHeight = - mService.getResources().getDisplayMetrics().heightPixels; - final int currentHeight = popupLayout.getLayoutParams().height; - final int keyboardHeight = keyboardView.getHeight(); - if (mMinimumVoiceRecognitionViewHeightPixel > keyboardHeight - || mMinimumVoiceRecognitionViewHeightPixel > currentHeight) { - popupLayout.getLayoutParams().height = - mMinimumVoiceRecognitionViewHeightPixel; - } else if (keyboardHeight > currentHeight || keyboardHeight - > (displayHeight / RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO)) { - popupLayout.getLayoutParams().height = keyboardHeight; - } - } - mService.setInputView(v); - mService.updateInputViewShown(); - - if (configuration != null) { - mVoiceInput.onConfigurationChanged(configuration); - } - }}); - } - - private void switchToLastInputMethod() { - if (!VOICE_INSTALLED) { - return; - } - final IBinder token = mService.getWindow().getWindow().getAttributes().token; - new AsyncTask() { - @Override - protected Boolean doInBackground(Void... params) { - return mImm.switchToLastInputMethod(token); - } - - @Override - protected void onPostExecute(Boolean result) { - // Calls in this method need to be done in the same thread as the thread which - // called switchToLastInputMethod() - if (!result) { - if (DEBUG) { - Log.d(TAG, "Couldn't switch back to last IME."); - } - // Because the current IME and subtype failed to switch to any other IME and - // subtype by switchToLastInputMethod, the current IME and subtype should keep - // being LatinIME and voice subtype in the next time. And for re-showing voice - // mode, the state of voice input should be reset and the voice view should be - // hidden. - mVoiceInput.reset(); - mService.requestHideSelf(0); - } else { - // Notify an event that the current subtype was changed. This event will be - // handled if "onCurrentInputMethodSubtypeChanged" can't be implemented - // when the API level is 10 or previous. - mService.notifyOnCurrentInputMethodSubtypeChanged(null); - } - } - }.execute(); - } - - private void reallyStartListening(boolean swipe) { - if (!VOICE_INSTALLED) { - return; - } - if (!mHasUsedVoiceInput) { - // The user has started a voice input, so remember that in the - // future (so we don't show the warning dialog after the first run). - SharedPreferences.Editor editor = - PreferenceManager.getDefaultSharedPreferences(mService).edit(); - editor.putBoolean(PREF_HAS_USED_VOICE_INPUT, true); - SharedPreferencesCompat.apply(editor); - mHasUsedVoiceInput = true; - } - - if (!mLocaleSupportedForVoiceInput && !mHasUsedVoiceInputUnsupportedLocale) { - // The user has started a voice input from an unsupported locale, so remember that - // in the future (so we don't show the warning dialog the next time they do this). - SharedPreferences.Editor editor = - PreferenceManager.getDefaultSharedPreferences(mService).edit(); - editor.putBoolean(PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE, true); - SharedPreferencesCompat.apply(editor); - mHasUsedVoiceInputUnsupportedLocale = true; - } - - // Clear N-best suggestions - mService.clearSuggestions(); - - FieldContext context = makeFieldContext(); - mVoiceInput.startListening(context, swipe); - switchToRecognitionStatusView(null); - } - - public void startListening(final boolean swipe, IBinder token) { - if (!VOICE_INSTALLED) { - return; - } - // TODO: remove swipe which is no longer used. - if (needsToShowWarningDialog()) { - // Calls reallyStartListening if user clicks OK, does nothing if user clicks Cancel. - showVoiceWarningDialog(swipe, token); - } else { - reallyStartListening(swipe); - } - } - - private boolean fieldCanDoVoice(FieldContext fieldContext) { - return !mPasswordText - && mVoiceInput != null - && !mVoiceInput.isBlacklistedField(fieldContext); - } - - private boolean shouldShowVoiceButton(FieldContext fieldContext, EditorInfo editorInfo) { - @SuppressWarnings("deprecation") - final boolean noMic = StringUtils.inPrivateImeOptions(null, - LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo) - || StringUtils.inPrivateImeOptions(mService.getPackageName(), - LatinIME.IME_OPTION_NO_MICROPHONE, editorInfo); - return ENABLE_VOICE_BUTTON && fieldCanDoVoice(fieldContext) && !noMic - && SpeechRecognizer.isRecognitionAvailable(mService); - } - - public static boolean isRecognitionAvailable(Context context) { - return SpeechRecognizer.isRecognitionAvailable(context); - } - - public void loadSettings(EditorInfo editorInfo, SharedPreferences sp) { - if (!VOICE_INSTALLED) { - return; - } - mHasUsedVoiceInput = sp.getBoolean(PREF_HAS_USED_VOICE_INPUT, false); - mHasUsedVoiceInputUnsupportedLocale = - sp.getBoolean(PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE, false); - - mLocaleSupportedForVoiceInput = SubtypeSwitcher.isVoiceSupported( - mService, SubtypeSwitcher.getInstance().getInputLocaleStr()); - - final String voiceMode = sp.getString(PREF_VOICE_MODE, - mService.getString(R.string.voice_mode_main)); - mVoiceButtonEnabled = !voiceMode.equals(mService.getString(R.string.voice_mode_off)) - && shouldShowVoiceButton(makeFieldContext(), editorInfo); - mVoiceButtonOnPrimary = voiceMode.equals(mService.getString(R.string.voice_mode_main)); - } - - public void destroy() { - if (!VOICE_INSTALLED) { - return; - } - if (mVoiceInput != null) { - mVoiceInput.destroy(); - } - } - - public void onStartInputView(IBinder keyboardViewToken) { - if (!VOICE_INSTALLED) { - return; - } - // If keyboardViewToken is null, keyboardView is not attached but voiceView is attached. - IBinder windowToken = keyboardViewToken != null ? keyboardViewToken - : mVoiceInput.getView().getWindowToken(); - // If IME is in voice mode, but still needs to show the voice warning dialog, - // keep showing the warning. - if (mSubtypeSwitcher.isVoiceMode() && windowToken != null) { - // Close keyboard view if it is been shown. - final LatinKeyboardView keyboardView = KeyboardSwitcher.getInstance().getKeyboardView(); - if (keyboardView != null && keyboardView.isShown()) - keyboardView.purgeKeyboardAndClosing(); - startListening(false, windowToken); - } - // If we have no token, onAttachedToWindow will take care of showing dialog and start - // listening. - } - - public void onAttachedToWindow() { - if (!VOICE_INSTALLED) { - return; - } - // After onAttachedToWindow, we can show the voice warning dialog. See startListening() - // above. - VoiceInputWrapper.getInstance().setVoiceInput(mVoiceInput, mSubtypeSwitcher); - } - - public void onConfigurationChanged(Configuration configuration) { - if (!VOICE_INSTALLED) { - return; - } - if (mRecognizing) { - switchToRecognitionStatusView(configuration); - } - } - - @Override - public void onCancelVoice() { - if (!VOICE_INSTALLED) { - return; - } - if (mRecognizing) { - if (mSubtypeSwitcher.isVoiceMode()) { - // If voice mode is being canceled within LatinIME (i.e. time-out or user - // cancellation etc.), onCancelVoice() will be called first. LatinIME thinks it's - // still in voice mode. LatinIME needs to call switchToLastInputMethod(). - // Note that onCancelVoice() will be called again from SubtypeSwitcher. - switchToLastInputMethod(); - } else if (mSubtypeSwitcher.isKeyboardMode()) { - // If voice mode is being canceled out of LatinIME (i.e. by user's IME switching or - // as a result of switchToLastInputMethod() etc.), - // onCurrentInputMethodSubtypeChanged() will be called first. LatinIME will know - // that it's in keyboard mode and SubtypeSwitcher will call onCancelVoice(). - mRecognizing = false; - mService.switchToKeyboardView(); - } - } - } - - @Override - public void onVoiceResults(List candidates, - Map> alternatives) { - if (!VOICE_INSTALLED) { - return; - } - if (!mRecognizing) { - return; - } - mVoiceResults.candidates = candidates; - mVoiceResults.alternatives = alternatives; - mHandler.updateVoiceResults(); - } - - private FieldContext makeFieldContext() { - SubtypeSwitcher switcher = SubtypeSwitcher.getInstance(); - return new FieldContext(mService.getCurrentInputConnection(), - mService.getCurrentInputEditorInfo(), switcher.getInputLocaleStr(), - switcher.getEnabledLanguages()); - } - - // TODO: make this private (proguard issue) - public static class VoiceResults { - List candidates; - Map> alternatives; - } - - public static class VoiceInputWrapper { - private static final VoiceInputWrapper sInputWrapperInstance = new VoiceInputWrapper(); - private VoiceInput mVoiceInput; - public static VoiceInputWrapper getInstance() { - return sInputWrapperInstance; - } - private void setVoiceInput(VoiceInput voiceInput, SubtypeSwitcher switcher) { - if (!VOICE_INSTALLED) { - return; - } - if (mVoiceInput == null && voiceInput != null) { - mVoiceInput = voiceInput; - } - switcher.setVoiceInputWrapper(this); - } - - private VoiceInputWrapper() { - } - - public void cancel() { - if (!VOICE_INSTALLED) { - return; - } - if (mVoiceInput != null) mVoiceInput.cancel(); - } - - public void reset() { - if (!VOICE_INSTALLED) { - return; - } - if (mVoiceInput != null) mVoiceInput.reset(); - } - } - - // A list of locales which are supported by default for voice input, unless we get a - // different list from Gservices. - private static final String DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES = - "en " + - "en_US " + - "en_GB " + - "en_AU " + - "en_CA " + - "en_IE " + - "en_IN " + - "en_NZ " + - "en_SG " + - "en_ZA "; - - public static String getSupportedLocalesString (ContentResolver resolver) { - return SettingsUtil.getSettingsString( - resolver, - SettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES, - DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES); - } - - public void startChangingConfiguration() { - mConfigurationChanging = true; - } - - public void finishChangingConfiguration() { - mConfigurationChanging = false; - } -} diff --git a/java/src/com/android/inputmethod/deprecated/compat/VoiceInputLoggerCompatUtils.java b/java/src/com/android/inputmethod/deprecated/compat/VoiceInputLoggerCompatUtils.java deleted file mode 100644 index 488390fbc..000000000 --- a/java/src/com/android/inputmethod/deprecated/compat/VoiceInputLoggerCompatUtils.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2011 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.deprecated.compat; - -import com.android.common.userhappiness.UserHappinessSignals; -import com.android.inputmethod.compat.CompatUtils; - -import java.lang.reflect.Method; - -public class VoiceInputLoggerCompatUtils { - public static final String EXTRA_TEXT_REPLACED_LENGTH = "length"; - public static final String EXTRA_BEFORE_N_BEST_CHOOSE = "before"; - public static final String EXTRA_AFTER_N_BEST_CHOOSE = "after"; - private static final Method METHOD_UserHappinessSignals_setHasVoiceLoggingInfo = - CompatUtils.getMethod(UserHappinessSignals.class, "setHasVoiceLoggingInfo", - boolean.class); - - public static void setHasVoiceLoggingInfoCompat(boolean hasLoggingInfo) { - CompatUtils.invoke(null, null, METHOD_UserHappinessSignals_setHasVoiceLoggingInfo, - hasLoggingInfo); - } -} diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java deleted file mode 100644 index 421ee6529..000000000 --- a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2008-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 - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.inputmethod.deprecated.languageswitcher; - -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.content.res.Resources; -import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.PreferenceActivity; -import android.preference.PreferenceGroup; -import android.preference.PreferenceManager; -import android.text.TextUtils; -import android.util.Pair; - -import com.android.inputmethod.compat.SharedPreferencesCompat; -import com.android.inputmethod.keyboard.KeyboardSet; -import com.android.inputmethod.latin.DictionaryFactory; -import com.android.inputmethod.latin.LocaleUtils; -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.Settings; -import com.android.inputmethod.latin.StringUtils; - -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.text.Collator; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map.Entry; -import java.util.TreeMap; - -public class InputLanguageSelection extends PreferenceActivity { - - private SharedPreferences mPrefs; - private String mSelectedLanguages; - private HashMap mLocaleMap = - new HashMap(); - - private static class LocaleEntry implements Comparable { - private static Collator sCollator = Collator.getInstance(); - - private String mLabel; - public final Locale mLocale; - - public LocaleEntry(String label, Locale locale) { - this.mLabel = label; - this.mLocale = locale; - } - - @Override - public String toString() { - return this.mLabel; - } - - @Override - public int compareTo(Object o) { - return sCollator.compare(this.mLabel, ((LocaleEntry) o).mLabel); - } - } - - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(icicle); - addPreferencesFromResource(R.xml.language_prefs); - // Get the settings preferences - mPrefs = PreferenceManager.getDefaultSharedPreferences(this); - mSelectedLanguages = mPrefs.getString(Settings.PREF_SELECTED_LANGUAGES, ""); - String[] languageList = mSelectedLanguages.split(","); - ArrayList availableLanguages = getUniqueLocales(); - PreferenceGroup parent = getPreferenceScreen(); - final HashMap dictionaryIdLocaleMap = new HashMap(); - final TreeMap localeHasDictionaryMap = - new TreeMap(); - for (int i = 0; i < availableLanguages.size(); i++) { - LocaleEntry loc = availableLanguages.get(i); - Locale locale = loc.mLocale; - final Pair hasDictionaryOrLayout = hasDictionaryOrLayout(locale); - final Long dictionaryId = hasDictionaryOrLayout.first; - final boolean hasLayout = hasDictionaryOrLayout.second; - final boolean hasDictionary = dictionaryId != null; - // Add this locale to the supported list if: - // 1) this locale has a layout/ 2) this locale has a dictionary - // If some locales have no layout but have a same dictionary, the shortest locale - // will be added to the supported list. - if (!hasLayout && !hasDictionary) { - continue; - } - if (hasLayout) { - localeHasDictionaryMap.put(loc, hasDictionary); - } - if (!hasDictionary) { - continue; - } - if (dictionaryIdLocaleMap.containsKey(dictionaryId)) { - final String newLocale = locale.toString(); - final String oldLocale = - dictionaryIdLocaleMap.get(dictionaryId).mLocale.toString(); - // Check if this locale is more appropriate to be the candidate of the input locale. - if (oldLocale.length() <= newLocale.length() && !hasLayout) { - // Don't add this new locale to the map if: - // 1) the new locale's name is longer than the existing one, and - // 2) the new locale doesn't have its layout - continue; - } - } - dictionaryIdLocaleMap.put(dictionaryId, loc); - } - - for (LocaleEntry localeEntry : dictionaryIdLocaleMap.values()) { - if (!localeHasDictionaryMap.containsKey(localeEntry)) { - localeHasDictionaryMap.put(localeEntry, true); - } - } - - for (Entry entry : localeHasDictionaryMap.entrySet()) { - final LocaleEntry localeEntry = entry.getKey(); - final Locale locale = localeEntry.mLocale; - final Boolean hasDictionary = entry.getValue(); - CheckBoxPreference pref = new CheckBoxPreference(this); - pref.setTitle(localeEntry.mLabel); - boolean checked = isLocaleIn(locale, languageList); - pref.setChecked(checked); - if (hasDictionary) { - pref.setSummary(R.string.has_dictionary); - } - mLocaleMap.put(pref, locale); - parent.addPreference(pref); - } - } - - private boolean isLocaleIn(Locale locale, String[] list) { - String lang = get5Code(locale); - for (int i = 0; i < list.length; i++) { - if (lang.equalsIgnoreCase(list[i])) return true; - } - return false; - } - - private Pair hasDictionaryOrLayout(Locale locale) { - if (locale == null) return new Pair(null, false); - final Resources res = getResources(); - final Locale saveLocale = LocaleUtils.setSystemLocale(res, locale); - final Long dictionaryId = DictionaryFactory.getDictionaryId(this, locale); - boolean hasLayout = false; - - try { - final String localeStr = locale.toString(); - final String[] layoutCountryCodes = KeyboardSet.parseKeyboardLocale( - getResources(), R.xml.keyboard_set).split(",", -1); - if (!TextUtils.isEmpty(localeStr) && layoutCountryCodes.length > 0) { - for (String s : layoutCountryCodes) { - if (s.equals(localeStr)) { - hasLayout = true; - break; - } - } - } - } catch (XmlPullParserException e) { - } catch (IOException e) { - } - LocaleUtils.setSystemLocale(res, saveLocale); - return new Pair(dictionaryId, hasLayout); - } - - private String get5Code(Locale locale) { - String country = locale.getCountry(); - return locale.getLanguage() - + (TextUtils.isEmpty(country) ? "" : "_" + country); - } - - @Override - protected void onResume() { - super.onResume(); - } - - @Override - protected void onPause() { - super.onPause(); - // Save the selected languages - String checkedLanguages = ""; - PreferenceGroup parent = getPreferenceScreen(); - int count = parent.getPreferenceCount(); - for (int i = 0; i < count; i++) { - CheckBoxPreference pref = (CheckBoxPreference) parent.getPreference(i); - if (pref.isChecked()) { - checkedLanguages += get5Code(mLocaleMap.get(pref)) + ","; - } - } - if (checkedLanguages.length() < 1) checkedLanguages = null; // Save null - Editor editor = mPrefs.edit(); - editor.putString(Settings.PREF_SELECTED_LANGUAGES, checkedLanguages); - SharedPreferencesCompat.apply(editor); - } - - public ArrayList getUniqueLocales() { - String[] locales = getAssets().getLocales(); - Arrays.sort(locales); - ArrayList uniqueLocales = new ArrayList(); - - final int origSize = locales.length; - LocaleEntry[] preprocess = new LocaleEntry[origSize]; - int finalSize = 0; - for (int i = 0 ; i < origSize; i++ ) { - String s = locales[i]; - int len = s.length(); - String language = ""; - String country = ""; - if (len == 5) { - language = s.substring(0, 2); - country = s.substring(3, 5); - } else if (len < 5) { - language = s; - } - Locale l = new Locale(language, country); - - // Exclude languages that are not relevant to LatinIME - if (TextUtils.isEmpty(language)) { - continue; - } - - if (finalSize == 0) { - preprocess[finalSize++] = - new LocaleEntry(StringUtils.getFullDisplayName(l, false), l); - } else { - if (s.equals("zz_ZZ")) { - // ignore this locale - } else { - final String displayName = StringUtils.getFullDisplayName(l, false); - preprocess[finalSize++] = new LocaleEntry(displayName, l); - } - } - } - for (int i = 0; i < finalSize ; i++) { - uniqueLocales.add(preprocess[i]); - } - return uniqueLocales; - } -} diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java deleted file mode 100644 index 7e2627c81..000000000 --- a/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) 2010 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.deprecated.languageswitcher; - -import com.android.inputmethod.compat.SharedPreferencesCompat; -import com.android.inputmethod.latin.LatinIME; -import com.android.inputmethod.latin.LatinImeLogger; -import com.android.inputmethod.latin.LocaleUtils; -import com.android.inputmethod.latin.Settings; - -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.content.res.Configuration; -import android.text.TextUtils; -import android.util.Log; - -import java.util.ArrayList; -import java.util.Locale; - -/** - * Keeps track of list of selected input languages and the current - * input language that the user has selected. - */ -public class LanguageSwitcher { - private static final String TAG = LanguageSwitcher.class.getSimpleName(); - - @SuppressWarnings("unused") - private static final String KEYBOARD_MODE = "keyboard"; - private static final String[] EMPTY_STIRNG_ARRAY = new String[0]; - - private final ArrayList mLocales = new ArrayList(); - private final LatinIME mIme; - private String[] mSelectedLanguageArray = EMPTY_STIRNG_ARRAY; - private String mSelectedLanguages; - private int mCurrentIndex = 0; - private String mDefaultInputLanguage; - private Locale mDefaultInputLocale; - private Locale mSystemLocale; - - public LanguageSwitcher(LatinIME ime) { - mIme = ime; - } - - public int getLocaleCount() { - return mLocales.size(); - } - - public void onConfigurationChanged(Configuration conf, SharedPreferences prefs) { - final Locale newLocale = conf.locale; - if (!getSystemLocale().toString().equals(newLocale.toString())) { - loadLocales(prefs, newLocale); - } - } - - /** - * Loads the currently selected input languages from shared preferences. - * @param sp shared preference for getting the current input language and enabled languages - * @param systemLocale the current system locale, stored for changing the current input language - * based on the system current system locale. - * @return whether there was any change - */ - public boolean loadLocales(SharedPreferences sp, Locale systemLocale) { - if (LatinImeLogger.sDBG) { - Log.d(TAG, "load locales"); - } - if (systemLocale != null) { - setSystemLocale(systemLocale); - } - String selectedLanguages = sp.getString(Settings.PREF_SELECTED_LANGUAGES, null); - String currentLanguage = sp.getString(Settings.PREF_INPUT_LANGUAGE, null); - if (TextUtils.isEmpty(selectedLanguages)) { - mSelectedLanguageArray = EMPTY_STIRNG_ARRAY; - mSelectedLanguages = null; - loadDefaults(); - if (mLocales.size() == 0) { - return false; - } - mLocales.clear(); - return true; - } - if (selectedLanguages.equals(mSelectedLanguages)) { - return false; - } - mSelectedLanguageArray = selectedLanguages.split(","); - mSelectedLanguages = selectedLanguages; // Cache it for comparison later - constructLocales(); - mCurrentIndex = 0; - if (currentLanguage != null) { - // Find the index - mCurrentIndex = 0; - for (int i = 0; i < mLocales.size(); i++) { - if (mSelectedLanguageArray[i].equals(currentLanguage)) { - mCurrentIndex = i; - break; - } - } - // If we didn't find the index, use the first one - } - return true; - } - - private void loadDefaults() { - if (LatinImeLogger.sDBG) { - Log.d(TAG, "load default locales:"); - } - mDefaultInputLocale = mIme.getResources().getConfiguration().locale; - String country = mDefaultInputLocale.getCountry(); - mDefaultInputLanguage = mDefaultInputLocale.getLanguage() + - (TextUtils.isEmpty(country) ? "" : "_" + country); - } - - private void constructLocales() { - mLocales.clear(); - for (final String lang : mSelectedLanguageArray) { - final Locale locale = LocaleUtils.constructLocaleFromString(lang); - mLocales.add(locale); - } - } - - /** - * Returns the currently selected input language code, or the display language code if - * no specific locale was selected for input. - */ - public String getInputLanguage() { - if (getLocaleCount() == 0) return mDefaultInputLanguage; - - return mSelectedLanguageArray[mCurrentIndex]; - } - - /** - * Returns the list of enabled language codes. - */ - public String[] getEnabledLanguages(boolean allowImplicitlySelectedLanguages) { - if (mSelectedLanguageArray.length == 0 && allowImplicitlySelectedLanguages) { - return new String[] { mDefaultInputLanguage }; - } - return mSelectedLanguageArray; - } - - /** - * Returns the currently selected input locale, or the display locale if no specific - * locale was selected for input. - */ - public Locale getInputLocale() { - if (getLocaleCount() == 0) return mDefaultInputLocale; - - return mLocales.get(mCurrentIndex); - } - - private int nextLocaleIndex() { - final int size = mLocales.size(); - return (mCurrentIndex + 1) % size; - } - - private int prevLocaleIndex() { - final int size = mLocales.size(); - return (mCurrentIndex - 1 + size) % size; - } - - /** - * Returns the next input locale in the list. Wraps around to the beginning of the - * list if we're at the end of the list. - */ - public Locale getNextInputLocale() { - if (getLocaleCount() == 0) return mDefaultInputLocale; - return mLocales.get(nextLocaleIndex()); - } - - /** - * Sets the system locale (display UI) used for comparing with the input language. - * @param locale the locale of the system - */ - private void setSystemLocale(Locale locale) { - mSystemLocale = locale; - } - - /** - * Returns the system locale. - * @return the system locale - */ - private Locale getSystemLocale() { - return mSystemLocale; - } - - /** - * Returns the previous input locale in the list. Wraps around to the end of the - * list if we're at the beginning of the list. - */ - public Locale getPrevInputLocale() { - if (getLocaleCount() == 0) return mDefaultInputLocale; - return mLocales.get(prevLocaleIndex()); - } - - public void reset() { - mCurrentIndex = 0; - } - - public void next() { - mCurrentIndex = nextLocaleIndex(); - } - - public void prev() { - mCurrentIndex = prevLocaleIndex(); - } - - public void setLocale(String localeStr) { - final int N = mLocales.size(); - for (int i = 0; i < N; ++i) { - if (mLocales.get(i).toString().equals(localeStr)) { - mCurrentIndex = i; - } - } - } - - public void persist(SharedPreferences prefs) { - Editor editor = prefs.edit(); - editor.putString(Settings.PREF_INPUT_LANGUAGE, getInputLanguage()); - SharedPreferencesCompat.apply(editor); - } -} diff --git a/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java deleted file mode 100644 index fd2cf3d25..000000000 --- a/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.inputmethod.deprecated.voice; - -import android.os.Bundle; -import android.util.Log; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.ExtractedText; -import android.view.inputmethod.ExtractedTextRequest; -import android.view.inputmethod.InputConnection; - -/** - * Represents information about a given text field, which can be passed - * to the speech recognizer as context information. - */ -public class FieldContext { - private static final boolean DBG = false; - - static final String LABEL = "label"; - static final String HINT = "hint"; - static final String PACKAGE_NAME = "packageName"; - static final String FIELD_ID = "fieldId"; - static final String FIELD_NAME = "fieldName"; - static final String SINGLE_LINE = "singleLine"; - static final String INPUT_TYPE = "inputType"; - static final String IME_OPTIONS = "imeOptions"; - static final String SELECTED_LANGUAGE = "selectedLanguage"; - static final String ENABLED_LANGUAGES = "enabledLanguages"; - - Bundle mFieldInfo; - - public FieldContext(InputConnection conn, EditorInfo editorInfo, - String selectedLanguage, String[] enabledLanguages) { - mFieldInfo = new Bundle(); - addEditorInfoToBundle(editorInfo, mFieldInfo); - addInputConnectionToBundle(conn, mFieldInfo); - addLanguageInfoToBundle(selectedLanguage, enabledLanguages, mFieldInfo); - if (DBG) Log.i("FieldContext", "Bundle = " + mFieldInfo.toString()); - } - - private static String safeToString(Object o) { - if (o == null) { - return ""; - } - return o.toString(); - } - - private static void addEditorInfoToBundle(EditorInfo info, Bundle bundle) { - if (info == null) { - return; - } - - bundle.putString(LABEL, safeToString(info.label)); - bundle.putString(HINT, safeToString(info.hintText)); - bundle.putString(PACKAGE_NAME, safeToString(info.packageName)); - bundle.putInt(FIELD_ID, info.fieldId); - bundle.putString(FIELD_NAME, safeToString(info.fieldName)); - bundle.putInt(INPUT_TYPE, info.inputType); - bundle.putInt(IME_OPTIONS, info.imeOptions); - } - - @SuppressWarnings("static-access") - private static void addInputConnectionToBundle( - InputConnection conn, Bundle bundle) { - if (conn == null) { - return; - } - - ExtractedText et = conn.getExtractedText(new ExtractedTextRequest(), 0); - if (et == null) { - return; - } - bundle.putBoolean(SINGLE_LINE, (et.flags & et.FLAG_SINGLE_LINE) > 0); - } - - private static void addLanguageInfoToBundle( - String selectedLanguage, String[] enabledLanguages, Bundle bundle) { - bundle.putString(SELECTED_LANGUAGE, selectedLanguage); - bundle.putStringArray(ENABLED_LANGUAGES, enabledLanguages); - } - - public Bundle getBundle() { - return mFieldInfo; - } - - @Override - public String toString() { - return mFieldInfo.toString(); - } -} diff --git a/java/src/com/android/inputmethod/deprecated/voice/Hints.java b/java/src/com/android/inputmethod/deprecated/voice/Hints.java deleted file mode 100644 index 17a19bf23..000000000 --- a/java/src/com/android/inputmethod/deprecated/voice/Hints.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 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 - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.inputmethod.deprecated.voice; - -import com.android.inputmethod.compat.SharedPreferencesCompat; -import com.android.inputmethod.latin.R; - -import android.content.ContentResolver; -import android.content.Context; -import android.content.SharedPreferences; -import android.view.inputmethod.InputConnection; - -import java.util.Calendar; -import java.util.HashMap; -import java.util.Map; - -/** - * Logic to determine when to display hints on usage to the user. - */ -public class Hints { - public interface Display { - public void showHint(int viewResource); - } - - private static final String PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN = - "voice_hint_num_unique_days_shown"; - private static final String PREF_VOICE_HINT_LAST_TIME_SHOWN = - "voice_hint_last_time_shown"; - private static final String PREF_VOICE_INPUT_LAST_TIME_USED = - "voice_input_last_time_used"; - private static final String PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT = - "voice_punctuation_hint_view_count"; - private static final int DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW = 7; - private static final int DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS = 7; - - private final Context mContext; - private final SharedPreferences mPrefs; - private final Display mDisplay; - private boolean mVoiceResultContainedPunctuation; - private int mSwipeHintMaxDaysToShow; - private int mPunctuationHintMaxDisplays; - - // Only show punctuation hint if voice result did not contain punctuation. - static final Map SPEAKABLE_PUNCTUATION - = new HashMap(); - static { - SPEAKABLE_PUNCTUATION.put(",", "comma"); - SPEAKABLE_PUNCTUATION.put(".", "period"); - SPEAKABLE_PUNCTUATION.put("?", "question mark"); - } - - public Hints(Context context, SharedPreferences prefs, Display display) { - mContext = context; - mPrefs = prefs; - mDisplay = display; - - ContentResolver cr = mContext.getContentResolver(); - mSwipeHintMaxDaysToShow = SettingsUtil.getSettingsInt( - cr, - SettingsUtil.LATIN_IME_VOICE_INPUT_SWIPE_HINT_MAX_DAYS, - DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW); - mPunctuationHintMaxDisplays = SettingsUtil.getSettingsInt( - cr, - SettingsUtil.LATIN_IME_VOICE_INPUT_PUNCTUATION_HINT_MAX_DISPLAYS, - DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS); - } - - public boolean showSwipeHintIfNecessary(boolean fieldRecommended) { - if (fieldRecommended && shouldShowSwipeHint()) { - showHint(R.layout.voice_swipe_hint); - return true; - } - - return false; - } - - public boolean showPunctuationHintIfNecessary(InputConnection ic) { - if (!mVoiceResultContainedPunctuation - && ic != null - && getAndIncrementPref(PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT) - < mPunctuationHintMaxDisplays) { - CharSequence charBeforeCursor = ic.getTextBeforeCursor(1, 0); - if (SPEAKABLE_PUNCTUATION.containsKey(charBeforeCursor)) { - showHint(R.layout.voice_punctuation_hint); - return true; - } - } - - return false; - } - - public void registerVoiceResult(String text) { - // Update the current time as the last time voice input was used. - SharedPreferences.Editor editor = mPrefs.edit(); - editor.putLong(PREF_VOICE_INPUT_LAST_TIME_USED, System.currentTimeMillis()); - SharedPreferencesCompat.apply(editor); - - mVoiceResultContainedPunctuation = false; - for (CharSequence s : SPEAKABLE_PUNCTUATION.keySet()) { - if (text.indexOf(s.toString()) >= 0) { - mVoiceResultContainedPunctuation = true; - break; - } - } - } - - private boolean shouldShowSwipeHint() { - final SharedPreferences prefs = mPrefs; - - int numUniqueDaysShown = prefs.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0); - - // If we've already shown the hint for enough days, we'll return false. - if (numUniqueDaysShown < mSwipeHintMaxDaysToShow) { - - long lastTimeVoiceWasUsed = prefs.getLong(PREF_VOICE_INPUT_LAST_TIME_USED, 0); - - // If the user has used voice today, we'll return false. (We don't show the hint on - // any day that the user has already used voice.) - if (!isFromToday(lastTimeVoiceWasUsed)) { - return true; - } - } - - return false; - } - - /** - * Determines whether the provided time is from some time today (i.e., this day, month, - * and year). - */ - private boolean isFromToday(long timeInMillis) { - if (timeInMillis == 0) return false; - - Calendar today = Calendar.getInstance(); - today.setTimeInMillis(System.currentTimeMillis()); - - Calendar timestamp = Calendar.getInstance(); - timestamp.setTimeInMillis(timeInMillis); - - return (today.get(Calendar.YEAR) == timestamp.get(Calendar.YEAR) && - today.get(Calendar.DAY_OF_MONTH) == timestamp.get(Calendar.DAY_OF_MONTH) && - today.get(Calendar.MONTH) == timestamp.get(Calendar.MONTH)); - } - - private void showHint(int hintViewResource) { - final SharedPreferences prefs = mPrefs; - - int numUniqueDaysShown = prefs.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0); - long lastTimeHintWasShown = prefs.getLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, 0); - - // If this is the first time the hint is being shown today, increase the saved values - // to represent that. We don't need to increase the last time the hint was shown unless - // it is a different day from the current value. - if (!isFromToday(lastTimeHintWasShown)) { - SharedPreferences.Editor editor = prefs.edit(); - editor.putInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, numUniqueDaysShown + 1); - editor.putLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, System.currentTimeMillis()); - SharedPreferencesCompat.apply(editor); - } - - if (mDisplay != null) { - mDisplay.showHint(hintViewResource); - } - } - - private int getAndIncrementPref(String pref) { - final SharedPreferences prefs = mPrefs; - int value = prefs.getInt(pref, 0); - SharedPreferences.Editor editor = prefs.edit(); - editor.putInt(pref, value + 1); - SharedPreferencesCompat.apply(editor); - return value; - } -} diff --git a/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java b/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java deleted file mode 100644 index ff8b1abce..000000000 --- a/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java +++ /dev/null @@ -1,355 +0,0 @@ -/* - * 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 - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.inputmethod.deprecated.voice; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.CornerPathEffect; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.PathEffect; -import android.graphics.drawable.Drawable; -import android.os.Handler; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.TextView; - -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.StringUtils; -import com.android.inputmethod.latin.SubtypeSwitcher; - -import java.io.ByteArrayOutputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; -import java.util.Locale; - -/** - * The user interface for the "Speak now" and "working" states. - * Displays a recognition dialog (with waveform, voice meter, etc.), - * plays beeps, shows errors, etc. - */ -public class RecognitionView { - private static final String TAG = "RecognitionView"; - - private Handler mUiHandler; // Reference to UI thread - private View mView; - private Context mContext; - - private TextView mText; - private ImageView mImage; - private View mProgress; - private SoundIndicator mSoundIndicator; - private TextView mLanguage; - private Button mButton; - - private Drawable mInitializing; - private Drawable mError; - - private static final int INIT = 0; - private static final int LISTENING = 1; - private static final int WORKING = 2; - private static final int READY = 3; - - private int mState = INIT; - - private final View mPopupLayout; - - private final Drawable mListeningBorder; - private final Drawable mWorkingBorder; - private final Drawable mErrorBorder; - - public RecognitionView(Context context, OnClickListener clickListener) { - mUiHandler = new Handler(); - - LayoutInflater inflater = (LayoutInflater) context.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - - mView = inflater.inflate(R.layout.recognition_status, null); - - mPopupLayout= mView.findViewById(R.id.popup_layout); - - // Pre-load volume level images - Resources r = context.getResources(); - - mListeningBorder = r.getDrawable(R.drawable.vs_dialog_red); - mWorkingBorder = r.getDrawable(R.drawable.vs_dialog_blue); - mErrorBorder = r.getDrawable(R.drawable.vs_dialog_yellow); - - mInitializing = r.getDrawable(R.drawable.mic_slash); - mError = r.getDrawable(R.drawable.caution); - - mImage = (ImageView) mView.findViewById(R.id.image); - mProgress = mView.findViewById(R.id.progress); - mSoundIndicator = (SoundIndicator) mView.findViewById(R.id.sound_indicator); - - mButton = (Button) mView.findViewById(R.id.button); - mButton.setOnClickListener(clickListener); - mText = (TextView) mView.findViewById(R.id.text); - mLanguage = (TextView) mView.findViewById(R.id.language); - - mContext = context; - } - - public View getView() { - return mView; - } - - public void restoreState() { - mUiHandler.post(new Runnable() { - @Override - public void run() { - // Restart the spinner - if (mState == WORKING) { - ((ProgressBar) mProgress).setIndeterminate(false); - ((ProgressBar) mProgress).setIndeterminate(true); - } - } - }); - } - - public void showInitializing() { - mUiHandler.post(new Runnable() { - @Override - public void run() { - mState = INIT; - prepareDialog(mContext.getText(R.string.voice_initializing), mInitializing, - mContext.getText(R.string.cancel)); - } - }); - } - - public void showListening() { - Log.d(TAG, "#showListening"); - mUiHandler.post(new Runnable() { - @Override - public void run() { - mState = LISTENING; - prepareDialog(mContext.getText(R.string.voice_listening), null, - mContext.getText(R.string.cancel)); - } - }); - } - - public void updateVoiceMeter(float rmsdB) { - mSoundIndicator.setRmsdB(rmsdB); - } - - public void showError(final String message) { - mUiHandler.post(new Runnable() { - @Override - public void run() { - mState = READY; - prepareDialog(message, mError, mContext.getText(R.string.ok)); - } - }); - } - - public void showWorking( - final ByteArrayOutputStream waveBuffer, - final int speechStartPosition, - final int speechEndPosition) { - mUiHandler.post(new Runnable() { - @Override - public void run() { - mState = WORKING; - prepareDialog(mContext.getText(R.string.voice_working), null, mContext - .getText(R.string.cancel)); - final ShortBuffer buf = ByteBuffer.wrap(waveBuffer.toByteArray()).order( - ByteOrder.nativeOrder()).asShortBuffer(); - buf.position(0); - waveBuffer.reset(); - showWave(buf, speechStartPosition / 2, speechEndPosition / 2); - } - }); - } - - private void prepareDialog(CharSequence text, Drawable image, - CharSequence btnTxt) { - - /* - * The mic of INIT and of LISTENING has to be displayed in the same position. To accomplish - * that, some text visibility are not set as GONE but as INVISIBLE. - */ - switch (mState) { - case INIT: - mText.setVisibility(View.INVISIBLE); - - mProgress.setVisibility(View.GONE); - - mImage.setVisibility(View.VISIBLE); - mImage.setImageResource(R.drawable.mic_slash); - - mSoundIndicator.setVisibility(View.GONE); - mSoundIndicator.stop(); - - mLanguage.setVisibility(View.INVISIBLE); - - mPopupLayout.setBackgroundDrawable(mListeningBorder); - break; - case LISTENING: - mText.setVisibility(View.VISIBLE); - mText.setText(text); - - mProgress.setVisibility(View.GONE); - - mImage.setVisibility(View.GONE); - - mSoundIndicator.setVisibility(View.VISIBLE); - mSoundIndicator.start(); - - Locale locale = SubtypeSwitcher.getInstance().getInputLocale(); - - mLanguage.setVisibility(View.VISIBLE); - mLanguage.setText(StringUtils.getFullDisplayName(locale, true)); - - mPopupLayout.setBackgroundDrawable(mListeningBorder); - break; - case WORKING: - - mText.setVisibility(View.VISIBLE); - mText.setText(text); - - mProgress.setVisibility(View.VISIBLE); - - mImage.setVisibility(View.VISIBLE); - - mSoundIndicator.setVisibility(View.GONE); - mSoundIndicator.stop(); - - mLanguage.setVisibility(View.GONE); - - mPopupLayout.setBackgroundDrawable(mWorkingBorder); - break; - case READY: - mText.setVisibility(View.VISIBLE); - mText.setText(text); - - mProgress.setVisibility(View.GONE); - - mImage.setVisibility(View.VISIBLE); - mImage.setImageResource(R.drawable.caution); - - mSoundIndicator.setVisibility(View.GONE); - mSoundIndicator.stop(); - - mLanguage.setVisibility(View.GONE); - - mPopupLayout.setBackgroundDrawable(mErrorBorder); - break; - default: - Log.w(TAG, "Unknown state " + mState); - } - mPopupLayout.requestLayout(); - mButton.setText(btnTxt); - } - - /** - * @return an average abs of the specified buffer. - */ - private static int getAverageAbs(ShortBuffer buffer, int start, int i, int npw) { - int from = start + i * npw; - int end = from + npw; - int total = 0; - for (int x = from; x < end; x++) { - total += Math.abs(buffer.get(x)); - } - return total / npw; - } - - - /** - * Shows waveform of input audio. - * - * Copied from version in VoiceSearch's RecognitionActivity. - * - * TODO: adjust stroke width based on the size of data. - * TODO: use dip rather than pixels. - */ - private void showWave(ShortBuffer waveBuffer, int startPosition, int endPosition) { - final int w = ((View) mImage.getParent()).getWidth(); - final int h = ((View) mImage.getParent()).getHeight(); - if (w <= 0 || h <= 0) { - // view is not visible this time. Skip drawing. - return; - } - final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); - final Canvas c = new Canvas(b); - final Paint paint = new Paint(); - paint.setColor(0xFFFFFFFF); // 0xAARRGGBB - paint.setAntiAlias(true); - paint.setStyle(Paint.Style.STROKE); - paint.setAlpha(80); - - final PathEffect effect = new CornerPathEffect(3); - paint.setPathEffect(effect); - - final int numSamples = waveBuffer.remaining(); - int endIndex; - if (endPosition == 0) { - endIndex = numSamples; - } else { - endIndex = Math.min(endPosition, numSamples); - } - - int startIndex = startPosition - 2000; // include 250ms before speech - if (startIndex < 0) { - startIndex = 0; - } - final int numSamplePerWave = 200; // 8KHz 25ms = 200 samples - final float scale = 10.0f / 65536.0f; - - final int count = (endIndex - startIndex) / numSamplePerWave; - final float deltaX = 1.0f * w / count; - int yMax = h / 2; - Path path = new Path(); - c.translate(0, yMax); - float x = 0; - path.moveTo(x, 0); - for (int i = 0; i < count; i++) { - final int avabs = getAverageAbs(waveBuffer, startIndex, i , numSamplePerWave); - int sign = ( (i & 01) == 0) ? -1 : 1; - final float y = Math.min(yMax, avabs * h * scale) * sign; - path.lineTo(x, y); - x += deltaX; - path.lineTo(x, y); - } - if (deltaX > 4) { - paint.setStrokeWidth(2); - } else { - paint.setStrokeWidth(Math.max(0, (int) (deltaX -.05))); - } - c.drawPath(path, paint); - mImage.setImageBitmap(b); - } - - public void finish() { - mUiHandler.post(new Runnable() { - @Override - public void run() { - mSoundIndicator.stop(); - } - }); - } -} diff --git a/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java b/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java deleted file mode 100644 index 855a09a1d..000000000 --- a/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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 - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.inputmethod.deprecated.voice; - -import android.content.ContentResolver; -import android.provider.Settings; - -/** - * Utility for retrieving settings from Settings.Secure. - */ -public class SettingsUtil { - /** - * A whitespace-separated list of supported locales for voice input from the keyboard. - */ - public static final String LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES = - "latin_ime_voice_input_supported_locales"; - - /** - * A whitespace-separated list of recommended app packages for voice input from the - * keyboard. - */ - public static final String LATIN_IME_VOICE_INPUT_RECOMMENDED_PACKAGES = - "latin_ime_voice_input_recommended_packages"; - - /** - * The maximum number of unique days to show the swipe hint for voice input. - */ - public static final String LATIN_IME_VOICE_INPUT_SWIPE_HINT_MAX_DAYS = - "latin_ime_voice_input_swipe_hint_max_days"; - - /** - * The maximum number of times to show the punctuation hint for voice input. - */ - public static final String LATIN_IME_VOICE_INPUT_PUNCTUATION_HINT_MAX_DISPLAYS = - "latin_ime_voice_input_punctuation_hint_max_displays"; - - /** - * Endpointer parameters for voice input from the keyboard. - */ - public static final String LATIN_IME_SPEECH_MINIMUM_LENGTH_MILLIS = - "latin_ime_speech_minimum_length_millis"; - public static final String LATIN_IME_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS = - "latin_ime_speech_input_complete_silence_length_millis"; - public static final String LATIN_IME_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS = - "latin_ime_speech_input_possibly_complete_silence_length_millis"; - - /** - * Min and max volume levels that can be displayed on the "speak now" screen. - */ - public static final String LATIN_IME_MIN_MICROPHONE_LEVEL = - "latin_ime_min_microphone_level"; - public static final String LATIN_IME_MAX_MICROPHONE_LEVEL = - "latin_ime_max_microphone_level"; - - /** - * The number of sentence-level alternates to request of the server. - */ - public static final String LATIN_IME_MAX_VOICE_RESULTS = "latin_ime_max_voice_results"; - - /** - * Get a string-valued setting. - * - * @param cr The content resolver to use - * @param key The setting to look up - * @param defaultValue The default value to use if none can be found - * @return The value of the setting, or defaultValue if it couldn't be found - */ - public static String getSettingsString(ContentResolver cr, String key, String defaultValue) { - String result = Settings.Secure.getString(cr, key); - return (result == null) ? defaultValue : result; - } - - /** - * Get an int-valued setting. - * - * @param cr The content resolver to use - * @param key The setting to look up - * @param defaultValue The default value to use if the setting couldn't be found or parsed - * @return The value of the setting, or defaultValue if it couldn't be found or parsed - */ - public static int getSettingsInt(ContentResolver cr, String key, int defaultValue) { - return Settings.Secure.getInt(cr, key, defaultValue); - } - - /** - * Get a float-valued setting. - * - * @param cr The content resolver to use - * @param key The setting to look up - * @param defaultValue The default value to use if the setting couldn't be found or parsed - * @return The value of the setting, or defaultValue if it couldn't be found or parsed - */ - public static float getSettingsFloat(ContentResolver cr, String key, float defaultValue) { - return Settings.Secure.getFloat(cr, key, defaultValue); - } -} diff --git a/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java b/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java deleted file mode 100644 index 25b314085..000000000 --- a/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2011 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.deprecated.voice; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; -import android.graphics.Rect; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.os.Handler; -import android.util.AttributeSet; -import android.widget.ImageView; - -import com.android.inputmethod.latin.R; - -/** - * A widget which shows the volume of audio using a microphone icon - */ -public class SoundIndicator extends ImageView { - @SuppressWarnings("unused") - private static final String TAG = "SoundIndicator"; - - private static final float UP_SMOOTHING_FACTOR = 0.9f; - private static final float DOWN_SMOOTHING_FACTOR = 0.4f; - - private static final float AUDIO_METER_MIN_DB = 7.0f; - private static final float AUDIO_METER_DB_RANGE = 20.0f; - - private static final long FRAME_DELAY = 50; - - private Bitmap mDrawingBuffer; - private Canvas mBufferCanvas; - private Bitmap mEdgeBitmap; - private float mLevel = 0.0f; - private Drawable mFrontDrawable; - private Paint mClearPaint; - private Paint mMultPaint; - private int mEdgeBitmapOffset; - - private Handler mHandler; - - private Runnable mDrawFrame = new Runnable() { - public void run() { - invalidate(); - mHandler.postDelayed(mDrawFrame, FRAME_DELAY); - } - }; - - public SoundIndicator(Context context) { - this(context, null); - } - - public SoundIndicator(Context context, AttributeSet attrs) { - super(context, attrs); - - mFrontDrawable = getDrawable(); - BitmapDrawable edgeDrawable = - (BitmapDrawable) context.getResources().getDrawable(R.drawable.vs_popup_mic_edge); - mEdgeBitmap = edgeDrawable.getBitmap(); - mEdgeBitmapOffset = mEdgeBitmap.getHeight() / 2; - - mDrawingBuffer = - Bitmap.createBitmap(mFrontDrawable.getIntrinsicWidth(), - mFrontDrawable.getIntrinsicHeight(), Config.ARGB_8888); - - mBufferCanvas = new Canvas(mDrawingBuffer); - - // Initialize Paints. - mClearPaint = new Paint(); - mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); - - mMultPaint = new Paint(); - mMultPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY)); - - mHandler = new Handler(); - } - - @Override - public void onDraw(Canvas canvas) { - //super.onDraw(canvas); - - float w = getWidth(); - float h = getHeight(); - - // Clear the buffer canvas - mBufferCanvas.drawRect(0, 0, w, h, mClearPaint); - - // Set its clip so we don't draw the front image all the way to the top - Rect clip = new Rect(0, - (int) ((1.0 - mLevel) * (h + mEdgeBitmapOffset)) - mEdgeBitmapOffset, - (int) w, - (int) h); - - mBufferCanvas.save(); - mBufferCanvas.clipRect(clip); - - // Draw the front image - mFrontDrawable.setBounds(new Rect(0, 0, (int) w, (int) h)); - mFrontDrawable.draw(mBufferCanvas); - - mBufferCanvas.restore(); - - // Draw the edge image on top of the buffer image with a multiply mode - mBufferCanvas.drawBitmap(mEdgeBitmap, 0, clip.top, mMultPaint); - - // Draw the buffer image (on top of the background image) - canvas.drawBitmap(mDrawingBuffer, 0, 0, null); - } - - /** - * Sets the sound level - * - * @param rmsdB The level of the sound, in dB. - */ - public void setRmsdB(float rmsdB) { - float level = ((rmsdB - AUDIO_METER_MIN_DB) / AUDIO_METER_DB_RANGE); - - level = Math.min(Math.max(0.0f, level), 1.0f); - - // We smooth towards the new level - if (level > mLevel) { - mLevel = (level - mLevel) * UP_SMOOTHING_FACTOR + mLevel; - } else { - mLevel = (level - mLevel) * DOWN_SMOOTHING_FACTOR + mLevel; - } - invalidate(); - } - - public void start() { - mHandler.post(mDrawFrame); - } - - public void stop() { - mHandler.removeCallbacks(mDrawFrame); - } -} diff --git a/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java b/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java deleted file mode 100644 index 8969a2168..000000000 --- a/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java +++ /dev/null @@ -1,692 +0,0 @@ -/* - * 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 - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.inputmethod.deprecated.voice; - -import com.android.inputmethod.latin.EditingUtils; -import com.android.inputmethod.latin.LatinImeLogger; -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.StaticInnerHandlerWrapper; - -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.os.Message; -import android.os.Parcelable; -import android.speech.RecognitionListener; -import android.speech.RecognizerIntent; -import android.speech.SpeechRecognizer; -import android.util.Log; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.inputmethod.InputConnection; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -/** - * Speech recognition input, including both user interface and a background - * process to stream audio to the network recognizer. This class supplies a - * View (getView()), which it updates as recognition occurs. The user of this - * class is responsible for making the view visible to the user, as well as - * handling various events returned through UiListener. - */ -public class VoiceInput implements OnClickListener { - private static final String TAG = "VoiceInput"; - private static final String EXTRA_RECOGNITION_CONTEXT = - "android.speech.extras.RECOGNITION_CONTEXT"; - private static final String EXTRA_CALLING_PACKAGE = "calling_package"; - private static final String EXTRA_ALTERNATES = "android.speech.extra.ALTERNATES"; - private static final int MAX_ALT_LIST_LENGTH = 6; - private static boolean DBG = LatinImeLogger.sDBG; - - private static final String DEFAULT_RECOMMENDED_PACKAGES = - "com.android.mms " + - "com.google.android.gm " + - "com.google.android.talk " + - "com.google.android.apps.googlevoice " + - "com.android.email " + - "com.android.browser "; - - // WARNING! Before enabling this, fix the problem with calling getExtractedText() in - // landscape view. It causes Extracted text updates to be rejected due to a token mismatch - public static boolean ENABLE_WORD_CORRECTIONS = true; - - // Dummy word suggestion which means "delete current word" - public static final String DELETE_SYMBOL = " \u00D7 "; // times symbol - - private Whitelist mRecommendedList; - private Whitelist mBlacklist; - - private VoiceInputLogger mLogger; - - // Names of a few extras defined in VoiceSearch's RecognitionController - // Note, the version of voicesearch that shipped in Froyo returns the raw - // RecognitionClientAlternates protocol buffer under the key "alternates", - // so a VS market update must be installed on Froyo devices in order to see - // alternatives. - private static final String ALTERNATES_BUNDLE = "alternates_bundle"; - - // This is copied from the VoiceSearch app. - @SuppressWarnings("unused") - private static final class AlternatesBundleKeys { - public static final String ALTERNATES = "alternates"; - public static final String CONFIDENCE = "confidence"; - public static final String LENGTH = "length"; - public static final String MAX_SPAN_LENGTH = "max_span_length"; - public static final String SPANS = "spans"; - public static final String SPAN_KEY_DELIMITER = ":"; - public static final String START = "start"; - public static final String TEXT = "text"; - } - - // Names of a few intent extras defined in VoiceSearch's RecognitionService. - // These let us tweak the endpointer parameters. - private static final String EXTRA_SPEECH_MINIMUM_LENGTH_MILLIS = - "android.speech.extras.SPEECH_INPUT_MINIMUM_LENGTH_MILLIS"; - private static final String EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS = - "android.speech.extras.SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS"; - private static final String EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS = - "android.speech.extras.SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS"; - - // The usual endpointer default value for input complete silence length is 0.5 seconds, - // but that's used for things like voice search. For dictation-like voice input like this, - // we go with a more liberal value of 1 second. This value will only be used if a value - // is not provided from Gservices. - private static final String INPUT_COMPLETE_SILENCE_LENGTH_DEFAULT_VALUE_MILLIS = "1000"; - - // Used to record part of that state for logging purposes. - public static final int DEFAULT = 0; - public static final int LISTENING = 1; - public static final int WORKING = 2; - public static final int ERROR = 3; - - private int mAfterVoiceInputDeleteCount = 0; - private int mAfterVoiceInputInsertCount = 0; - private int mAfterVoiceInputInsertPunctuationCount = 0; - private int mAfterVoiceInputCursorPos = 0; - private int mAfterVoiceInputSelectionSpan = 0; - - private int mState = DEFAULT; - - private final static int MSG_RESET = 1; - - private final UIHandler mHandler = new UIHandler(this); - - private static class UIHandler extends StaticInnerHandlerWrapper { - public UIHandler(VoiceInput outerInstance) { - super(outerInstance); - } - - @Override - public void handleMessage(Message msg) { - if (msg.what == MSG_RESET) { - final VoiceInput voiceInput = getOuterInstance(); - voiceInput.mState = DEFAULT; - voiceInput.mRecognitionView.finish(); - voiceInput.mUiListener.onCancelVoice(); - } - } - }; - - /** - * Events relating to the recognition UI. You must implement these. - */ - public interface UiListener { - - /** - * @param recognitionResults a set of transcripts for what the user - * spoke, sorted by likelihood. - */ - public void onVoiceResults( - List recognitionResults, - Map> alternatives); - - /** - * Called when the user cancels speech recognition. - */ - public void onCancelVoice(); - } - - private SpeechRecognizer mSpeechRecognizer; - private RecognitionListener mRecognitionListener; - private RecognitionView mRecognitionView; - private UiListener mUiListener; - private Context mContext; - - /** - * @param context the service or activity in which we're running. - * @param uiHandler object to receive events from VoiceInput. - */ - public VoiceInput(Context context, UiListener uiHandler) { - mLogger = VoiceInputLogger.getLogger(context); - mRecognitionListener = new ImeRecognitionListener(); - mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(context); - mSpeechRecognizer.setRecognitionListener(mRecognitionListener); - mUiListener = uiHandler; - mContext = context; - newView(); - - String recommendedPackages = SettingsUtil.getSettingsString( - context.getContentResolver(), - SettingsUtil.LATIN_IME_VOICE_INPUT_RECOMMENDED_PACKAGES, - DEFAULT_RECOMMENDED_PACKAGES); - - mRecommendedList = new Whitelist(); - for (String recommendedPackage : recommendedPackages.split("\\s+")) { - mRecommendedList.addApp(recommendedPackage); - } - - mBlacklist = new Whitelist(); - mBlacklist.addApp("com.google.android.setupwizard"); - } - - public void setCursorPos(int pos) { - mAfterVoiceInputCursorPos = pos; - } - - public int getCursorPos() { - return mAfterVoiceInputCursorPos; - } - - public void setSelectionSpan(int span) { - mAfterVoiceInputSelectionSpan = span; - } - - public int getSelectionSpan() { - return mAfterVoiceInputSelectionSpan; - } - - public void incrementTextModificationDeleteCount(int count){ - mAfterVoiceInputDeleteCount += count; - // Send up intents for other text modification types - if (mAfterVoiceInputInsertCount > 0) { - logTextModifiedByTypingInsertion(mAfterVoiceInputInsertCount); - mAfterVoiceInputInsertCount = 0; - } - if (mAfterVoiceInputInsertPunctuationCount > 0) { - logTextModifiedByTypingInsertionPunctuation(mAfterVoiceInputInsertPunctuationCount); - mAfterVoiceInputInsertPunctuationCount = 0; - } - - } - - public void incrementTextModificationInsertCount(int count){ - mAfterVoiceInputInsertCount += count; - if (mAfterVoiceInputSelectionSpan > 0) { - // If text was highlighted before inserting the char, count this as - // a delete. - mAfterVoiceInputDeleteCount += mAfterVoiceInputSelectionSpan; - } - // Send up intents for other text modification types - if (mAfterVoiceInputDeleteCount > 0) { - logTextModifiedByTypingDeletion(mAfterVoiceInputDeleteCount); - mAfterVoiceInputDeleteCount = 0; - } - if (mAfterVoiceInputInsertPunctuationCount > 0) { - logTextModifiedByTypingInsertionPunctuation(mAfterVoiceInputInsertPunctuationCount); - mAfterVoiceInputInsertPunctuationCount = 0; - } - } - - public void incrementTextModificationInsertPunctuationCount(int count){ - mAfterVoiceInputInsertPunctuationCount += count; - if (mAfterVoiceInputSelectionSpan > 0) { - // If text was highlighted before inserting the char, count this as - // a delete. - mAfterVoiceInputDeleteCount += mAfterVoiceInputSelectionSpan; - } - // Send up intents for aggregated non-punctuation insertions - if (mAfterVoiceInputDeleteCount > 0) { - logTextModifiedByTypingDeletion(mAfterVoiceInputDeleteCount); - mAfterVoiceInputDeleteCount = 0; - } - if (mAfterVoiceInputInsertCount > 0) { - logTextModifiedByTypingInsertion(mAfterVoiceInputInsertCount); - mAfterVoiceInputInsertCount = 0; - } - } - - public void flushAllTextModificationCounters() { - if (mAfterVoiceInputInsertCount > 0) { - logTextModifiedByTypingInsertion(mAfterVoiceInputInsertCount); - mAfterVoiceInputInsertCount = 0; - } - if (mAfterVoiceInputDeleteCount > 0) { - logTextModifiedByTypingDeletion(mAfterVoiceInputDeleteCount); - mAfterVoiceInputDeleteCount = 0; - } - if (mAfterVoiceInputInsertPunctuationCount > 0) { - logTextModifiedByTypingInsertionPunctuation(mAfterVoiceInputInsertPunctuationCount); - mAfterVoiceInputInsertPunctuationCount = 0; - } - } - - /** - * The configuration of the IME changed and may have caused the views to be layed out - * again. Restore the state of the recognition view. - */ - public void onConfigurationChanged(Configuration configuration) { - mRecognitionView.restoreState(); - mRecognitionView.getView().dispatchConfigurationChanged(configuration); - } - - /** - * @return true if field is blacklisted for voice - */ - public boolean isBlacklistedField(FieldContext context) { - return mBlacklist.matches(context); - } - - /** - * Used to decide whether to show voice input hints for this field, etc. - * - * @return true if field is recommended for voice - */ - public boolean isRecommendedField(FieldContext context) { - return mRecommendedList.matches(context); - } - - /** - * Start listening for speech from the user. This will grab the microphone - * and start updating the view provided by getView(). It is the caller's - * responsibility to ensure that the view is visible to the user at this stage. - * - * @param context the same FieldContext supplied to voiceIsEnabled() - * @param swipe whether this voice input was started by swipe, for logging purposes - */ - public void startListening(FieldContext context, boolean swipe) { - if (DBG) { - Log.d(TAG, "startListening: " + context); - } - - if (mState != DEFAULT) { - Log.w(TAG, "startListening in the wrong status " + mState); - } - - // If everything works ok, the voice input should be already in the correct state. As this - // class can be called by third-party, we call reset just to be on the safe side. - reset(); - - Locale locale = Locale.getDefault(); - String localeString = locale.getLanguage() + "-" + locale.getCountry(); - - mLogger.start(localeString, swipe); - - mState = LISTENING; - - mRecognitionView.showInitializing(); - startListeningAfterInitialization(context); - } - - /** - * Called only when the recognition manager's initialization completed - * - * @param context context with which {@link #startListening(FieldContext, boolean)} was executed - */ - private void startListeningAfterInitialization(FieldContext context) { - Intent intent = makeIntent(); - intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, ""); - intent.putExtra(EXTRA_RECOGNITION_CONTEXT, context.getBundle()); - intent.putExtra(EXTRA_CALLING_PACKAGE, "VoiceIME"); - intent.putExtra(EXTRA_ALTERNATES, true); - intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, - SettingsUtil.getSettingsInt( - mContext.getContentResolver(), - SettingsUtil.LATIN_IME_MAX_VOICE_RESULTS, - 1)); - // Get endpointer params from Gservices. - // TODO: Consider caching these values for improved performance on slower devices. - final ContentResolver cr = mContext.getContentResolver(); - putEndpointerExtra( - cr, - intent, - SettingsUtil.LATIN_IME_SPEECH_MINIMUM_LENGTH_MILLIS, - EXTRA_SPEECH_MINIMUM_LENGTH_MILLIS, - null /* rely on endpointer default */); - putEndpointerExtra( - cr, - intent, - SettingsUtil.LATIN_IME_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, - EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, - INPUT_COMPLETE_SILENCE_LENGTH_DEFAULT_VALUE_MILLIS - /* our default value is different from the endpointer's */); - putEndpointerExtra( - cr, - intent, - SettingsUtil. - LATIN_IME_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, - EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, - null /* rely on endpointer default */); - - mSpeechRecognizer.startListening(intent); - } - - /** - * Gets the value of the provided Gservices key, attempts to parse it into a long, - * and if successful, puts the long value as an extra in the provided intent. - */ - private void putEndpointerExtra(ContentResolver cr, Intent i, - String gservicesKey, String intentExtraKey, String defaultValue) { - long l = -1; - String s = SettingsUtil.getSettingsString(cr, gservicesKey, defaultValue); - if (s != null) { - try { - l = Long.valueOf(s); - } catch (NumberFormatException e) { - Log.e(TAG, "could not parse value for " + gservicesKey + ": " + s); - } - } - - if (l != -1) i.putExtra(intentExtraKey, l); - } - - public void destroy() { - mSpeechRecognizer.destroy(); - } - - /** - * Creates a new instance of the view that is returned by {@link #getView()} - * Clients should use this when a previously returned view is stuck in a - * layout that is being thrown away and a new one is need to show to the - * user. - */ - public void newView() { - mRecognitionView = new RecognitionView(mContext, this); - } - - /** - * @return a view that shows the recognition flow--e.g., "Speak now" and - * "working" dialogs. - */ - public View getView() { - return mRecognitionView.getView(); - } - - /** - * Handle the cancel button. - */ - @Override - public void onClick(View view) { - switch(view.getId()) { - case R.id.button: - cancel(); - break; - } - } - - public void logTextModifiedByTypingInsertion(int length) { - mLogger.textModifiedByTypingInsertion(length); - } - - public void logTextModifiedByTypingInsertionPunctuation(int length) { - mLogger.textModifiedByTypingInsertionPunctuation(length); - } - - public void logTextModifiedByTypingDeletion(int length) { - mLogger.textModifiedByTypingDeletion(length); - } - - public void logTextModifiedByChooseSuggestion(String suggestion, int index, - String wordSeparators, InputConnection ic) { - String wordToBeReplaced = EditingUtils.getWordAtCursor(ic, wordSeparators); - // If we enable phrase-based alternatives, only send up the first word - // in suggestion and wordToBeReplaced. - mLogger.textModifiedByChooseSuggestion(suggestion.length(), wordToBeReplaced.length(), - index, wordToBeReplaced, suggestion); - } - - public void logKeyboardWarningDialogShown() { - mLogger.keyboardWarningDialogShown(); - } - - public void logKeyboardWarningDialogDismissed() { - mLogger.keyboardWarningDialogDismissed(); - } - - public void logKeyboardWarningDialogOk() { - mLogger.keyboardWarningDialogOk(); - } - - public void logKeyboardWarningDialogCancel() { - mLogger.keyboardWarningDialogCancel(); - } - - public void logSwipeHintDisplayed() { - mLogger.swipeHintDisplayed(); - } - - public void logPunctuationHintDisplayed() { - mLogger.punctuationHintDisplayed(); - } - - public void logVoiceInputDelivered(int length) { - mLogger.voiceInputDelivered(length); - } - - public void logInputEnded() { - mLogger.inputEnded(); - } - - public void flushLogs() { - mLogger.flush(); - } - - private static Intent makeIntent() { - Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); - - // On Cupcake, use VoiceIMEHelper since VoiceSearch doesn't support. - // On Donut, always use VoiceSearch, since VoiceIMEHelper and - // VoiceSearch may conflict. - if (Build.VERSION.RELEASE.equals("1.5")) { - intent = intent.setClassName( - "com.google.android.voiceservice", - "com.google.android.voiceservice.IMERecognitionService"); - } else { - intent = intent.setClassName( - "com.google.android.voicesearch", - "com.google.android.voicesearch.RecognitionService"); - } - - return intent; - } - - /** - * Reset the current voice recognition. - */ - public void reset() { - if (mState != DEFAULT) { - mState = DEFAULT; - - // Remove all pending tasks (e.g., timers to cancel voice input) - mHandler.removeMessages(MSG_RESET); - - mSpeechRecognizer.cancel(); - mRecognitionView.finish(); - } - } - - /** - * Cancel in-progress speech recognition. - */ - public void cancel() { - switch (mState) { - case LISTENING: - mLogger.cancelDuringListening(); - break; - case WORKING: - mLogger.cancelDuringWorking(); - break; - case ERROR: - mLogger.cancelDuringError(); - break; - } - - reset(); - mUiListener.onCancelVoice(); - } - - private int getErrorStringId(int errorType, boolean endpointed) { - switch (errorType) { - // We use CLIENT_ERROR to signify that voice search is not available on the device. - case SpeechRecognizer.ERROR_CLIENT: - return R.string.voice_not_installed; - case SpeechRecognizer.ERROR_NETWORK: - return R.string.voice_network_error; - case SpeechRecognizer.ERROR_NETWORK_TIMEOUT: - return endpointed ? - R.string.voice_network_error : R.string.voice_too_much_speech; - case SpeechRecognizer.ERROR_AUDIO: - return R.string.voice_audio_error; - case SpeechRecognizer.ERROR_SERVER: - return R.string.voice_server_error; - case SpeechRecognizer.ERROR_SPEECH_TIMEOUT: - return R.string.voice_speech_timeout; - case SpeechRecognizer.ERROR_NO_MATCH: - return R.string.voice_no_match; - default: return R.string.voice_error; - } - } - - private void onError(int errorType, boolean endpointed) { - Log.i(TAG, "error " + errorType); - mLogger.error(errorType); - onError(mContext.getString(getErrorStringId(errorType, endpointed))); - } - - private void onError(String error) { - mState = ERROR; - mRecognitionView.showError(error); - // Wait a couple seconds and then automatically dismiss message. - mHandler.sendMessageDelayed(Message.obtain(mHandler, MSG_RESET), 2000); - } - - private class ImeRecognitionListener implements RecognitionListener { - // Waveform data - final ByteArrayOutputStream mWaveBuffer = new ByteArrayOutputStream(); - int mSpeechStart; - private boolean mEndpointed = false; - - @Override - public void onReadyForSpeech(Bundle noiseParams) { - mRecognitionView.showListening(); - } - - @Override - public void onBeginningOfSpeech() { - mEndpointed = false; - mSpeechStart = mWaveBuffer.size(); - } - - @Override - public void onRmsChanged(float rmsdB) { - mRecognitionView.updateVoiceMeter(rmsdB); - } - - @Override - public void onBufferReceived(byte[] buf) { - try { - mWaveBuffer.write(buf); - } catch (IOException e) { - // ignore. - } - } - - @Override - public void onEndOfSpeech() { - mEndpointed = true; - mState = WORKING; - mRecognitionView.showWorking(mWaveBuffer, mSpeechStart, mWaveBuffer.size()); - } - - @Override - public void onError(int errorType) { - mState = ERROR; - VoiceInput.this.onError(errorType, mEndpointed); - } - - @Override - public void onResults(Bundle resultsBundle) { - List results = resultsBundle - .getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); - // VS Market update is needed for IME froyo clients to access the alternatesBundle - // TODO: verify this. - Bundle alternatesBundle = resultsBundle.getBundle(ALTERNATES_BUNDLE); - mState = DEFAULT; - - final Map> alternatives = - new HashMap>(); - - if (ENABLE_WORD_CORRECTIONS && alternatesBundle != null && results.size() > 0) { - // Use the top recognition result to map each alternative's start:length to a word. - String[] words = results.get(0).split(" "); - Bundle spansBundle = alternatesBundle.getBundle(AlternatesBundleKeys.SPANS); - for (String key : spansBundle.keySet()) { - // Get the word for which these alternates correspond to. - Bundle spanBundle = spansBundle.getBundle(key); - int start = spanBundle.getInt(AlternatesBundleKeys.START); - int length = spanBundle.getInt(AlternatesBundleKeys.LENGTH); - // Only keep single-word based alternatives. - if (length == 1 && start < words.length) { - // Get the alternatives associated with the span. - // If a word appears twice in a recognition result, - // concatenate the alternatives for the word. - List altList = alternatives.get(words[start]); - if (altList == null) { - altList = new ArrayList(); - alternatives.put(words[start], altList); - } - Parcelable[] alternatesArr = spanBundle - .getParcelableArray(AlternatesBundleKeys.ALTERNATES); - for (int j = 0; j < alternatesArr.length && - altList.size() < MAX_ALT_LIST_LENGTH; j++) { - Bundle alternateBundle = (Bundle) alternatesArr[j]; - String alternate = alternateBundle.getString(AlternatesBundleKeys.TEXT); - // Don't allow duplicates in the alternates list. - if (!altList.contains(alternate)) { - altList.add(alternate); - } - } - } - } - } - - if (results.size() > 5) { - results = results.subList(0, 5); - } - mUiListener.onVoiceResults(results, alternatives); - mRecognitionView.finish(); - } - - @Override - public void onPartialResults(final Bundle partialResults) { - // currently - do nothing - } - - @Override - public void onEvent(int eventType, Bundle params) { - // do nothing - reserved for events that might be added in the future - } - } -} diff --git a/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java b/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java deleted file mode 100644 index 22e8207bf..000000000 --- a/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2008 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.deprecated.voice; - -import com.android.common.speech.LoggingEvents; -import com.android.inputmethod.deprecated.compat.VoiceInputLoggerCompatUtils; - -import android.content.Context; -import android.content.Intent; - -/** - * Provides the logging facility for voice input events. This fires broadcasts back to - * the voice search app which then logs on our behalf. - * - * Note that debug console logging does not occur in this class. If you want to - * see console output of these logging events, there is a boolean switch to turn - * on on the VoiceSearch side. - */ -public class VoiceInputLogger { - @SuppressWarnings("unused") - private static final String TAG = VoiceInputLogger.class.getSimpleName(); - - private static VoiceInputLogger sVoiceInputLogger; - - private final Context mContext; - - // The base intent used to form all broadcast intents to the logger - // in VoiceSearch. - private final Intent mBaseIntent; - - // This flag is used to indicate when there are voice events that - // need to be flushed. - private boolean mHasLoggingInfo = false; - - /** - * Returns the singleton of the logger. - * - * @param contextHint a hint context used when creating the logger instance. - * Ignored if the singleton instance already exists. - */ - public static synchronized VoiceInputLogger getLogger(Context contextHint) { - if (sVoiceInputLogger == null) { - sVoiceInputLogger = new VoiceInputLogger(contextHint); - } - return sVoiceInputLogger; - } - - public VoiceInputLogger(Context context) { - mContext = context; - - mBaseIntent = new Intent(LoggingEvents.ACTION_LOG_EVENT); - mBaseIntent.putExtra(LoggingEvents.EXTRA_APP_NAME, LoggingEvents.VoiceIme.APP_NAME); - } - - private Intent newLoggingBroadcast(int event) { - Intent i = new Intent(mBaseIntent); - i.putExtra(LoggingEvents.EXTRA_EVENT, event); - return i; - } - - public void flush() { - if (hasLoggingInfo()) { - Intent i = new Intent(mBaseIntent); - i.putExtra(LoggingEvents.EXTRA_FLUSH, true); - mContext.sendBroadcast(i); - setHasLoggingInfo(false); - } - } - - public void keyboardWarningDialogShown() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast( - LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_SHOWN)); - } - - public void keyboardWarningDialogDismissed() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast( - LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_DISMISSED)); - } - - public void keyboardWarningDialogOk() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast( - LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_OK)); - } - - public void keyboardWarningDialogCancel() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast( - LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_CANCEL)); - } - - public void settingsWarningDialogShown() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast( - LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_SHOWN)); - } - - public void settingsWarningDialogDismissed() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast( - LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_DISMISSED)); - } - - public void settingsWarningDialogOk() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast( - LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_OK)); - } - - public void settingsWarningDialogCancel() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast( - LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_CANCEL)); - } - - public void swipeHintDisplayed() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.SWIPE_HINT_DISPLAYED)); - } - - public void cancelDuringListening() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.CANCEL_DURING_LISTENING)); - } - - public void cancelDuringWorking() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.CANCEL_DURING_WORKING)); - } - - public void cancelDuringError() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.CANCEL_DURING_ERROR)); - } - - public void punctuationHintDisplayed() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast( - LoggingEvents.VoiceIme.PUNCTUATION_HINT_DISPLAYED)); - } - - public void error(int code) { - setHasLoggingInfo(true); - Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.ERROR); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_ERROR_CODE, code); - mContext.sendBroadcast(i); - } - - public void start(String locale, boolean swipe) { - setHasLoggingInfo(true); - Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.START); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_START_LOCALE, locale); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_START_SWIPE, swipe); - i.putExtra(LoggingEvents.EXTRA_TIMESTAMP, System.currentTimeMillis()); - mContext.sendBroadcast(i); - } - - public void voiceInputDelivered(int length) { - setHasLoggingInfo(true); - Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.VOICE_INPUT_DELIVERED); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_LENGTH, length); - mContext.sendBroadcast(i); - } - - public void textModifiedByTypingInsertion(int length) { - setHasLoggingInfo(true); - Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_LENGTH, length); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_TYPE, - LoggingEvents.VoiceIme.TEXT_MODIFIED_TYPE_TYPING_INSERTION); - mContext.sendBroadcast(i); - } - - public void textModifiedByTypingInsertionPunctuation(int length) { - setHasLoggingInfo(true); - Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_LENGTH, length); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_TYPE, - LoggingEvents.VoiceIme.TEXT_MODIFIED_TYPE_TYPING_INSERTION_PUNCTUATION); - mContext.sendBroadcast(i); - } - - public void textModifiedByTypingDeletion(int length) { - setHasLoggingInfo(true); - Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_LENGTH, length); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_TYPE, - LoggingEvents.VoiceIme.TEXT_MODIFIED_TYPE_TYPING_DELETION); - - mContext.sendBroadcast(i); - } - - - public void textModifiedByChooseSuggestion(int suggestionLength, int replacedPhraseLength, - int index, String before, String after) { - setHasLoggingInfo(true); - Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_LENGTH, suggestionLength); - i.putExtra(VoiceInputLoggerCompatUtils.EXTRA_TEXT_REPLACED_LENGTH, replacedPhraseLength); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_TYPE, - LoggingEvents.VoiceIme.TEXT_MODIFIED_TYPE_CHOOSE_SUGGESTION); - i.putExtra(LoggingEvents.VoiceIme.EXTRA_N_BEST_CHOOSE_INDEX, index); - i.putExtra(VoiceInputLoggerCompatUtils.EXTRA_BEFORE_N_BEST_CHOOSE, before); - i.putExtra(VoiceInputLoggerCompatUtils.EXTRA_AFTER_N_BEST_CHOOSE, after); - mContext.sendBroadcast(i); - } - - public void inputEnded() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.INPUT_ENDED)); - } - - public void voiceInputSettingEnabled() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast( - LoggingEvents.VoiceIme.VOICE_INPUT_SETTING_ENABLED)); - } - - public void voiceInputSettingDisabled() { - setHasLoggingInfo(true); - mContext.sendBroadcast(newLoggingBroadcast( - LoggingEvents.VoiceIme.VOICE_INPUT_SETTING_DISABLED)); - } - - private void setHasLoggingInfo(boolean hasLoggingInfo) { - mHasLoggingInfo = hasLoggingInfo; - // If applications that call UserHappinessSignals.userAcceptedImeText - // make that call after VoiceInputLogger.flush() calls this method with false, we - // will lose those happiness signals. For example, consider the gmail sequence: - // 1. compose message - // 2. speak message into message field - // 3. type subject into subject field - // 4. press send - // We will NOT get the signal that the user accepted the voice inputted message text - // because when the user tapped on the subject field, the ime's flush will be triggered - // and the hasLoggingInfo will be then set to false. So by the time the user hits send - // we have essentially forgotten about any voice input. - // However the following (more common) use case is properly logged - // 1. compose message - // 2. type subject in subject field - // 3. speak message in message field - // 4. press send - VoiceInputLoggerCompatUtils.setHasVoiceLoggingInfoCompat(hasLoggingInfo); - } - - private boolean hasLoggingInfo(){ - return mHasLoggingInfo; - } - -} diff --git a/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java b/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java deleted file mode 100644 index 8ed279f42..000000000 --- a/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2008-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 - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.inputmethod.deprecated.voice; - -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Paint; - -import java.io.ByteArrayOutputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; - -/** - * Utility class to draw a waveform into a bitmap, given a byte array - * that represents the waveform as a sequence of 16-bit integers. - * Adapted from RecognitionActivity.java. - */ -public class WaveformImage { - private static final int SAMPLING_RATE = 8000; - - private WaveformImage() { - // Intentional empty constructor. - } - - public static Bitmap drawWaveform( - ByteArrayOutputStream waveBuffer, int w, int h, int start, int end) { - final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); - final Canvas c = new Canvas(b); - final Paint paint = new Paint(); - paint.setColor(0xFFFFFFFF); // 0xRRGGBBAA - paint.setAntiAlias(true); - paint.setStrokeWidth(0); - - final ShortBuffer buf = ByteBuffer - .wrap(waveBuffer.toByteArray()) - .order(ByteOrder.nativeOrder()) - .asShortBuffer(); - buf.position(0); - - final int numSamples = waveBuffer.size() / 2; - final int delay = (SAMPLING_RATE * 100 / 1000); - int endIndex = end / 2 + delay; - if (end == 0 || endIndex >= numSamples) { - endIndex = numSamples; - } - int index = start / 2 - delay; - if (index < 0) { - index = 0; - } - final int size = endIndex - index; - int numSamplePerPixel = 32; - int delta = size / (numSamplePerPixel * w); - if (delta == 0) { - numSamplePerPixel = size / w; - delta = 1; - } - - final float scale = 3.5f / 65536.0f; - // do one less column to make sure we won't read past - // the buffer. - try { - for (int i = 0; i < w - 1 ; i++) { - final float x = i; - for (int j = 0; j < numSamplePerPixel; j++) { - final short s = buf.get(index); - final float y = (h / 2) - (s * h * scale); - c.drawPoint(x, y, paint); - index += delta; - } - } - } catch (IndexOutOfBoundsException e) { - // this can happen, but we don't care - } - - return b; - } -} diff --git a/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java b/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java deleted file mode 100644 index 6c5f52ae2..000000000 --- a/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.inputmethod.deprecated.voice; - -import android.os.Bundle; - -import java.util.ArrayList; -import java.util.List; - -/** - * A set of text fields where speech has been explicitly enabled. - */ -public class Whitelist { - private List mConditions; - - public Whitelist() { - mConditions = new ArrayList(); - } - - public Whitelist(List conditions) { - this.mConditions = conditions; - } - - public void addApp(String app) { - Bundle bundle = new Bundle(); - bundle.putString("packageName", app); - mConditions.add(bundle); - } - - /** - * @return true if the field is a member of the whitelist. - */ - public boolean matches(FieldContext context) { - for (Bundle condition : mConditions) { - if (matches(condition, context.getBundle())) { - return true; - } - } - return false; - } - - /** - * @return true of all values in condition are matched by a value - * in target. - */ - private boolean matches(Bundle condition, Bundle target) { - for (String key : condition.keySet()) { - if (!condition.getString(key).equals(target.getString(key))) { - return false; - } - } - return true; - } -} diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java index 1bf2fc04e..c17fe8628 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java @@ -390,30 +390,4 @@ public class KeyboardSet { } } } - - // TODO: Should be removed. This is no longer required if {@link InputMethodSubtype} is - // supported. - public static String parseKeyboardLocale(Resources res, int resId) - throws XmlPullParserException, IOException { - final XmlPullParser parser = res.getXml(resId); - if (parser == null) - return ""; - int event; - while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) { - if (event == XmlPullParser.START_TAG) { - final String tag = parser.getName(); - if (TAG_KEYBOARD_SET.equals(tag)) { - final TypedArray keyboardSetAttr = res.obtainAttributes( - Xml.asAttributeSet(parser), R.styleable.KeyboardSet); - final String locale = keyboardSetAttr.getString( - R.styleable.KeyboardSet_keyboardLocale); - keyboardSetAttr.recycle(); - return locale; - } else { - throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD_SET); - } - } - } - return ""; - } } diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 7194cced3..62bcf6ca8 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -39,7 +39,6 @@ import android.widget.PopupWindow; import com.android.inputmethod.accessibility.AccessibilityUtils; import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; -import com.android.inputmethod.deprecated.VoiceProxy; import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy; import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; import com.android.inputmethod.keyboard.internal.KeySpecParser; @@ -828,12 +827,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke } } - @Override - protected void onAttachedToWindow() { - // Token is available from here. - VoiceProxy.getInstance().onAttachedToWindow(); - } - /** * Receives hover events from the input framework. This method overrides * View.dispatchHoverEvent(MotionEvent) on SDK version ICS or higher. On diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 8b32be937..f5909a692 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -60,8 +60,6 @@ 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 +191,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 +231,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar public static class UIHandler extends StaticInnerHandlerWrapper { 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 +268,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 +302,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 +423,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 +462,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 +562,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } unregisterReceiver(mReceiver); unregisterReceiver(mDictionaryPackInstallReceiver); - mVoiceProxy.destroy(); LatinImeLogger.commit(); LatinImeLogger.onDestroy(); super.onDestroy(); @@ -596,14 +580,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 +675,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 +696,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 +713,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 +728,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(); @@ -779,12 +742,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mHandler.cancelUpdateSuggestions(); } - @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, @@ -816,8 +773,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. @@ -905,7 +860,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mOptionsDialog.dismiss(); mOptionsDialog = null; } - mVoiceProxy.hideVoiceWindow(); super.hideWindow(); } @@ -1094,7 +1048,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (ic != null) { ic.finishComposingText(); } - mVoiceProxy.setVoiceInputHighlighted(false); } private void resetComposingState(final boolean alsoResetLastComposedWord) { @@ -1184,14 +1137,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. @@ -1351,7 +1297,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(); @@ -1396,7 +1341,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(); @@ -1406,8 +1350,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(); @@ -1506,7 +1448,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? @@ -1582,8 +1523,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(); @@ -1669,7 +1608,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) @@ -1749,8 +1687,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()); @@ -1859,8 +1796,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); @@ -1953,7 +1888,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( @@ -2206,11 +2140,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) { @@ -2269,11 +2198,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 @@ -2341,32 +2265,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/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index 110264892..650dcdc68 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -45,15 +45,13 @@ 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.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() { @@ -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,80 +349,12 @@ 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) { 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 voiceInputSupportedLocales = Arrays.asList( - supportedLocalesString.split("\\s+")); - return voiceInputSupportedLocales.contains(locale); - } } -- cgit v1.2.3-83-g751a From 0dbf6ab53d53e4cb08052310f38ae41662e27c8d Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 2 Apr 2012 20:54:17 +0900 Subject: Remove InputMethodInfoCompatWrapper Bug: 6129704 Change-Id: I0eca1ee7d1769ddc44f93c50f0723196299bc6d6 --- .../compat/InputMethodInfoCompatWrapper.java | 77 ---------------------- .../compat/InputMethodManagerCompatWrapper.java | 34 ++++------ .../android/inputmethod/latin/SubtypeSwitcher.java | 13 ++-- .../android/inputmethod/latin/SubtypeUtils.java | 18 ++--- 4 files changed, 26 insertions(+), 116 deletions(-) delete mode 100644 java/src/com/android/inputmethod/compat/InputMethodInfoCompatWrapper.java (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/src/com/android/inputmethod/compat/InputMethodInfoCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodInfoCompatWrapper.java deleted file mode 100644 index 831559809..000000000 --- a/java/src/com/android/inputmethod/compat/InputMethodInfoCompatWrapper.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2011 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.compat; - -import android.content.pm.PackageManager; -import android.content.pm.ServiceInfo; -import android.view.inputmethod.InputMethodInfo; - -import java.lang.reflect.Method; - -public class InputMethodInfoCompatWrapper { - private final InputMethodInfo mImi; - private static final Method METHOD_getSubtypeAt = CompatUtils.getMethod( - InputMethodInfo.class, "getSubtypeAt", int.class); - private static final Method METHOD_getSubtypeCount = CompatUtils.getMethod( - InputMethodInfo.class, "getSubtypeCount"); - - public InputMethodInfoCompatWrapper(InputMethodInfo imi) { - mImi = imi; - } - - public InputMethodInfo getInputMethodInfo() { - return mImi; - } - - public String getId() { - return mImi.getId(); - } - - public String getPackageName() { - return mImi.getPackageName(); - } - - public ServiceInfo getServiceInfo() { - return mImi.getServiceInfo(); - } - - public int getSubtypeCount() { - return (Integer) CompatUtils.invoke(mImi, 0, METHOD_getSubtypeCount); - } - - public InputMethodSubtypeCompatWrapper getSubtypeAt(int index) { - return new InputMethodSubtypeCompatWrapper(CompatUtils.invoke(mImi, null, - METHOD_getSubtypeAt, index)); - } - - public CharSequence loadLabel(PackageManager pm) { - return mImi.loadLabel(pm); - } - - @Override - public boolean equals(Object o) { - if (o instanceof InputMethodInfoCompatWrapper) { - return mImi.equals(((InputMethodInfoCompatWrapper)o).mImi); - } - return false; - } - - @Override - public int hashCode() { - return mImi.hashCode(); - } -} diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java index 3df6bea4b..cf6b37979 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -16,11 +16,7 @@ package com.android.inputmethod.compat; -import android.app.AlertDialog; import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.IBinder; @@ -29,14 +25,12 @@ import android.util.Log; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; -import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.SubtypeUtils; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -106,9 +100,9 @@ public class InputMethodManagerCompatWrapper { } public List getEnabledInputMethodSubtypeList( - InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) { + InputMethodInfo imi, boolean allowsImplicitlySelectedSubtypes) { Object retval = CompatUtils.invoke(mImm, null, METHOD_getEnabledInputMethodSubtypeList, - (imi != null ? imi.getInputMethodInfo() : null), allowsImplicitlySelectedSubtypes); + imi, allowsImplicitlySelectedSubtypes); if (retval == null || !(retval instanceof List) || ((List)retval).isEmpty()) { if (!FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) { // Returns an empty list @@ -131,7 +125,7 @@ public class InputMethodManagerCompatWrapper { return CompatUtils.copyInputMethodSubtypeListToWrapper(retval); } - private InputMethodInfoCompatWrapper getLatinImeInputMethodInfo() { + private InputMethodInfo getLatinImeInputMethodInfo() { if (TextUtils.isEmpty(mLatinImePackageName)) return null; return SubtypeUtils.getInputMethodInfo(mLatinImePackageName); @@ -146,7 +140,7 @@ public class InputMethodManagerCompatWrapper { return new InputMethodSubtypeCompatWrapper(0, 0, inputLocale.toString(), mode, ""); } - public Map> + public Map> getShortcutInputMethodsAndSubtypes() { Object retval = CompatUtils.invoke(mImm, null, METHOD_getShortcutInputMethodsAndSubtypes); if (retval == null || !(retval instanceof Map) || ((Map)retval).isEmpty()) { @@ -156,12 +150,12 @@ public class InputMethodManagerCompatWrapper { } // Creates dummy subtypes @SuppressWarnings("unused") - InputMethodInfoCompatWrapper imi = getLatinImeInputMethodInfo(); + InputMethodInfo imi = getLatinImeInputMethodInfo(); InputMethodSubtypeCompatWrapper voiceSubtype = getLastResortSubtype(VOICE_MODE); if (imi != null && voiceSubtype != null) { - Map> + Map> shortcutMap = - new HashMap>(); List subtypeList = new ArrayList(); @@ -172,15 +166,15 @@ public class InputMethodManagerCompatWrapper { return Collections.emptyMap(); } } - Map> shortcutMap = - new HashMap>(); + Map> shortcutMap = + new HashMap>(); final Map retvalMap = (Map)retval; for (Object key : retvalMap.keySet()) { if (!(key instanceof InputMethodInfo)) { Log.e(TAG, "Class type error."); return null; } - shortcutMap.put(new InputMethodInfoCompatWrapper((InputMethodInfo)key), + shortcutMap.put((InputMethodInfo)key, CompatUtils.copyInputMethodSubtypeListToWrapper(retvalMap.get(key))); } return shortcutMap; @@ -207,13 +201,9 @@ public class InputMethodManagerCompatWrapper { onlyCurrentIme); } - public List getEnabledInputMethodList() { + public List getEnabledInputMethodList() { if (mImm == null) return null; - List imis = new ArrayList(); - for (InputMethodInfo imi : mImm.getEnabledInputMethodList()) { - imis.add(new InputMethodInfoCompatWrapper(imi)); - } - return imis; + return mImm.getEnabledInputMethodList(); } public void showInputMethodPicker() { diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index de2e8be3d..5cdee1435 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -29,14 +29,13 @@ import android.os.AsyncTask; import android.os.IBinder; import android.text.TextUtils; import android.util.Log; +import android.view.inputmethod.InputMethodInfo; -import com.android.inputmethod.compat.InputMethodInfoCompatWrapper; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; import com.android.inputmethod.keyboard.KeyboardSwitcher; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.Map; @@ -47,7 +46,6 @@ public class SubtypeSwitcher { public static final String KEYBOARD_MODE = "keyboard"; private static final char LOCALE_SEPARATOR = '_'; - private static final String VOICE_MODE = "voice"; private static final String SUBTYPE_EXTRAVALUE_REQUIRE_NETWORK_CONNECTIVITY = "requireNetworkConnectivity"; @@ -68,7 +66,7 @@ public class SubtypeSwitcher { // Variants which should be changed only by reload functions. private boolean mNeedsToDisplayLanguage; private boolean mIsSystemLanguageSameAsInputLanguage; - private InputMethodInfoCompatWrapper mShortcutInputMethodInfo; + private InputMethodInfo mShortcutInputMethodInfo; private InputMethodSubtypeCompatWrapper mShortcutSubtype; private List mAllEnabledSubtypesOfCurrentInputMethod; private InputMethodSubtypeCompatWrapper mCurrentSubtype; @@ -168,11 +166,11 @@ public class SubtypeSwitcher { + ", " + mShortcutSubtype.getMode()))); } // TODO: Update an icon for shortcut IME - final Map> shortcuts = + final Map> shortcuts = mImm.getShortcutInputMethodsAndSubtypes(); mShortcutInputMethodInfo = null; mShortcutSubtype = null; - for (InputMethodInfoCompatWrapper imi : shortcuts.keySet()) { + for (InputMethodInfo imi : shortcuts.keySet()) { List subtypes = shortcuts.get(imi); // TODO: Returns the first found IMI for now. Should handle all shortcuts as // appropriate. @@ -320,8 +318,7 @@ public class SubtypeSwitcher { return getSubtypeIcon(mShortcutInputMethodInfo, mShortcutSubtype); } - private Drawable getSubtypeIcon( - InputMethodInfoCompatWrapper imi, InputMethodSubtypeCompatWrapper subtype) { + private Drawable getSubtypeIcon(InputMethodInfo imi, InputMethodSubtypeCompatWrapper subtype) { final PackageManager pm = mService.getPackageManager(); if (imi != null) { final String imiPackageName = imi.getPackageName(); diff --git a/java/src/com/android/inputmethod/latin/SubtypeUtils.java b/java/src/com/android/inputmethod/latin/SubtypeUtils.java index cb2bcf43f..8beb71bf1 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeUtils.java +++ b/java/src/com/android/inputmethod/latin/SubtypeUtils.java @@ -17,8 +17,8 @@ package com.android.inputmethod.latin; import android.content.Context; +import android.view.inputmethod.InputMethodInfo; -import com.android.inputmethod.compat.InputMethodInfoCompatWrapper; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; @@ -36,7 +36,7 @@ public class SubtypeUtils { final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); if (imm == null) return false; - final InputMethodInfoCompatWrapper myImi = getInputMethodInfo(context.getPackageName()); + final InputMethodInfo myImi = getInputMethodInfo(context.getPackageName()); final List subtypes = imm.getEnabledInputMethodSubtypeList(myImi, true); for (final InputMethodSubtypeCompatWrapper subtype : subtypes) { @@ -52,26 +52,26 @@ public class SubtypeUtils { final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); if (imm == null) return false; - final List enabledImis = imm.getEnabledInputMethodList(); + final List enabledImis = imm.getEnabledInputMethodList(); return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, enabledImis); } public static boolean hasMultipleEnabledSubtypesInThisIme(Context context, final boolean shouldIncludeAuxiliarySubtypes) { - final InputMethodInfoCompatWrapper myImi = getInputMethodInfo(context.getPackageName()); - final List imiList = Collections.singletonList(myImi); + final InputMethodInfo myImi = getInputMethodInfo(context.getPackageName()); + final List imiList = Collections.singletonList(myImi); return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, imiList); } private static boolean hasMultipleEnabledSubtypes(final boolean shouldIncludeAuxiliarySubtypes, - List imiList) { + List imiList) { final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); if (imm == null) return false; // Number of the filtered IMEs int filteredImisCount = 0; - for (InputMethodInfoCompatWrapper imi : imiList) { + for (InputMethodInfo imi : imiList) { // We can return true immediately after we find two or more filtered IMEs. if (filteredImisCount > 1) return true; final List subtypes = @@ -120,13 +120,13 @@ public class SubtypeUtils { return getInputMethodInfo(packageName).getId(); } - public static InputMethodInfoCompatWrapper getInputMethodInfo(String packageName) { + public static InputMethodInfo getInputMethodInfo(String packageName) { final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); if (imm == null) { throw new RuntimeException("Input method manager not found"); } - for (final InputMethodInfoCompatWrapper imi : imm.getEnabledInputMethodList()) { + for (final InputMethodInfo imi : imm.getEnabledInputMethodList()) { if (imi.getPackageName().equals(packageName)) return imi; } -- cgit v1.2.3-83-g751a From 19457316c1da5e4ca52d2fe8039d76469fbf1e61 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 2 Apr 2012 21:25:01 +0900 Subject: Remove CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED boolean Bug: 6129704 Change-Id: I7643e656c6e7656eff339cc301dd32f34dee83a4 --- java/res/xml/prefs.xml | 3 - .../android/inputmethod/compat/CompatUtils.java | 25 +++---- .../compat/InputMethodManagerCompatWrapper.java | 80 ++-------------------- .../compat/InputMethodServiceCompatWrapper.java | 37 ---------- .../com/android/inputmethod/latin/Settings.java | 42 +----------- .../android/inputmethod/latin/SubtypeSwitcher.java | 11 --- 6 files changed, 14 insertions(+), 184 deletions(-) (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml index ebca25089..c5c647aac 100644 --- a/java/res/xml/prefs.xml +++ b/java/res/xml/prefs.xml @@ -21,9 +21,6 @@ - = 11) { - // Refer to android.provider.Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS - action = INPUT_METHOD_SUBTYPE_SETTINGS; - intent = new Intent(action); - if (!TextUtils.isEmpty(inputMethodId)) { - intent.putExtra(EXTRA_INPUT_METHOD_ID, inputMethodId); - } - if (flagsForSubtypeSettings > 0) { - intent.setFlags(flagsForSubtypeSettings); - } - return intent; + // Refer to android.provider.Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS + final String action = INPUT_METHOD_SUBTYPE_SETTINGS; + final Intent intent = new Intent(action); + if (!TextUtils.isEmpty(inputMethodId)) { + intent.putExtra(EXTRA_INPUT_METHOD_ID, inputMethodId); } - throw new RuntimeException("Language selection doesn't supported on this platform"); + if (flagsForSubtypeSettings > 0) { + intent.setFlags(flagsForSubtypeSettings); + } + return intent; } public static Class getClass(String className) { diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java index cf6b37979..0f03c2ef8 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -17,23 +17,15 @@ package com.android.inputmethod.compat; import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; import android.os.IBinder; -import android.text.TextUtils; import android.util.Log; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; -import com.android.inputmethod.latin.SubtypeSwitcher; -import com.android.inputmethod.latin.SubtypeUtils; - import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; -import java.util.Locale; import java.util.Map; // TODO: Override this class with the concrete implementation if we need to take care of the @@ -61,18 +53,7 @@ public class InputMethodManagerCompatWrapper { private static final InputMethodManagerCompatWrapper sInstance = new InputMethodManagerCompatWrapper(); - // For the compatibility, IMM will create dummy subtypes if subtypes are not found. - // This is required to be false if the current behavior is broken. For now, it's ok to be true. - public static final boolean FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES = - !InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED; - private static final String VOICE_MODE = "voice"; - private static final String KEYBOARD_MODE = "keyboard"; - - private InputMethodServiceCompatWrapper mService; private InputMethodManager mImm; - private PackageManager mPackageManager; - private ApplicationInfo mApplicationInfo; - private String mLatinImePackageName; public static InputMethodManagerCompatWrapper getInstance() { if (sInstance.mImm == null) @@ -81,12 +62,8 @@ public class InputMethodManagerCompatWrapper { } public static void init(InputMethodServiceCompatWrapper service) { - sInstance.mService = service; sInstance.mImm = (InputMethodManager) service.getSystemService( Context.INPUT_METHOD_SERVICE); - sInstance.mLatinImePackageName = service.getPackageName(); - sInstance.mPackageManager = service.getPackageManager(); - sInstance.mApplicationInfo = service.getApplicationInfo(); } public InputMethodSubtypeCompatWrapper getCurrentInputMethodSubtype() { @@ -104,67 +81,18 @@ public class InputMethodManagerCompatWrapper { Object retval = CompatUtils.invoke(mImm, null, METHOD_getEnabledInputMethodSubtypeList, imi, allowsImplicitlySelectedSubtypes); if (retval == null || !(retval instanceof List) || ((List)retval).isEmpty()) { - if (!FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) { - // Returns an empty list - return Collections.emptyList(); - } - // Creates dummy subtypes - @SuppressWarnings("unused") - List subtypeList = - new ArrayList(); - InputMethodSubtypeCompatWrapper keyboardSubtype = getLastResortSubtype(KEYBOARD_MODE); - InputMethodSubtypeCompatWrapper voiceSubtype = getLastResortSubtype(VOICE_MODE); - if (keyboardSubtype != null) { - subtypeList.add(keyboardSubtype); - } - if (voiceSubtype != null) { - subtypeList.add(voiceSubtype); - } - return subtypeList; + // Returns an empty list + return Collections.emptyList(); } return CompatUtils.copyInputMethodSubtypeListToWrapper(retval); } - private InputMethodInfo getLatinImeInputMethodInfo() { - if (TextUtils.isEmpty(mLatinImePackageName)) - return null; - return SubtypeUtils.getInputMethodInfo(mLatinImePackageName); - } - - private static InputMethodSubtypeCompatWrapper getLastResortSubtype(String mode) { - if (VOICE_MODE.equals(mode) && !FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) - return null; - Locale inputLocale = SubtypeSwitcher.getInstance().getInputLocale(); - if (inputLocale == null) - return null; - return new InputMethodSubtypeCompatWrapper(0, 0, inputLocale.toString(), mode, ""); - } - public Map> getShortcutInputMethodsAndSubtypes() { Object retval = CompatUtils.invoke(mImm, null, METHOD_getShortcutInputMethodsAndSubtypes); if (retval == null || !(retval instanceof Map) || ((Map)retval).isEmpty()) { - if (!FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) { - // Returns an empty map - return Collections.emptyMap(); - } - // Creates dummy subtypes - @SuppressWarnings("unused") - InputMethodInfo imi = getLatinImeInputMethodInfo(); - InputMethodSubtypeCompatWrapper voiceSubtype = getLastResortSubtype(VOICE_MODE); - if (imi != null && voiceSubtype != null) { - Map> - shortcutMap = - new HashMap>(); - List subtypeList = - new ArrayList(); - subtypeList.add(voiceSubtype); - shortcutMap.put(imi, subtypeList); - return shortcutMap; - } else { - return Collections.emptyMap(); - } + // Returns an empty map + return Collections.emptyMap(); } Map> shortcutMap = new HashMap>(); diff --git a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java index 7c15be300..6386fed78 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java @@ -27,15 +27,6 @@ import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.latin.SubtypeSwitcher; public class InputMethodServiceCompatWrapper extends InputMethodService { - // CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED needs to be false if the API level is 10 - // or previous. Note that InputMethodSubtype was added in the API level 11. - // For the API level 11 or later, LatinIME should override onCurrentInputMethodSubtypeChanged(). - // For the API level 10 or previous, we handle the "subtype changed" events by ourselves - // without having support from framework -- onCurrentInputMethodSubtypeChanged(). - public static final boolean CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED = true; - - private InputMethodManagerCompatWrapper mImm; - // For compatibility of {@link InputMethodManager#showInputMethodPicker}. // TODO: Move this variable back to LatinIME when this compatibility wrapper is removed. protected AlertDialog mOptionsDialog; @@ -62,32 +53,6 @@ public class InputMethodServiceCompatWrapper extends InputMethodService { @Override public void onCreate() { super.onCreate(); - mImm = InputMethodManagerCompatWrapper.getInstance(); - } - - // When the API level is 10 or previous, notifyOnCurrentInputMethodSubtypeChanged should - // handle the event the current subtype was changed. LatinIME calls - // notifyOnCurrentInputMethodSubtypeChanged every time LatinIME - // changes the current subtype. - // This call is required to let LatinIME itself know a subtype changed - // event when the API level is 10 or previous. - @SuppressWarnings("unused") - public void notifyOnCurrentInputMethodSubtypeChanged( - InputMethodSubtypeCompatWrapper newSubtype) { - // Do nothing when the API level is 11 or later - // and FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES is not true - if (CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED && !InputMethodManagerCompatWrapper. - FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) { - return; - } - final InputMethodSubtypeCompatWrapper subtype = (newSubtype == null) - ? mImm.getCurrentInputMethodSubtype() - : newSubtype; - if (subtype != null) { - if (!InputMethodManagerCompatWrapper.FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES - && !subtype.isDummy()) return; - SubtypeSwitcher.getInstance().updateSubtype(subtype); - } } ////////////////////////////////////// @@ -95,8 +60,6 @@ public class InputMethodServiceCompatWrapper extends InputMethodService { ////////////////////////////////////// @Override public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) { - // Do nothing when the API level is 10 or previous - if (!CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) return; SubtypeSwitcher.getInstance().updateSubtype( new InputMethodSubtypeCompatWrapper(subtype)); } diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index fd61292df..7b98a7188 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -18,7 +18,6 @@ package com.android.inputmethod.latin; import android.app.Activity; import android.app.AlertDialog; -import android.app.Dialog; import android.app.Fragment; import android.app.backup.BackupManager; import android.content.Context; @@ -34,31 +33,20 @@ import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceGroup; import android.preference.PreferenceScreen; -import android.text.TextUtils; -import android.text.method.LinkMovementMethod; -import android.util.Log; import android.view.View; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; -import com.android.inputmethod.compat.CompatUtils; -import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; -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, OnPreferenceClickListener { - private static final String TAG = Settings.class.getSimpleName(); - + implements SharedPreferences.OnSharedPreferenceChangeListener { public static final boolean ENABLE_EXPERIMENTAL_SETTINGS = false; // In the same order as xml/prefs.xml public static final String PREF_GENERAL_SETTINGS = "general_settings"; - public static final String PREF_SUBTYPES_SETTINGS = "subtype_settings"; public static final String PREF_AUTO_CAP = "auto_cap"; public static final String PREF_VIBRATE_ON = "vibrate_on"; public static final String PREF_SOUND_ON = "sound_on"; @@ -90,7 +78,6 @@ public class Settings extends InputMethodSettingsActivity public static final String PREF_SELECTED_LANGUAGES = "selected_languages"; public static final String PREF_DEBUG_SETTINGS = "debug_settings"; - private PreferenceScreen mInputLanguageSelection; private PreferenceScreen mKeypressVibrationDurationSettingsPref; private PreferenceScreen mKeypressSoundVolumeSettingsPref; private ListPreference mVoicePreference; @@ -102,14 +89,10 @@ public class Settings extends InputMethodSettingsActivity // Prediction: use bigrams to predict the next word when there is no input for it yet private CheckBoxPreference mBigramPrediction; private Preference mDebugSettingsPreference; - private boolean mVoiceOn; - private AlertDialog mDialog; private TextView mKeypressVibrationDurationSettingsTextView; private TextView mKeypressSoundVolumeSettingsTextView; - private String mVoiceModeOff; - private void ensureConsistencyOfAutoCorrectionSettings() { final String autoCorrectionOff = getResources().getString( R.string.auto_correction_threshold_mode_index_off); @@ -140,18 +123,12 @@ public class Settings extends InputMethodSettingsActivity final Context context = getActivityInternal(); addPreferencesFromResource(R.xml.prefs); - mInputLanguageSelection = (PreferenceScreen) findPreference(PREF_SUBTYPES_SETTINGS); - mInputLanguageSelection.setOnPreferenceClickListener(this); mVoicePreference = (ListPreference) findPreference(PREF_VOICE_MODE); mShowCorrectionSuggestionsPreference = (ListPreference) findPreference(PREF_SHOW_SUGGESTIONS_SETTING); SharedPreferences prefs = getPreferenceManager().getSharedPreferences(); prefs.registerOnSharedPreferenceChangeListener(this); - mVoiceModeOff = getString(R.string.voice_mode_off); - mVoiceOn = !(prefs.getString(PREF_VOICE_MODE, mVoiceModeOff) - .equals(mVoiceModeOff)); - mAutoCorrectionThresholdPreference = (ListPreference) findPreference(PREF_AUTO_CORRECTION_THRESHOLD); mBigramSuggestion = (CheckBoxPreference) findPreference(PREF_BIGRAM_SUGGESTION); @@ -183,10 +160,6 @@ public class Settings extends InputMethodSettingsActivity generalSettings.removePreference(findPreference(PREF_VIBRATE_ON)); } - if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) { - generalSettings.removePreference(findPreference(PREF_SUBTYPES_SETTINGS)); - } - final boolean showPopupOption = res.getBoolean( R.bool.config_enable_show_popup_on_keypress_option); if (!showPopupOption) { @@ -318,25 +291,12 @@ public class Settings extends InputMethodSettingsActivity !SettingsValues.isLanguageSwitchKeySupressed(prefs)); } ensureConsistencyOfAutoCorrectionSettings(); - mVoiceOn = !(prefs.getString(PREF_VOICE_MODE, mVoiceModeOff) - .equals(mVoiceModeOff)); updateVoiceModeSummary(); updateShowCorrectionSuggestionsSummary(); updateKeyPreviewPopupDelaySummary(); refreshEnablingsOfKeypressSoundAndVibrationSettings(prefs, getResources()); } - @Override - public boolean onPreferenceClick(Preference pref) { - if (pref == mInputLanguageSelection) { - final String imeId = SubtypeUtils.getInputMethodId( - getActivityInternal().getApplicationInfo().packageName); - startActivity(CompatUtils.getInputLanguageSelectionIntent(imeId, 0)); - return true; - } - return false; - } - private void updateShowCorrectionSuggestionsSummary() { mShowCorrectionSuggestionsPreference.setSummary( getResources().getStringArray(R.array.prefs_suggestion_visibilities) diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index 5cdee1435..794e5dc3a 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -300,17 +300,6 @@ public class SubtypeSwitcher { mImm.setInputMethodAndSubtype(token, imiId, subtype); return null; } - - @Override - protected void onPostExecute(Void result) { - // Calls in this method need to be done in the same thread as the thread which - // called switchToShortcutIME(). - - // Notify an event that the current subtype was changed. This event will be - // handled if "onCurrentInputMethodSubtypeChanged" can't be implemented - // when the API level is 10 or previous. - mService.notifyOnCurrentInputMethodSubtypeChanged(subtype); - } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } -- cgit v1.2.3-83-g751a From 9cc2c94c8b4bfd4e00e5d3478b9f6e520e791bc5 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 2 Apr 2012 21:31:52 +0900 Subject: Remove InputMethodSubtypeCompatWrapper Bug: 6129704 Change-Id: I8f84f0f61a2205ac1fcd1cd40e3a586ee535282d --- .../inputmethod/compat/AbstractCompatWrapper.java | 39 ----- .../android/inputmethod/compat/CompatUtils.java | 13 -- .../compat/InputMethodManagerCompatWrapper.java | 72 ++------ .../compat/InputMethodServiceCompatWrapper.java | 16 -- .../compat/InputMethodSubtypeCompatWrapper.java | 188 --------------------- .../android/inputmethod/keyboard/KeyboardSet.java | 1 - .../com/android/inputmethod/latin/LatinIME.java | 9 +- .../android/inputmethod/latin/SubtypeSwitcher.java | 66 +++----- .../android/inputmethod/latin/SubtypeUtils.java | 19 +-- .../inputmethod/latin/ArbitrarySubtype.java | 54 ------ .../android/inputmethod/latin/InputTestsBase.java | 32 +++- 11 files changed, 81 insertions(+), 428 deletions(-) delete mode 100644 java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java delete mode 100644 java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java delete mode 100644 tests/src/com/android/inputmethod/latin/ArbitrarySubtype.java (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java b/java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java deleted file mode 100644 index 2c31c55b0..000000000 --- a/java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2011 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.compat; - -import android.util.Log; - -public abstract class AbstractCompatWrapper { - private static final String TAG = AbstractCompatWrapper.class.getSimpleName(); - protected final Object mObj; - - public AbstractCompatWrapper(Object obj) { - if (obj == null) { - Log.e(TAG, "Invalid input to AbstractCompatWrapper"); - } - mObj = obj; - } - - public Object getOriginalObject() { - return mObj; - } - - public boolean hasOriginalObject() { - return mObj != null; - } -} diff --git a/java/src/com/android/inputmethod/compat/CompatUtils.java b/java/src/com/android/inputmethod/compat/CompatUtils.java index f1f6a1220..ce427e9c9 100644 --- a/java/src/com/android/inputmethod/compat/CompatUtils.java +++ b/java/src/com/android/inputmethod/compat/CompatUtils.java @@ -23,8 +23,6 @@ import android.util.Log; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; public class CompatUtils { private static final String TAG = CompatUtils.class.getSimpleName(); @@ -131,15 +129,4 @@ public class CompatUtils { Log.e(TAG, "Exception in setFieldValue: " + e.getClass().getSimpleName()); } } - - public static List copyInputMethodSubtypeListToWrapper( - Object listObject) { - if (!(listObject instanceof List)) return null; - final List subtypes = - new ArrayList(); - for (Object o: (List)listObject) { - subtypes.add(new InputMethodSubtypeCompatWrapper(o)); - } - return subtypes; - } } diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java index 0f03c2ef8..7f0b071a3 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -21,10 +21,9 @@ import android.os.IBinder; import android.util.Log; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; +import android.view.inputmethod.InputMethodSubtype; import java.lang.reflect.Method; -import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,21 +31,6 @@ import java.util.Map; // performance. public class InputMethodManagerCompatWrapper { private static final String TAG = InputMethodManagerCompatWrapper.class.getSimpleName(); - private static final Method METHOD_getCurrentInputMethodSubtype = - CompatUtils.getMethod(InputMethodManager.class, "getCurrentInputMethodSubtype"); - private static final Method METHOD_getLastInputMethodSubtype = - CompatUtils.getMethod(InputMethodManager.class, "getLastInputMethodSubtype"); - private static final Method METHOD_getEnabledInputMethodSubtypeList = - CompatUtils.getMethod(InputMethodManager.class, "getEnabledInputMethodSubtypeList", - InputMethodInfo.class, boolean.class); - private static final Method METHOD_getShortcutInputMethodsAndSubtypes = - CompatUtils.getMethod(InputMethodManager.class, "getShortcutInputMethodsAndSubtypes"); - private static final Method METHOD_setInputMethodAndSubtype = - CompatUtils.getMethod( - InputMethodManager.class, "setInputMethodAndSubtype", IBinder.class, - String.class, InputMethodSubtypeCompatWrapper.CLASS_InputMethodSubtype); - private static final Method METHOD_switchToLastInputMethod = CompatUtils.getMethod( - InputMethodManager.class, "switchToLastInputMethod", IBinder.class); private static final Method METHOD_switchToNextInputMethod = CompatUtils.getMethod( InputMethodManager.class, "switchToNextInputMethod", IBinder.class, Boolean.TYPE); @@ -66,62 +50,30 @@ public class InputMethodManagerCompatWrapper { Context.INPUT_METHOD_SERVICE); } - public InputMethodSubtypeCompatWrapper getCurrentInputMethodSubtype() { - Object o = CompatUtils.invoke(mImm, null, METHOD_getCurrentInputMethodSubtype); - return new InputMethodSubtypeCompatWrapper(o); + public InputMethodSubtype getCurrentInputMethodSubtype() { + return mImm.getCurrentInputMethodSubtype(); } - public InputMethodSubtypeCompatWrapper getLastInputMethodSubtype() { - Object o = CompatUtils.invoke(mImm, null, METHOD_getLastInputMethodSubtype); - return new InputMethodSubtypeCompatWrapper(o); + public InputMethodSubtype getLastInputMethodSubtype() { + return mImm.getLastInputMethodSubtype(); } - public List getEnabledInputMethodSubtypeList( + public List getEnabledInputMethodSubtypeList( InputMethodInfo imi, boolean allowsImplicitlySelectedSubtypes) { - Object retval = CompatUtils.invoke(mImm, null, METHOD_getEnabledInputMethodSubtypeList, - imi, allowsImplicitlySelectedSubtypes); - if (retval == null || !(retval instanceof List) || ((List)retval).isEmpty()) { - // Returns an empty list - return Collections.emptyList(); - } - return CompatUtils.copyInputMethodSubtypeListToWrapper(retval); + return mImm.getEnabledInputMethodSubtypeList(imi, allowsImplicitlySelectedSubtypes); } - public Map> - getShortcutInputMethodsAndSubtypes() { - Object retval = CompatUtils.invoke(mImm, null, METHOD_getShortcutInputMethodsAndSubtypes); - if (retval == null || !(retval instanceof Map) || ((Map)retval).isEmpty()) { - // Returns an empty map - return Collections.emptyMap(); - } - Map> shortcutMap = - new HashMap>(); - final Map retvalMap = (Map)retval; - for (Object key : retvalMap.keySet()) { - if (!(key instanceof InputMethodInfo)) { - Log.e(TAG, "Class type error."); - return null; - } - shortcutMap.put((InputMethodInfo)key, - CompatUtils.copyInputMethodSubtypeListToWrapper(retvalMap.get(key))); - } - return shortcutMap; + public Map> getShortcutInputMethodsAndSubtypes() { + return mImm.getShortcutInputMethodsAndSubtypes(); } // We don't call this method when we switch between subtypes within this IME. - public void setInputMethodAndSubtype( - IBinder token, String id, InputMethodSubtypeCompatWrapper subtype) { - // TODO: Support subtype change on non-subtype-supported platform. - if (subtype != null && subtype.hasOriginalObject()) { - CompatUtils.invoke(mImm, null, METHOD_setInputMethodAndSubtype, - token, id, subtype.getOriginalObject()); - } else { - mImm.setInputMethod(token, id); - } + public void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) { + mImm.setInputMethodAndSubtype(token, id, subtype); } public boolean switchToLastInputMethod(IBinder token) { - return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToLastInputMethod, token); + return mImm.switchToLastInputMethod(token); } public boolean switchToNextInputMethod(IBinder token, boolean onlyCurrentIme) { diff --git a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java index 6386fed78..363b4b095 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java @@ -21,10 +21,8 @@ import android.inputmethodservice.InputMethodService; import android.os.IBinder; import android.view.Window; import android.view.WindowManager; -import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.keyboard.KeyboardSwitcher; -import com.android.inputmethod.latin.SubtypeSwitcher; public class InputMethodServiceCompatWrapper extends InputMethodService { // For compatibility of {@link InputMethodManager#showInputMethodPicker}. @@ -50,20 +48,6 @@ public class InputMethodServiceCompatWrapper extends InputMethodService { dialog.show(); } - @Override - public void onCreate() { - super.onCreate(); - } - - ////////////////////////////////////// - // Functions using API v11 or later // - ////////////////////////////////////// - @Override - public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) { - SubtypeSwitcher.getInstance().updateSubtype( - new InputMethodSubtypeCompatWrapper(subtype)); - } - protected static void setTouchableRegionCompat(InputMethodService.Insets outInsets, int x, int y, int width, int height) { outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION; diff --git a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java deleted file mode 100644 index 574158825..000000000 --- a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (C) 2011 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.compat; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.text.TextUtils; -import android.util.Log; - -import com.android.inputmethod.latin.LatinImeLogger; - -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Locale; - -// TODO: Override this class with the concrete implementation if we need to take care of the -// performance. -public class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper { - private static final boolean DBG = LatinImeLogger.sDBG; - private static final String TAG = InputMethodSubtypeCompatWrapper.class.getSimpleName(); - private static final String DEFAULT_LOCALE = "en_US"; - private static final String DEFAULT_MODE = "keyboard"; - - public static final Class CLASS_InputMethodSubtype = - CompatUtils.getClass("android.view.inputmethod.InputMethodSubtype"); - private static final Method METHOD_getNameResId = - CompatUtils.getMethod(CLASS_InputMethodSubtype, "getNameResId"); - private static final Method METHOD_getIconResId = - CompatUtils.getMethod(CLASS_InputMethodSubtype, "getIconResId"); - private static final Method METHOD_getLocale = - CompatUtils.getMethod(CLASS_InputMethodSubtype, "getLocale"); - private static final Method METHOD_getMode = - CompatUtils.getMethod(CLASS_InputMethodSubtype, "getMode"); - private static final Method METHOD_getExtraValue = - CompatUtils.getMethod(CLASS_InputMethodSubtype, "getExtraValue"); - private static final Method METHOD_containsExtraValueKey = - CompatUtils.getMethod(CLASS_InputMethodSubtype, "containsExtraValueKey", String.class); - private static final Method METHOD_getExtraValueOf = - CompatUtils.getMethod(CLASS_InputMethodSubtype, "getExtraValueOf", String.class); - private static final Method METHOD_isAuxiliary = - CompatUtils.getMethod(CLASS_InputMethodSubtype, "isAuxiliary"); - private static final Method METHOD_getDisplayName = - CompatUtils.getMethod(CLASS_InputMethodSubtype, "getDisplayName", Context.class, - String.class, ApplicationInfo.class); - - private final int mDummyNameResId; - private final int mDummyIconResId; - private final String mDummyLocale; - private final String mDummyMode; - private final String mDummyExtraValues; - - public InputMethodSubtypeCompatWrapper(Object subtype) { - super((CLASS_InputMethodSubtype != null && CLASS_InputMethodSubtype.isInstance(subtype)) - ? subtype : new Object()); - mDummyNameResId = 0; - mDummyIconResId = 0; - mDummyLocale = DEFAULT_LOCALE; - mDummyMode = DEFAULT_MODE; - mDummyExtraValues = ""; - } - - // Constructor for creating a dummy subtype. - public InputMethodSubtypeCompatWrapper(int nameResId, int iconResId, String locale, - String mode, String extraValues) { - super(new Object()); - if (DBG) { - Log.d(TAG, "CreateInputMethodSubtypeCompatWrapper"); - } - mDummyNameResId = nameResId; - mDummyIconResId = iconResId; - mDummyLocale = locale != null ? locale : ""; - mDummyMode = mode != null ? mode : ""; - mDummyExtraValues = extraValues != null ? extraValues : ""; - } - - public int getNameResId() { - if (mObj == null) return mDummyNameResId; - return (Integer)CompatUtils.invoke(mObj, 0, METHOD_getNameResId); - } - - public int getIconResId() { - if (mObj == null) return mDummyIconResId; - return (Integer)CompatUtils.invoke(mObj, 0, METHOD_getIconResId); - } - - public String getLocale() { - if (mObj == null) return mDummyLocale; - final String s = (String)CompatUtils.invoke(mObj, null, METHOD_getLocale); - return s != null ? s : DEFAULT_LOCALE; - } - - public String getMode() { - if (mObj == null) return mDummyMode; - String s = (String)CompatUtils.invoke(mObj, null, METHOD_getMode); - if (TextUtils.isEmpty(s)) return DEFAULT_MODE; - return s; - } - - public String getExtraValue() { - if (mObj == null) return mDummyExtraValues; - return (String)CompatUtils.invoke(mObj, null, METHOD_getExtraValue); - } - - public boolean containsExtraValueKey(String key) { - return (Boolean)CompatUtils.invoke(mObj, false, METHOD_containsExtraValueKey, key); - } - - public String getExtraValueOf(String key) { - return (String)CompatUtils.invoke(mObj, null, METHOD_getExtraValueOf, key); - } - - public boolean isAuxiliary() { - return (Boolean)CompatUtils.invoke(mObj, false, METHOD_isAuxiliary); - } - - public CharSequence getDisplayName(Context context, String packageName, - ApplicationInfo appInfo) { - if (mObj != null) { - return (CharSequence)CompatUtils.invoke( - mObj, "", METHOD_getDisplayName, context, packageName, appInfo); - } - - // The code below are based on {@link InputMethodSubtype#getDisplayName}. - - final Locale locale = new Locale(getLocale()); - final String localeStr = locale.getDisplayName(); - if (getNameResId() == 0) { - return localeStr; - } - final CharSequence subtypeName = context.getText(getNameResId()); - if (!TextUtils.isEmpty(localeStr)) { - return String.format(subtypeName.toString(), localeStr); - } else { - return localeStr; - } - } - - public boolean isDummy() { - return !hasOriginalObject(); - } - - @Override - public boolean equals(Object o) { - if (o instanceof InputMethodSubtypeCompatWrapper) { - InputMethodSubtypeCompatWrapper subtype = (InputMethodSubtypeCompatWrapper)o; - if (mObj == null) { - // easy check of dummy subtypes - return (mDummyNameResId == subtype.mDummyNameResId - && mDummyIconResId == subtype.mDummyIconResId - && mDummyLocale.equals(subtype.mDummyLocale) - && mDummyMode.equals(subtype.mDummyMode) - && mDummyExtraValues.equals(subtype.mDummyExtraValues)); - } - return mObj.equals(subtype.getOriginalObject()); - } else { - return mObj.equals(o); - } - } - - @Override - public int hashCode() { - if (mObj == null) { - return hashCodeInternal(mDummyNameResId, mDummyIconResId, mDummyLocale, - mDummyMode, mDummyExtraValues); - } - return mObj.hashCode(); - } - - private static int hashCodeInternal(int nameResId, int iconResId, String locale, - String mode, String extraValue) { - return Arrays - .hashCode(new Object[] { nameResId, iconResId, locale, mode, extraValue }); - } -} diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java index f0c773ff4..4d0f00380 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java @@ -237,7 +237,6 @@ public class KeyboardSet { return this; } - // TODO: Use InputMethodSubtype object as argument. public Builder setSubtype(Locale inputLocale, boolean asciiCapable) { final boolean deprecatedForceAscii = StringUtils.inPrivateImeOptions( mPackageName, LatinIME.IME_OPTION_FORCE_ASCII, mEditorInfo); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 69780d0fd..2cd291add 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -49,6 +49,7 @@ import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CorrectionInfo; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; +import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.accessibility.AccessibilityUtils; import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; @@ -56,7 +57,6 @@ import com.android.inputmethod.compat.CompatUtils; import com.android.inputmethod.compat.EditorInfoCompatUtils; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; -import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; import com.android.inputmethod.compat.SuggestionSpanUtils; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardActionListener; @@ -627,6 +627,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mHandler.onFinishInput(); } + @Override + public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) { + SubtypeSwitcher.getInstance().updateSubtype(subtype); + } + private void onStartInputInternal(EditorInfo editorInfo, boolean restarting) { super.onStartInput(editorInfo, restarting); } @@ -1178,7 +1183,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar final boolean includesOtherImes = mSettingsValues.mIncludesOtherImesInLanguageSwitchList; final IBinder token = getWindow().getWindow().getAttributes().token; if (mShouldSwitchToLastSubtype) { - final InputMethodSubtypeCompatWrapper lastSubtype = mImm.getLastInputMethodSubtype(); + final InputMethodSubtype lastSubtype = mImm.getLastInputMethodSubtype(); final boolean lastSubtypeBelongsToThisIme = SubtypeUtils.checkIfSubtypeBelongsToThisIme( this, lastSubtype); if ((includesOtherImes || lastSubtypeBelongsToThisIme) diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index 794e5dc3a..e35364420 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -30,9 +30,9 @@ import android.os.IBinder; import android.text.TextUtils; import android.util.Log; import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; -import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; import com.android.inputmethod.keyboard.KeyboardSwitcher; import java.util.ArrayList; @@ -57,9 +57,8 @@ public class SubtypeSwitcher { private /* final */ InputMethodManagerCompatWrapper mImm; private /* final */ Resources mResources; private /* final */ ConnectivityManager mConnectivityManager; - private final ArrayList - mEnabledKeyboardSubtypesOfCurrentInputMethod = - new ArrayList(); + private final ArrayList mEnabledKeyboardSubtypesOfCurrentInputMethod = + new ArrayList(); private final ArrayList mEnabledLanguagesOfCurrentInputMethod = new ArrayList(); /*-----------------------------------------------------------*/ @@ -67,9 +66,10 @@ public class SubtypeSwitcher { private boolean mNeedsToDisplayLanguage; private boolean mIsSystemLanguageSameAsInputLanguage; private InputMethodInfo mShortcutInputMethodInfo; - private InputMethodSubtypeCompatWrapper mShortcutSubtype; - private List mAllEnabledSubtypesOfCurrentInputMethod; - private InputMethodSubtypeCompatWrapper mCurrentSubtype; + private InputMethodSubtype mShortcutSubtype; + private List mAllEnabledSubtypesOfCurrentInputMethod; + // Note: This variable is always non-null after {@link #initialize(LatinIME)}. + private InputMethodSubtype mCurrentSubtype; private Locale mSystemLocale; private Locale mInputLocale; private String mInputLocaleStr; @@ -102,7 +102,7 @@ public class SubtypeSwitcher { mSystemLocale = null; mInputLocale = null; mInputLocaleStr = null; - mCurrentSubtype = null; + mCurrentSubtype = mImm.getCurrentInputMethodSubtype(); mAllEnabledSubtypesOfCurrentInputMethod = null; final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo(); @@ -132,7 +132,7 @@ public class SubtypeSwitcher { null, true); mEnabledLanguagesOfCurrentInputMethod.clear(); mEnabledKeyboardSubtypesOfCurrentInputMethod.clear(); - for (InputMethodSubtypeCompatWrapper ims : mAllEnabledSubtypesOfCurrentInputMethod) { + for (InputMethodSubtype ims : mAllEnabledSubtypesOfCurrentInputMethod) { final String locale = getSubtypeLocale(ims); final String mode = ims.getMode(); mLocaleSplitter.setString(locale); @@ -166,12 +166,12 @@ public class SubtypeSwitcher { + ", " + mShortcutSubtype.getMode()))); } // TODO: Update an icon for shortcut IME - final Map> shortcuts = + final Map> shortcuts = mImm.getShortcutInputMethodsAndSubtypes(); mShortcutInputMethodInfo = null; mShortcutSubtype = null; for (InputMethodInfo imi : shortcuts.keySet()) { - List subtypes = shortcuts.get(imi); + List subtypes = shortcuts.get(imi); // TODO: Returns the first found IMI for now. Should handle all shortcuts as // appropriate. mShortcutInputMethodInfo = imi; @@ -189,27 +189,17 @@ public class SubtypeSwitcher { } } - private static String getSubtypeLocale(InputMethodSubtypeCompatWrapper subtype) { + private static String getSubtypeLocale(InputMethodSubtype subtype) { final String keyboardLocale = subtype.getExtraValueOf( LatinIME.SUBTYPE_EXTRA_VALUE_KEYBOARD_LOCALE); return keyboardLocale != null ? keyboardLocale : subtype.getLocale(); } // Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function. - public void updateSubtype(InputMethodSubtypeCompatWrapper newSubtype) { - final String newLocale; - final String newMode; + public void updateSubtype(InputMethodSubtype newSubtype) { + final String newLocale = getSubtypeLocale(newSubtype); + final String newMode = newSubtype.getMode(); final String oldMode = getCurrentSubtypeMode(); - if (newSubtype == null) { - // Normally, newSubtype shouldn't be null. But just in case newSubtype was null, - // fallback to the default locale. - Log.w(TAG, "Couldn't get the current subtype."); - newLocale = "en_US"; - newMode = KEYBOARD_MODE; - } else { - newLocale = getSubtypeLocale(newSubtype); - newMode = newSubtype.getMode(); - } if (DBG) { Log.w(TAG, "Update subtype to:" + newLocale + "," + newMode + ", from: " + mInputLocaleStr + ", " + oldMode); @@ -284,12 +274,10 @@ public class SubtypeSwitcher { } final String imiId = mShortcutInputMethodInfo.getId(); - final InputMethodSubtypeCompatWrapper subtype = mShortcutSubtype; - switchToTargetIME(imiId, subtype); + switchToTargetIME(imiId, mShortcutSubtype); } - private void switchToTargetIME( - final String imiId, final InputMethodSubtypeCompatWrapper subtype) { + private void switchToTargetIME(final String imiId, final InputMethodSubtype subtype) { final IBinder token = mService.getWindow().getWindow().getAttributes().token; if (token == null) { return; @@ -307,7 +295,7 @@ public class SubtypeSwitcher { return getSubtypeIcon(mShortcutInputMethodInfo, mShortcutSubtype); } - private Drawable getSubtypeIcon(InputMethodInfo imi, InputMethodSubtypeCompatWrapper subtype) { + private Drawable getSubtypeIcon(InputMethodInfo imi, InputMethodSubtype subtype) { final PackageManager pm = mService.getPackageManager(); if (imi != null) { final String imiPackageName = imi.getPackageName(); @@ -348,15 +336,9 @@ public class SubtypeSwitcher { if (mShortcutSubtype == null) { return true; } - // For compatibility, if the shortcut subtype is dummy, we assume the shortcut IME - // (built-in voice dummy subtype) is available. - if (!mShortcutSubtype.hasOriginalObject()) { - return true; - } final boolean allowsImplicitlySelectedSubtypes = true; - for (final InputMethodSubtypeCompatWrapper enabledSubtype : - mImm.getEnabledInputMethodSubtypeList( - mShortcutInputMethodInfo, allowsImplicitlySelectedSubtypes)) { + for (final InputMethodSubtype enabledSubtype : mImm.getEnabledInputMethodSubtypeList( + mShortcutInputMethodInfo, allowsImplicitlySelectedSubtypes)) { if (enabledSubtype.equals(mShortcutSubtype)) { return true; } @@ -448,20 +430,20 @@ public class SubtypeSwitcher { public String getCurrentSubtypeExtraValue() { // If null, return what an empty ExtraValue would return : the empty string. - return null != mCurrentSubtype ? mCurrentSubtype.getExtraValue() : ""; + return mCurrentSubtype.getExtraValue(); } public boolean currentSubtypeContainsExtraValueKey(String key) { // If null, return what an empty ExtraValue would return : false. - return null != mCurrentSubtype ? mCurrentSubtype.containsExtraValueKey(key) : false; + return mCurrentSubtype.containsExtraValueKey(key); } public String getCurrentSubtypeExtraValueOf(String key) { // If null, return what an empty ExtraValue would return : null. - return null != mCurrentSubtype ? mCurrentSubtype.getExtraValueOf(key) : null; + return mCurrentSubtype.getExtraValueOf(key); } public String getCurrentSubtypeMode() { - return null != mCurrentSubtype ? mCurrentSubtype.getMode() : KEYBOARD_MODE; + return mCurrentSubtype.getMode(); } } diff --git a/java/src/com/android/inputmethod/latin/SubtypeUtils.java b/java/src/com/android/inputmethod/latin/SubtypeUtils.java index 8beb71bf1..2c5d58200 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeUtils.java +++ b/java/src/com/android/inputmethod/latin/SubtypeUtils.java @@ -18,9 +18,9 @@ package com.android.inputmethod.latin; import android.content.Context; import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; -import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; import java.util.Collections; import java.util.List; @@ -31,15 +31,13 @@ public class SubtypeUtils { } // TODO: Cache my InputMethodInfo and/or InputMethodSubtype list. - public static boolean checkIfSubtypeBelongsToThisIme(Context context, - InputMethodSubtypeCompatWrapper ims) { + public static boolean checkIfSubtypeBelongsToThisIme(Context context, InputMethodSubtype ims) { final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); if (imm == null) return false; final InputMethodInfo myImi = getInputMethodInfo(context.getPackageName()); - final List subtypes = - imm.getEnabledInputMethodSubtypeList(myImi, true); - for (final InputMethodSubtypeCompatWrapper subtype : subtypes) { + final List subtypes = imm.getEnabledInputMethodSubtypeList(myImi, true); + for (final InputMethodSubtype subtype : subtypes) { if (subtype.equals(ims)) { return true; } @@ -74,7 +72,7 @@ public class SubtypeUtils { for (InputMethodInfo imi : imiList) { // We can return true immediately after we find two or more filtered IMEs. if (filteredImisCount > 1) return true; - final List subtypes = + final List subtypes = imm.getEnabledInputMethodSubtypeList(imi, true); // IMEs that have no subtypes should be counted. if (subtypes.isEmpty()) { @@ -83,7 +81,7 @@ public class SubtypeUtils { } int auxCount = 0; - for (InputMethodSubtypeCompatWrapper subtype : subtypes) { + for (InputMethodSubtype subtype : subtypes) { if (subtype.isAuxiliary()) { ++auxCount; } @@ -102,13 +100,12 @@ public class SubtypeUtils { if (filteredImisCount > 1) { return true; } - final List subtypes = - imm.getEnabledInputMethodSubtypeList(null, true); + final List subtypes = imm.getEnabledInputMethodSubtypeList(null, true); int keyboardCount = 0; // imm.getEnabledInputMethodSubtypeList(null, true) will return the current IME's // both explicitly and implicitly enabled input method subtype. // (The current IME should be LatinIME.) - for (InputMethodSubtypeCompatWrapper subtype : subtypes) { + for (InputMethodSubtype subtype : subtypes) { if (SubtypeSwitcher.KEYBOARD_MODE.equals(subtype.getMode())) { ++keyboardCount; } diff --git a/tests/src/com/android/inputmethod/latin/ArbitrarySubtype.java b/tests/src/com/android/inputmethod/latin/ArbitrarySubtype.java deleted file mode 100644 index 1e3482ca7..000000000 --- a/tests/src/com/android/inputmethod/latin/ArbitrarySubtype.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; - -public class ArbitrarySubtype extends InputMethodSubtypeCompatWrapper { - final String mLocale; - final String mExtraValue; - - public ArbitrarySubtype(final String locale, final String extraValue) { - super(locale); - mLocale = locale; - mExtraValue = extraValue; - } - - public String getLocale() { - return mLocale; - } - - public String getExtraValue() { - return mExtraValue; - } - - public String getMode() { - return "keyboard"; - } - - public String getExtraValueOf(final String key) { - if (LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE.equals(key)) { - return ""; - } else { - return null; - } - } - - public boolean containsExtraValueKey(final String key) { - return LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE.equals(key); - } -} diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java index 7d97eed9e..5f6b229dd 100644 --- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java +++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java @@ -30,6 +30,9 @@ import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; +import android.view.inputmethod.InputMethodSubtype; import android.widget.FrameLayout; import android.widget.TextView; @@ -37,6 +40,8 @@ import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardActionListener; +import java.util.HashMap; + public class InputTestsBase extends ServiceTestCase { private static final String PREF_DEBUG_MODE = "debug_mode"; @@ -48,6 +53,8 @@ public class InputTestsBase extends ServiceTestCase { protected Keyboard mKeyboard; protected TextView mTextView; protected InputConnection mInputConnection; + private final HashMap mSubtypeMap = + new HashMap(); // A helper class to ease span tests public static class Span { @@ -108,6 +115,7 @@ public class InputTestsBase extends ServiceTestCase { final boolean previousDebugSetting = setDebugMode(true); mLatinIME.onCreate(); setDebugMode(previousDebugSetting); + initSubtypeMap(); final EditorInfo ei = new EditorInfo(); ei.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT; final InputConnection ic = mTextView.onCreateInputConnection(ei); @@ -126,6 +134,23 @@ public class InputTestsBase extends ServiceTestCase { changeLanguage("en_US"); } + private void initSubtypeMap() { + final InputMethodManager imm = (InputMethodManager)mLatinIME.getSystemService( + Context.INPUT_METHOD_SERVICE); + final String packageName = mLatinIME.getPackageName(); + for (final InputMethodInfo imi : imm.getEnabledInputMethodList()) { + if (imi.getPackageName().equals(packageName)) { + for (final InputMethodSubtype ims : + imm.getEnabledInputMethodSubtypeList(imi, true)) { + final String locale = ims.getLocale(); + mSubtypeMap.put(locale, ims); + } + return; + } + } + fail("LatinIME is disabled"); + } + // We need to run the messages added to the handler from LatinIME. The only way to do // that is to call Looper#loop() on the right looper, so we're going to get the looper // object and call #loop() here. The messages in the handler actually run on the UI @@ -217,8 +242,11 @@ public class InputTestsBase extends ServiceTestCase { } protected void changeLanguage(final String locale) { - SubtypeSwitcher.getInstance().updateSubtype( - new ArbitrarySubtype(locale, LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE)); + final InputMethodSubtype subtype = mSubtypeMap.get(locale); + if (subtype == null) { + fail("InputMethodSubtype for locale " + locale + " is not enabled"); + } + SubtypeSwitcher.getInstance().updateSubtype(subtype); waitForDictionaryToBeLoaded(); } -- cgit v1.2.3-83-g751a From 13d6ecc4c275b9e9c38c7713bb2c69d37f3467f3 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 2 Apr 2012 22:25:08 +0900 Subject: Remove InputMethodServiceCompatWrapper Bug: 6129704 Change-Id: I76f2854e27623be940a711d0d48fd3f90132141c --- .../compat/InputMethodManagerCompatWrapper.java | 3 +- .../compat/InputMethodServiceCompatWrapper.java | 56 ---------------------- .../com/android/inputmethod/latin/LatinIME.java | 29 +++++++++-- 3 files changed, 28 insertions(+), 60 deletions(-) delete mode 100644 java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java index 7f0b071a3..7be95a095 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -17,6 +17,7 @@ package com.android.inputmethod.compat; import android.content.Context; +import android.inputmethodservice.InputMethodService; import android.os.IBinder; import android.util.Log; import android.view.inputmethod.InputMethodInfo; @@ -45,7 +46,7 @@ public class InputMethodManagerCompatWrapper { return sInstance; } - public static void init(InputMethodServiceCompatWrapper service) { + public static void init(InputMethodService service) { sInstance.mImm = (InputMethodManager) service.getSystemService( Context.INPUT_METHOD_SERVICE); } diff --git a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java deleted file mode 100644 index 363b4b095..000000000 --- a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2011 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.compat; - -import android.app.AlertDialog; -import android.inputmethodservice.InputMethodService; -import android.os.IBinder; -import android.view.Window; -import android.view.WindowManager; - -import com.android.inputmethod.keyboard.KeyboardSwitcher; - -public class InputMethodServiceCompatWrapper extends InputMethodService { - // For compatibility of {@link InputMethodManager#showInputMethodPicker}. - // TODO: Move this variable back to LatinIME when this compatibility wrapper is removed. - protected AlertDialog mOptionsDialog; - - public void showOptionDialogInternal(AlertDialog dialog) { - final IBinder windowToken = KeyboardSwitcher.getInstance().getKeyboardView() - .getWindowToken(); - if (windowToken == null) return; - - dialog.setCancelable(true); - dialog.setCanceledOnTouchOutside(true); - - final Window window = dialog.getWindow(); - final WindowManager.LayoutParams lp = window.getAttributes(); - lp.token = windowToken; - lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; - window.setAttributes(lp); - window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); - - mOptionsDialog = dialog; - dialog.show(); - } - - protected static void setTouchableRegionCompat(InputMethodService.Insets outInsets, - int x, int y, int width, int height) { - outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION; - outInsets.touchableRegion.set(x, y, width, height); - } -} diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 2cd291add..3b41e3b0c 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -45,6 +45,8 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.ViewParent; +import android.view.Window; +import android.view.WindowManager; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CorrectionInfo; import android.view.inputmethod.EditorInfo; @@ -56,7 +58,6 @@ import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; import com.android.inputmethod.compat.CompatUtils; import com.android.inputmethod.compat.EditorInfoCompatUtils; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; -import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; import com.android.inputmethod.compat.SuggestionSpanUtils; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardActionListener; @@ -75,7 +76,7 @@ import java.util.Locale; /** * Input method implementation for Qwerty'ish keyboard. */ -public class LatinIME extends InputMethodServiceCompatWrapper implements KeyboardActionListener, +public class LatinIME extends InputMethodService implements KeyboardActionListener, SuggestionsView.Listener { private static final String TAG = LatinIME.class.getSimpleName(); private static final boolean TRACE = false; @@ -225,6 +226,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private boolean mIsAutoCorrectionIndicatorOn; + private AlertDialog mOptionsDialog; + public final UIHandler mHandler = new UIHandler(this); public static class UIHandler extends StaticInnerHandlerWrapper { @@ -973,7 +976,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar final int touchHeight = inputView.getHeight() + extraHeight // Extend touchable region below the keyboard. + EXTENDED_TOUCHABLE_REGION_HEIGHT; - setTouchableRegionCompat(outInsets, 0, touchY, touchWidth, touchHeight); + outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION; + outInsets.touchableRegion.set(0, touchY, touchWidth, touchHeight); } outInsets.contentTopInsets = touchY; outInsets.visibleTopInsets = touchY; @@ -2268,6 +2272,25 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar showOptionDialogInternal(builder.create()); } + private void showOptionDialogInternal(AlertDialog dialog) { + final IBinder windowToken = KeyboardSwitcher.getInstance().getKeyboardView() + .getWindowToken(); + if (windowToken == null) return; + + dialog.setCancelable(true); + dialog.setCanceledOnTouchOutside(true); + + final Window window = dialog.getWindow(); + final WindowManager.LayoutParams lp = window.getAttributes(); + lp.token = windowToken; + lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; + window.setAttributes(lp); + window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); + + mOptionsDialog = dialog; + dialog.show(); + } + @Override protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { super.dump(fd, fout, args); -- cgit v1.2.3-83-g751a From fde7efd87710dcc9e8376e3ef6db287e254c65fc Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Tue, 3 Apr 2012 18:01:04 +0900 Subject: Add private constructor to utility classes Bug: 6129704 Change-Id: I52925ae7bd80683f63efc48649448865a5654f41 --- java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java | 6 +++++- .../android/inputmethod/compat/InputMethodManagerCompatWrapper.java | 4 ++++ java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java | 4 ++++ .../com/android/inputmethod/compat/SuggestionsInfoCompatUtils.java | 1 + 4 files changed, 14 insertions(+), 1 deletion(-) (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java b/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java index d1af7a527..08c246f8b 100644 --- a/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java +++ b/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java @@ -21,12 +21,16 @@ import android.view.inputmethod.EditorInfo; import java.lang.reflect.Field; public class EditorInfoCompatUtils { + // EditorInfo.IME_FLAG_FORCE_ASCII has been introduced since API#16 (JellyBean). private static final Field FIELD_IME_FLAG_FORCE_ASCII = CompatUtils.getField( EditorInfo.class, "IME_FLAG_FORCE_ASCII"); private static final Integer OBJ_IME_FLAG_FORCE_ASCII = (Integer) CompatUtils .getFieldValue(null, null, FIELD_IME_FLAG_FORCE_ASCII); - // EditorInfo.IME_FLAG_FORCE_ASCII has been introduced since API#16 (JellyBean). + private EditorInfoCompatUtils() { + // This utility class is not publicly instantiable. + } + public static boolean hasFlagForceAscii(int imeOptions) { if (OBJ_IME_FLAG_FORCE_ASCII == null) return false; diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java index 7be95a095..ffed8202d 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -40,6 +40,10 @@ public class InputMethodManagerCompatWrapper { private InputMethodManager mImm; + private InputMethodManagerCompatWrapper() { + // This wrapper class is not publicly instantiable. + } + public static InputMethodManagerCompatWrapper getInstance() { if (sInstance.mImm == null) Log.w(TAG, "getInstance() is called before initialization"); diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java index df55aee94..5c351e41f 100644 --- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java +++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java @@ -77,6 +77,10 @@ public class SuggestionSpanUtils { } } + private SuggestionSpanUtils() { + // This utility class is not publicly instantiable. + } + public static CharSequence getTextWithAutoCorrectionIndicatorUnderline( Context context, CharSequence text) { if (TextUtils.isEmpty(text) || CONSTRUCTOR_SuggestionSpan == null diff --git a/java/src/com/android/inputmethod/compat/SuggestionsInfoCompatUtils.java b/java/src/com/android/inputmethod/compat/SuggestionsInfoCompatUtils.java index 723ec2862..e5f9db27c 100644 --- a/java/src/com/android/inputmethod/compat/SuggestionsInfoCompatUtils.java +++ b/java/src/com/android/inputmethod/compat/SuggestionsInfoCompatUtils.java @@ -30,6 +30,7 @@ public class SuggestionsInfoCompatUtils { ? OBJ_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS : 0; private SuggestionsInfoCompatUtils() { + // This utility class is not publicly instantiable. } /** -- cgit v1.2.3-83-g751a From 8abde7db6bacbd5726a87e924ec8aea7fbb10d9a Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Fri, 13 Apr 2012 13:07:28 +0900 Subject: Refatcor InputMethodSubtype related stuff a bit Change-Id: Iaded72331660afbaeddda085f2b633b681d4b6df --- .../compat/InputMethodManagerCompatWrapper.java | 11 +++-- .../inputmethod/keyboard/KeyboardLayoutSet.java | 36 ++-------------- .../android/inputmethod/latin/SubtypeLocale.java | 32 ++++++++++++++- .../android/inputmethod/latin/SubtypeSwitcher.java | 48 +++++++--------------- .../android/inputmethod/latin/SubtypeUtils.java | 12 +++--- .../inputmethod/latin/SubtypeLocaleTests.java | 8 ++-- 6 files changed, 66 insertions(+), 81 deletions(-) (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java index ffed8202d..04384523f 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -17,7 +17,6 @@ package com.android.inputmethod.compat; import android.content.Context; -import android.inputmethodservice.InputMethodService; import android.os.IBinder; import android.util.Log; import android.view.inputmethod.InputMethodInfo; @@ -50,9 +49,8 @@ public class InputMethodManagerCompatWrapper { return sInstance; } - public static void init(InputMethodService service) { - sInstance.mImm = (InputMethodManager) service.getSystemService( - Context.INPUT_METHOD_SERVICE); + public static void init(Context context) { + sInstance.mImm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE); } public InputMethodSubtype getCurrentInputMethodSubtype() { @@ -86,6 +84,11 @@ public class InputMethodManagerCompatWrapper { onlyCurrentIme); } + public List getInputMethodList() { + if (mImm == null) return null; + return mImm.getInputMethodList(); + } + public List getEnabledInputMethodList() { if (mImm == null) return null; return mImm.getEnabledInputMethodList(); diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java index 803a2948e..6d56c5cdc 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java @@ -32,7 +32,6 @@ import com.android.inputmethod.keyboard.KeyboardLayoutSet.Params.ElementParams; import com.android.inputmethod.latin.InputTypeUtils; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; -import com.android.inputmethod.latin.LocaleUtils; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StringUtils; import com.android.inputmethod.latin.SubtypeLocale; @@ -61,8 +60,6 @@ public class KeyboardLayoutSet { private static final String TAG_KEYBOARD_SET = "KeyboardLayoutSet"; private static final String TAG_ELEMENT = "Element"; - private static final String DEFAULT_KEYBOARD_LAYOUT_SET = "qwerty"; - private static final char KEYBOARD_LAYOUT_SET_LOCALE_DELIMITER = ':'; private static final String KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX = "keyboard_layout_set_"; private final Context mContext; @@ -164,14 +161,13 @@ public class KeyboardLayoutSet { } final KeyboardId id = getKeyboardId(keyboardLayoutSetElementId); try { - return getKeyboard(mContext, elementParams, id); + return getKeyboard(elementParams, id); } catch (RuntimeException e) { throw new KeyboardLayoutSetException(e, id); } } - private Keyboard getKeyboard(Context context, ElementParams elementParams, - final KeyboardId id) { + private Keyboard getKeyboard(ElementParams elementParams, final KeyboardId id) { final SoftReference ref = sKeyboardCache.get(id); Keyboard keyboard = (ref == null) ? null : ref.get(); if (keyboard == null) { @@ -215,30 +211,6 @@ public class KeyboardLayoutSet { voiceKeyEnabled, hasShortcutKey, params.mLanguageSwitchKeyEnabled); } - private static String getKeyboardLayoutSetName(InputMethodSubtype subtype) { - final String keyboardLayoutSet = subtype.getExtraValueOf( - LatinIME.SUBTYPE_EXTRA_VALUE_KEYBOARD_LAYOUT_SET); - // TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is - // fixed. - if (keyboardLayoutSet == null) return DEFAULT_KEYBOARD_LAYOUT_SET; - final int pos = keyboardLayoutSet.indexOf(KEYBOARD_LAYOUT_SET_LOCALE_DELIMITER); - return (pos > 0) ? keyboardLayoutSet.substring(0, pos) : keyboardLayoutSet; - } - - public static String getKeyboardLayoutSetLocaleString(InputMethodSubtype subtype) { - final String keyboardLayoutSet = subtype.getExtraValueOf( - LatinIME.SUBTYPE_EXTRA_VALUE_KEYBOARD_LAYOUT_SET); - // TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is - // fixed. - if (keyboardLayoutSet == null) return subtype.getLocale(); - final int pos = keyboardLayoutSet.indexOf(KEYBOARD_LAYOUT_SET_LOCALE_DELIMITER); - return (pos > 0) ? keyboardLayoutSet.substring(pos + 1) : subtype.getLocale(); - } - - public static Locale getKeyboardLayoutSetLocale(InputMethodSubtype subtype) { - return LocaleUtils.constructLocaleFromString(getKeyboardLayoutSetLocaleString(subtype)); - } - public static class Builder { private final Context mContext; private final String mPackageName; @@ -279,9 +251,9 @@ public class KeyboardLayoutSet { final InputMethodSubtype keyboardSubtype = (forceAscii && !asciiCapable) ? SubtypeSwitcher.getInstance().getNoLanguageSubtype() : subtype; - mParams.mLocale = getKeyboardLayoutSetLocale(keyboardSubtype); + mParams.mLocale = SubtypeLocale.getKeyboardLayoutSetLocale(keyboardSubtype); mParams.mKeyboardLayoutSetName = KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX - + getKeyboardLayoutSetName(keyboardSubtype); + + SubtypeLocale.getKeyboardLayoutSetName(keyboardSubtype); return this; } diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java index 2bc22a6f9..05f91688e 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java +++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java @@ -18,6 +18,8 @@ package com.android.inputmethod.latin; import android.content.Context; import android.content.res.Resources; +import android.view.inputmethod.InputMethodSubtype; + import java.util.Locale; @@ -33,6 +35,9 @@ public class SubtypeLocale { private static String[] sExceptionKeys; private static String[] sExceptionValues; + private static final String DEFAULT_KEYBOARD_LAYOUT_SET = "qwerty"; + private static final char KEYBOARD_LAYOUT_SET_LOCALE_DELIMITER = ':'; + private SubtypeLocale() { // Intentional empty constructor for utility class. } @@ -72,7 +77,8 @@ public class SubtypeLocale { return StringUtils.toTitleCase(locale.getDisplayName(locale), locale); } if (value.indexOf("%s") >= 0) { - final String languageName = StringUtils.toTitleCase(locale.getDisplayLanguage(locale), locale); + final String languageName = StringUtils.toTitleCase( + locale.getDisplayLanguage(locale), locale); return String.format(value, languageName); } return value; @@ -105,4 +111,28 @@ public class SubtypeLocale { return StringUtils.toTitleCase(locale.getLanguage(), locale); } } + + public static String getKeyboardLayoutSetName(InputMethodSubtype subtype) { + final String keyboardLayoutSet = subtype.getExtraValueOf( + LatinIME.SUBTYPE_EXTRA_VALUE_KEYBOARD_LAYOUT_SET); + // TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is + // fixed. + if (keyboardLayoutSet == null) return DEFAULT_KEYBOARD_LAYOUT_SET; + final int pos = keyboardLayoutSet.indexOf(KEYBOARD_LAYOUT_SET_LOCALE_DELIMITER); + return (pos > 0) ? keyboardLayoutSet.substring(0, pos) : keyboardLayoutSet; + } + + public static String getKeyboardLayoutSetLocaleString(InputMethodSubtype subtype) { + final String keyboardLayoutSet = subtype.getExtraValueOf( + LatinIME.SUBTYPE_EXTRA_VALUE_KEYBOARD_LAYOUT_SET); + // TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is + // fixed. + if (keyboardLayoutSet == null) return subtype.getLocale(); + final int pos = keyboardLayoutSet.indexOf(KEYBOARD_LAYOUT_SET_LOCALE_DELIMITER); + return (pos > 0) ? keyboardLayoutSet.substring(pos + 1) : subtype.getLocale(); + } + + public static Locale getKeyboardLayoutSetLocale(InputMethodSubtype subtype) { + return LocaleUtils.constructLocaleFromString(getKeyboardLayoutSetLocaleString(subtype)); + } } diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index 99f0ee184..2ba742303 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -31,7 +31,6 @@ import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; -import com.android.inputmethod.keyboard.KeyboardLayoutSet; import com.android.inputmethod.keyboard.KeyboardSwitcher; import java.util.ArrayList; @@ -105,8 +104,8 @@ public class SubtypeSwitcher { mInputLocaleStr = null; mCurrentSubtype = mImm.getCurrentInputMethodSubtype(); mAllEnabledSubtypesOfCurrentInputMethod = null; - mNoLanguageSubtype = SubtypeUtils.findSubtypeByKeyboardLayoutSetLocale( - service, SubtypeLocale.LOCALE_NO_LANGUAGE_QWERTY); + mNoLanguageSubtype = SubtypeUtils.findSubtypeByLocaleAndKeyboardLayoutSet( + service, SubtypeLocale.LOCALE_NO_LANGUAGE_QWERTY, "qwerty"); final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo(); mIsNetworkConnected = (info != null && info.isConnected()); @@ -129,14 +128,14 @@ public class SubtypeSwitcher { // Reload enabledSubtypes from the framework. private void updateEnabledSubtypes() { - final String currentMode = getCurrentSubtypeMode(); + final String currentMode = mCurrentSubtype.getMode(); boolean foundCurrentSubtypeBecameDisabled = true; mAllEnabledSubtypesOfCurrentInputMethod = mImm.getEnabledInputMethodSubtypeList( null, true); mEnabledLanguagesOfCurrentInputMethod.clear(); mEnabledKeyboardSubtypesOfCurrentInputMethod.clear(); for (InputMethodSubtype ims : mAllEnabledSubtypesOfCurrentInputMethod) { - final String locale = KeyboardLayoutSet.getKeyboardLayoutSetLocaleString(ims); + final String locale = SubtypeLocale.getKeyboardLayoutSetLocaleString(ims); final String mode = ims.getMode(); mLocaleSplitter.setString(locale); if (mLocaleSplitter.hasNext()) { @@ -166,7 +165,7 @@ public class SubtypeSwitcher { + (mShortcutInputMethodInfo == null ? "" : mShortcutInputMethodInfo.getId()) + ", " + (mShortcutSubtype == null ? "" : ( - KeyboardLayoutSet.getKeyboardLayoutSetLocaleString(mShortcutSubtype) + SubtypeLocale.getKeyboardLayoutSetLocaleString(mShortcutSubtype) + ", " + mShortcutSubtype.getMode()))); } // TODO: Update an icon for shortcut IME @@ -189,16 +188,16 @@ public class SubtypeSwitcher { + (mShortcutInputMethodInfo == null ? "" : mShortcutInputMethodInfo.getId()) + ", " + (mShortcutSubtype == null ? "" : ( - KeyboardLayoutSet.getKeyboardLayoutSetLocaleString(mShortcutSubtype) + SubtypeLocale.getKeyboardLayoutSetLocaleString(mShortcutSubtype) + ", " + mShortcutSubtype.getMode()))); } } // Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function. public void updateSubtype(InputMethodSubtype newSubtype) { - final String newLocale = KeyboardLayoutSet.getKeyboardLayoutSetLocaleString(newSubtype); + final String newLocale = SubtypeLocale.getKeyboardLayoutSetLocaleString(newSubtype); final String newMode = newSubtype.getMode(); - final String oldMode = getCurrentSubtypeMode(); + final String oldMode = mCurrentSubtype.getMode(); if (DBG) { Log.w(TAG, "Update subtype to:" + newLocale + "," + newMode + ", from: " + mInputLocaleStr + ", " + oldMode); @@ -218,7 +217,7 @@ public class SubtypeSwitcher { } mCurrentSubtype = newSubtype; - if (isKeyboardMode()) { + if (KEYBOARD_MODE.equals(mCurrentSubtype.getMode())) { if (modeChanged || languageChanged) { updateShortcutIME(); mService.onRefreshKeyboard(); @@ -233,12 +232,10 @@ public class SubtypeSwitcher { } Log.w(TAG, "Unknown subtype mode: " + newMode + "," + version + ", " + packageName + ". IME is already changed to other IME."); - if (newSubtype != null) { - Log.w(TAG, "Subtype mode:" + newSubtype.getMode()); - Log.w(TAG, "Subtype locale:" + newSubtype.getLocale()); - Log.w(TAG, "Subtype extra value:" + newSubtype.getExtraValue()); - Log.w(TAG, "Subtype is auxiliary:" + newSubtype.isAuxiliary()); - } + Log.w(TAG, "Subtype mode:" + newSubtype.getMode()); + Log.w(TAG, "Subtype locale:" + newSubtype.getLocale()); + Log.w(TAG, "Subtype extra value:" + newSubtype.getExtraValue()); + Log.w(TAG, "Subtype is auxiliary:" + newSubtype.isAuxiliary()); } } @@ -282,10 +279,11 @@ public class SubtypeSwitcher { if (token == null) { return; } + final InputMethodManagerCompatWrapper imm = mImm; new AsyncTask() { @Override protected Void doInBackground(Void... params) { - mImm.setInputMethodAndSubtype(token, imiId, subtype); + imm.setInputMethodAndSubtype(token, imiId, subtype); return null; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); @@ -385,22 +383,6 @@ public class SubtypeSwitcher { return mIsDictionaryAvailable; } - // TODO: Remove this method - private boolean isKeyboardMode() { - return KEYBOARD_MODE.equals(getCurrentSubtypeMode()); - } - - // TODO: Remove this method - private String getCurrentSubtypeMode() { - return mCurrentSubtype.getMode(); - } - - // TODO: Remove this method - public boolean currentSubtypeContainsExtraValueKey(String key) { - // If null, return what an empty ExtraValue would return : false. - return mCurrentSubtype.containsExtraValueKey(key); - } - public InputMethodSubtype getCurrentSubtype() { return mCurrentSubtype; } diff --git a/java/src/com/android/inputmethod/latin/SubtypeUtils.java b/java/src/com/android/inputmethod/latin/SubtypeUtils.java index a747c9ad7..4ad72fb9f 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeUtils.java +++ b/java/src/com/android/inputmethod/latin/SubtypeUtils.java @@ -21,7 +21,6 @@ import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; -import com.android.inputmethod.keyboard.KeyboardLayoutSet; import java.util.Collections; import java.util.List; @@ -125,21 +124,22 @@ public class SubtypeUtils { throw new RuntimeException("Input method manager not found"); } - for (final InputMethodInfo imi : imm.getEnabledInputMethodList()) { + for (final InputMethodInfo imi : imm.getInputMethodList()) { if (imi.getPackageName().equals(packageName)) return imi; } throw new RuntimeException("Can not find input method id for " + packageName); } - public static InputMethodSubtype findSubtypeByKeyboardLayoutSetLocale( - Context context, Locale locale) { + public static InputMethodSubtype findSubtypeByLocaleAndKeyboardLayoutSet( + Context context, Locale locale, String keyoardLayoutSet) { final String localeString = locale.toString(); - final InputMethodInfo imi = SubtypeUtils.getInputMethodInfo(context.getPackageName()); + final InputMethodInfo imi = getInputMethodInfo(context.getPackageName()); final int count = imi.getSubtypeCount(); for (int i = 0; i < count; i++) { final InputMethodSubtype subtype = imi.getSubtypeAt(i); - if (localeString.equals(KeyboardLayoutSet.getKeyboardLayoutSetLocaleString(subtype))) { + final String layout = SubtypeLocale.getKeyboardLayoutSetName(subtype); + if (localeString.equals(subtype.getLocale()) && keyoardLayoutSet.equals(layout)) { return subtype; } } diff --git a/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java b/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java index 4ac765782..911429ddf 100644 --- a/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java +++ b/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java @@ -22,8 +22,6 @@ import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; -import com.android.inputmethod.keyboard.KeyboardLayoutSet; - import java.util.ArrayList; import java.util.Locale; @@ -64,7 +62,7 @@ public class SubtypeLocaleTests extends AndroidTestCase { final StringBuilder messages = new StringBuilder(); int failedCount = 0; for (final InputMethodSubtype subtype : mSubtypesList) { - final Locale locale = KeyboardLayoutSet.getKeyboardLayoutSetLocale(subtype); + final Locale locale = SubtypeLocale.getKeyboardLayoutSetLocale(subtype); if (locale.getLanguage().equals(SubtypeLocale.NO_LANGUAGE)) { // This is special language name for language agnostic usage. continue; @@ -94,7 +92,7 @@ public class SubtypeLocaleTests extends AndroidTestCase { final StringBuilder messages = new StringBuilder(); int failedCount = 0; for (final InputMethodSubtype subtype : mSubtypesList) { - final Locale locale = KeyboardLayoutSet.getKeyboardLayoutSetLocale(subtype); + final Locale locale = SubtypeLocale.getKeyboardLayoutSetLocale(subtype); if (locale.getLanguage().equals(SubtypeLocale.NO_LANGUAGE)) { // This is special language name for language agnostic usage. continue; @@ -121,7 +119,7 @@ public class SubtypeLocaleTests extends AndroidTestCase { final StringBuilder messages = new StringBuilder(); int failedCount = 0; for (final InputMethodSubtype subtype : mSubtypesList) { - final Locale locale = KeyboardLayoutSet.getKeyboardLayoutSetLocale(subtype); + final Locale locale = SubtypeLocale.getKeyboardLayoutSetLocale(subtype); if (locale.getCountry().equals(SubtypeLocale.QWERTY)) { // This is special country code for QWERTY keyboard. continue; -- cgit v1.2.3-83-g751a From f6972561fcb45310f18230ce217f0c6bb57e7eee Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Wed, 11 Apr 2012 18:21:10 +0900 Subject: Utilize InputMethodSubtype and additional subtype * Remove de_QY and fr_CH from supported subtypes * Add de-qwerty and fr-qwertz predefined additional subtypes instead. Change-Id: I49e8ba0299529302f2b91b4d018b07304cdd6897 --- java/res/values/donottranslate.xml | 10 +- java/res/xml/method.xml | 18 +-- .../compat/InputMethodManagerCompatWrapper.java | 4 + .../com/android/inputmethod/keyboard/Keyboard.java | 2 +- .../android/inputmethod/keyboard/KeyboardId.java | 18 ++- .../inputmethod/keyboard/KeyboardLayoutSet.java | 11 +- .../inputmethod/keyboard/LatinKeyboardView.java | 18 +-- .../inputmethod/latin/AdditionalSubtype.java | 56 +++++++ .../com/android/inputmethod/latin/LatinIME.java | 4 + .../android/inputmethod/latin/SettingsValues.java | 18 +++ .../android/inputmethod/latin/SubtypeLocale.java | 145 ++++++++---------- .../android/inputmethod/latin/SubtypeSwitcher.java | 14 +- .../android/inputmethod/latin/SubtypeUtils.java | 3 +- .../inputmethod/latin/SubtypeLocaleTests.java | 167 ++++++++++++++------- 14 files changed, 296 insertions(+), 192 deletions(-) create mode 100644 java/src/com/android/inputmethod/latin/AdditionalSubtype.java (limited to 'java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java') diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml index bfe42327c..892c72aec 100644 --- a/java/res/values/donottranslate.xml +++ b/java/res/values/donottranslate.xml @@ -134,24 +134,24 @@ 5 - + en_US en_GB - *_QY - QY English (US) English (UK) - @string/subtype_generic_qwerty - QWERTY %s %s (QWERTY) + + %s (QWERTZ) + + %s (AZERTY) com.google.android.inputmethod.latin.dictionarypack diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml index ba4534351..ca0b24e19 100644 --- a/java/res/xml/method.xml +++ b/java/res/xml/method.xml @@ -28,7 +28,6 @@ cs: Czech/qwertz da: Danish/nordic de: German/qwertz - de_QY: German (QWERTY)/qwerty el: Greek/greek en_US: English United States/qwerty en_GB: English Great Britain/qwerty @@ -38,7 +37,6 @@ fi: Finnish/nordic fr: French/azerty fr_CA: French Canada/qwerty - fr_CH: French Switzerland/qwertz hi: Hindi/hindi hr: Croatian/qwertz hu: Hungarian/qwertz @@ -64,7 +62,7 @@ tr: Turkish/qwerty uk: Ukrainian/east_slavic vi: Vietnamese/qwerty - zz_QY: QWERTY/qwerty + zz: QWERTY/qwerty -->