diff options
Diffstat (limited to 'java/src')
11 files changed, 107 insertions, 65 deletions
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryPackConstants.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryPackConstants.java index 69615887f..df0e3f0e1 100644 --- a/java/src/com/android/inputmethod/dictionarypack/DictionaryPackConstants.java +++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryPackConstants.java @@ -28,13 +28,13 @@ public class DictionaryPackConstants { * The root domain for the dictionary pack, upon which authorities and actions will append * their own distinctive strings. */ - private static final String DICTIONARY_DOMAIN = "com.android.inputmethod.dictionarypack"; + private static final String DICTIONARY_DOMAIN = "com.android.inputmethod.dictionarypack.aosp"; /** * Authority for the ContentProvider protocol. */ // TODO: find some way to factorize this string with the one in the resources - public static final String AUTHORITY = DICTIONARY_DOMAIN + ".aosp"; + public static final String AUTHORITY = DICTIONARY_DOMAIN; /** * The action of the intent for publishing that new dictionary data is available. @@ -52,7 +52,14 @@ public class DictionaryPackConstants { */ public static final String UNKNOWN_DICTIONARY_PROVIDER_CLIENT = DICTIONARY_DOMAIN + ".UNKNOWN_CLIENT"; + // In the above intents, the name of the string extra that contains the name of the client // we want information about. public static final String DICTIONARY_PROVIDER_CLIENT_EXTRA = "client"; + + /** + * The action of the intent to tell the dictionary provider to update now. + */ + public static final String UPDATE_NOW_INTENT_ACTION = DICTIONARY_DOMAIN + + ".UPDATE_NOW"; } diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java index 46bb5543a..6e3dd7109 100644 --- a/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java +++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java @@ -54,12 +54,7 @@ public final class DictionaryService extends Service { /** * The package name, to use in the intent actions. */ - private static final String PACKAGE_NAME = "com.android.android.inputmethod.latin"; - - /** - * The action of the intent to tell the dictionary provider to update now. - */ - private static final String UPDATE_NOW_INTENT_ACTION = PACKAGE_NAME + ".UPDATE_NOW"; + private static final String PACKAGE_NAME = "com.android.inputmethod.latin"; /** * The action of the date changing, used to schedule a periodic freshness check @@ -173,7 +168,7 @@ public final class DictionaryService extends Service { // at midnight local time, but it may happen if the user changes the date // by hand or something similar happens. checkTimeAndMaybeSetupUpdateAlarm(context); - } else if (UPDATE_NOW_INTENT_ACTION.equals(intent.getAction())) { + } else if (DictionaryPackConstants.UPDATE_NOW_INTENT_ACTION.equals(intent.getAction())) { // Intent to trigger an update now. UpdateHandler.update(context, false); } else { @@ -196,7 +191,7 @@ public final class DictionaryService extends Service { // It doesn't matter too much if this is very inexact. final long now = System.currentTimeMillis(); final long alarmTime = now + new Random().nextInt(MAX_ALARM_DELAY); - final Intent updateIntent = new Intent(DictionaryService.UPDATE_NOW_INTENT_ACTION); + final Intent updateIntent = new Intent(DictionaryPackConstants.UPDATE_NOW_INTENT_ACTION); final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, updateIntent, PendingIntent.FLAG_CANCEL_CURRENT); diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureTrail.java b/java/src/com/android/inputmethod/keyboard/internal/GestureTrail.java index 0f3cd7887..fb69e22e7 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/GestureTrail.java +++ b/java/src/com/android/inputmethod/keyboard/internal/GestureTrail.java @@ -245,7 +245,7 @@ final class GestureTrail { final float body1 = r1 * params.mTrailBodyRatio; final float body2 = r2 * params.mTrailBodyRatio; final Path path = roundedLine.makePath(p1x, p1y, body1, p2x, p2y, body2); - if (path != null) { + if (!path.isEmpty()) { roundedLine.getBounds(mRoundedLineBounds); if (params.mTrailShadowEnabled) { final float shadow2 = r2 * params.mTrailShadowRatio; diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java index 15eb690e1..84319eb33 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java @@ -84,11 +84,16 @@ public class KeyboardParams { public void onAddKey(final Key newKey) { final Key key = (mKeysCache != null) ? mKeysCache.get(newKey) : newKey; - final boolean zeroWidthSpacer = key.isSpacer() && key.mWidth == 0; - if (!zeroWidthSpacer) { - mKeys.add(key); - updateHistogram(key); + final boolean isSpacer = key.isSpacer(); + if (isSpacer && key.mWidth == 0) { + // Ignore zero width {@link Spacer}. + return; } + mKeys.add(key); + if (isSpacer) { + return; + } + updateHistogram(key); if (key.mCode == Constants.CODE_SHIFT) { mShiftKeys.add(key); } diff --git a/java/src/com/android/inputmethod/keyboard/internal/RoundedLine.java b/java/src/com/android/inputmethod/keyboard/internal/RoundedLine.java index 2eefd6ae9..211ef5f8b 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/RoundedLine.java +++ b/java/src/com/android/inputmethod/keyboard/internal/RoundedLine.java @@ -37,16 +37,18 @@ public final class RoundedLine { * @param p2x the x-coordinate of the end point. * @param p2y the y-coordinate of the end point. * @param r2 the radius at the end point - * @return the path of rounded line + * @return an instance of {@link Path} that holds the result rounded line, or an instance of + * {@link Path} that holds an empty path if the start and end points are equal. */ public Path makePath(final float p1x, final float p1y, final float r1, final float p2x, final float p2y, final float r2) { + mPath.rewind(); final double dx = p2x - p1x; final double dy = p2y - p1y; // Distance of the points. final double l = Math.hypot(dx, dy); if (Double.compare(0.0d, l) == 0) { - return null; + return mPath; // Return an empty path } // Angle of the line p1-p2 final double a = Math.atan2(dy, dx); @@ -86,7 +88,6 @@ public final class RoundedLine { mArc2.set(p2x, p2y, p2x, p2y); mArc2.inset(-r2, -r2); - mPath.rewind(); // Trail cap at P1. mPath.moveTo(p1x, p1y); mPath.arcTo(mArc1, angle, a1); diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java index 98eadcacb..272f36e4f 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java @@ -290,16 +290,12 @@ final class BinaryDictionaryGetter { final Context context) { final boolean hasDefaultWordList = DictionaryFactory.isDictionaryAvailable(context, locale); - // TODO: The development-only-diagnostic version is not supported by the Dictionary Pack - // Service yet - if (!ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { - // We need internet access to do the following. Only do this if the package actually - // has the permission. - if (context.checkCallingOrSelfPermission(android.Manifest.permission.INTERNET) - == PackageManager.PERMISSION_GRANTED) { - BinaryDictionaryFileDumper.cacheWordListsFromContentProvider(locale, context, - hasDefaultWordList); - } + // We need internet access to do the following. Only do this if the package actually + // has the permission. + if (context.checkCallingOrSelfPermission(android.Manifest.permission.INTERNET) + == PackageManager.PERMISSION_GRANTED) { + BinaryDictionaryFileDumper.cacheWordListsFromContentProvider(locale, context, + hasDefaultWordList); } final File[] cachedWordLists = getCachedWordLists(locale.toString(), context); final String mainDictId = DictionaryInfoUtils.getMainDictId(locale); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 0bf167fd4..6a3066cc1 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -179,11 +179,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private int mDisplayOrientation; // Object for reacting to adding/removing a dictionary pack. - // TODO: The development-only-diagnostic version is not supported by the Dictionary Pack - // Service yet. private BroadcastReceiver mDictionaryPackInstallReceiver = - ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS - ? null : new DictionaryPackInstallBroadcastReceiver(this); + new DictionaryPackInstallBroadcastReceiver(this); // Keeps track of most recently inserted text (multi-character key) for reverting private String mEnteredText; @@ -458,19 +455,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); registerReceiver(mReceiver, filter); - // TODO: The development-only-diagnostic version is not supported by the Dictionary Pack - // Service yet. - if (!ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { - final IntentFilter packageFilter = new IntentFilter(); - packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED); - packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); - packageFilter.addDataScheme(SCHEME_PACKAGE); - registerReceiver(mDictionaryPackInstallReceiver, packageFilter); + final IntentFilter packageFilter = new IntentFilter(); + packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED); + packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); + packageFilter.addDataScheme(SCHEME_PACKAGE); + registerReceiver(mDictionaryPackInstallReceiver, packageFilter); - final IntentFilter newDictFilter = new IntentFilter(); - newDictFilter.addAction(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION); - registerReceiver(mDictionaryPackInstallReceiver, newDictFilter); - } + final IntentFilter newDictFilter = new IntentFilter(); + newDictFilter.addAction(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION); + registerReceiver(mDictionaryPackInstallReceiver, newDictFilter); } // Has to be package-visible for unit tests @@ -587,11 +580,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { ResearchLogger.getInstance().onDestroy(); } - // TODO: The development-only-diagnostic version is not supported by the Dictionary Pack - // Service yet. - if (!ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { - unregisterReceiver(mDictionaryPackInstallReceiver); - } + unregisterReceiver(mDictionaryPackInstallReceiver); LatinImeLogger.commit(); LatinImeLogger.onDestroy(); super.onDestroy(); @@ -855,8 +844,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } // Remove pending messages related to update suggestions mHandler.cancelUpdateSuggestionStrip(); + // Should do the following in onFinishInputInternal but until JB MR2 it's not called :( if (mWordComposer.isComposingWord()) mConnection.finishComposingText(); resetComposingState(true /* alsoResetLastComposedWord */); + mRichImm.clearSubtypeCaches(); // Notify ResearchLogger if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { ResearchLogger.latinIME_onFinishInputViewInternal(finishingInput, mLastSelectionStart, diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java index 94513e635..86f75635d 100644 --- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java +++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java @@ -30,6 +30,7 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import java.util.Collections; +import java.util.HashMap; import java.util.List; /** @@ -46,6 +47,10 @@ public final class RichInputMethodManager { private InputMethodManagerCompatWrapper mImmWrapper; private InputMethodInfo mInputMethodInfoOfThisIme; + final HashMap<InputMethodInfo, List<InputMethodSubtype>> + mSubtypeListCacheWithImplicitlySelectedSubtypes = CollectionUtils.newHashMap(); + final HashMap<InputMethodInfo, List<InputMethodSubtype>> + mSubtypeListCacheWithoutImplicitlySelectedSubtypes = CollectionUtils.newHashMap(); private static final int INDEX_NOT_FOUND = -1; @@ -102,8 +107,8 @@ public final class RichInputMethodManager { public List<InputMethodSubtype> getMyEnabledInputMethodSubtypeList( boolean allowsImplicitlySelectedSubtypes) { - return mImmWrapper.mImm.getEnabledInputMethodSubtypeList( - mInputMethodInfoOfThisIme, allowsImplicitlySelectedSubtypes); + return getEnabledInputMethodSubtypeList(mInputMethodInfoOfThisIme, + allowsImplicitlySelectedSubtypes); } public boolean switchToNextInputMethod(final IBinder token, final boolean onlyCurrentIme) { @@ -151,8 +156,8 @@ public final class RichInputMethodManager { return false; } final InputMethodInfo nextImi = getNextNonAuxiliaryIme(currentIndex, enabledImis); - final List<InputMethodSubtype> enabledSubtypes = imm.getEnabledInputMethodSubtypeList( - nextImi, true /* allowsImplicitlySelectedSubtypes */); + final List<InputMethodSubtype> enabledSubtypes = getEnabledInputMethodSubtypeList(nextImi, + true /* allowsImplicitlySelectedSubtypes */); if (enabledSubtypes.isEmpty()) { // The next IME has no subtype. imm.setInputMethod(token, nextImi.getId()); @@ -227,9 +232,8 @@ public final class RichInputMethodManager { public boolean checkIfSubtypeBelongsToImeAndEnabled(final InputMethodInfo imi, final InputMethodSubtype subtype) { - return checkIfSubtypeBelongsToList( - subtype, mImmWrapper.mImm.getEnabledInputMethodSubtypeList( - imi, true /* allowsImplicitlySelectedSubtypes */)); + return checkIfSubtypeBelongsToList(subtype, getEnabledInputMethodSubtypeList(imi, + true /* allowsImplicitlySelectedSubtypes */)); } private static boolean checkIfSubtypeBelongsToList(final InputMethodSubtype subtype, @@ -290,8 +294,7 @@ public final class RichInputMethodManager { for (InputMethodInfo imi : imiList) { // We can return true immediately after we find two or more filtered IMEs. if (filteredImisCount > 1) return true; - final List<InputMethodSubtype> subtypes = - mImmWrapper.mImm.getEnabledInputMethodSubtypeList(imi, true); + final List<InputMethodSubtype> subtypes = getEnabledInputMethodSubtypeList(imi, true); // IMEs that have no subtypes should be counted. if (subtypes.isEmpty()) { ++filteredImisCount; @@ -354,5 +357,26 @@ public final class RichInputMethodManager { public void setAdditionalInputMethodSubtypes(final InputMethodSubtype[] subtypes) { mImmWrapper.mImm.setAdditionalInputMethodSubtypes( mInputMethodInfoOfThisIme.getId(), subtypes); + // Clear the cache so that we go read the subtypes again next time. + clearSubtypeCaches(); + } + + private List<InputMethodSubtype> getEnabledInputMethodSubtypeList(final InputMethodInfo imi, + final boolean allowsImplicitlySelectedSubtypes) { + final HashMap<InputMethodInfo, List<InputMethodSubtype>> cache = + allowsImplicitlySelectedSubtypes + ? mSubtypeListCacheWithImplicitlySelectedSubtypes + : mSubtypeListCacheWithoutImplicitlySelectedSubtypes; + final List<InputMethodSubtype> cachedList = cache.get(imi); + if (null != cachedList) return cachedList; + final List<InputMethodSubtype> result = mImmWrapper.mImm.getEnabledInputMethodSubtypeList( + imi, allowsImplicitlySelectedSubtypes); + cache.put(imi, result); + return result; + } + + public void clearSubtypeCaches() { + mSubtypeListCacheWithImplicitlySelectedSubtypes.clear(); + mSubtypeListCacheWithoutImplicitlySelectedSubtypes.clear(); } } diff --git a/java/src/com/android/inputmethod/latin/SettingsFragment.java b/java/src/com/android/inputmethod/latin/SettingsFragment.java index 8365cce3a..1fad765d7 100644 --- a/java/src/com/android/inputmethod/latin/SettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/SettingsFragment.java @@ -42,6 +42,7 @@ import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.setup.LauncherIconVisibilityManager; import com.android.inputmethod.latin.userdictionary.UserDictionaryList; import com.android.inputmethod.latin.userdictionary.UserDictionarySettings; +import com.android.inputmethod.research.ResearchLogger; import com.android.inputmethodcommon.InputMethodSettingsFragment; public final class SettingsFragment extends InputMethodSettingsFragment @@ -130,7 +131,12 @@ public final class SettingsFragment extends InputMethodSettingsFragment feedbackSettings.setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(final Preference pref) { - FeedbackUtils.showFeedbackForm(getActivity()); + if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { + // Use development-only feedback mechanism + ResearchLogger.getInstance().presentFeedbackDialogFromSettings(); + } else { + FeedbackUtils.showFeedbackForm(getActivity()); + } return true; } }); @@ -141,6 +147,10 @@ public final class SettingsFragment extends InputMethodSettingsFragment miscSettings.removePreference(aboutSettings); } } + if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { + // The about screen contains items that may be confusing in development-only versions. + miscSettings.removePreference(aboutSettings); + } final boolean showVoiceKeyOption = res.getBoolean( R.bool.config_enable_show_voice_key_option); @@ -192,9 +202,7 @@ public final class SettingsFragment extends InputMethodSettingsFragment final Intent intent = dictionaryLink.getIntent(); intent.setClassName(context.getPackageName(), DictionarySettingsActivity.class.getName()); final int number = context.getPackageManager().queryIntentActivities(intent, 0).size(); - // TODO: The development-only-diagnostic version is not supported by the Dictionary Pack - // Service yet - if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS || 0 >= number) { + if (0 >= number) { textCorrectionGroup.removePreference(dictionaryLink); } diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java index 2b6fda381..89ec7466e 100644 --- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java +++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java @@ -76,7 +76,9 @@ public class UserDictionaryAddWordContents { final String word = args.getString(EXTRA_WORD); if (null != word) { mWordEditText.setText(word); - mWordEditText.setSelection(word.length()); + // Use getText in case the edit text modified the text we set. This happens when + // it's too long to be edited. + mWordEditText.setSelection(mWordEditText.getText().length()); } final String shortcut; if (UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) { diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java index aa4a866b8..e890b74aa 100644 --- a/java/src/com/android/inputmethod/research/ResearchLogger.java +++ b/java/src/com/android/inputmethod/research/ResearchLogger.java @@ -429,6 +429,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang mMainResearchLog.blockingClose(RESEARCHLOG_CLOSE_TIMEOUT_IN_MS); resetLogBuffers(); + cancelFeedbackDialog(); } public void abort() { @@ -465,6 +466,12 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang presentFeedbackDialog(latinIME); } + public void presentFeedbackDialogFromSettings() { + if (mLatinIME != null) { + presentFeedbackDialog(mLatinIME); + } + } + public void presentFeedbackDialog(final LatinIME latinIME) { if (isMakingUserRecording()) { saveRecording(); @@ -701,13 +708,19 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang mInFeedbackDialog = false; } + private void cancelFeedbackDialog() { + if (isMakingUserRecording()) { + cancelRecording(); + } + mInFeedbackDialog = false; + } + public void initSuggest(final Suggest suggest) { mSuggest = suggest; // MainLogBuffer now has an out-of-date Suggest object. Close down MainLogBuffer and create // a new one. if (mMainLogBuffer != null) { - stop(); - start(); + restart(); } } |