diff options
Diffstat (limited to 'java/src')
18 files changed, 271 insertions, 176 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index 745e7dfed..7dfbea353 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -1460,7 +1460,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack return ""; } final Locale locale = SubtypeLocale.getSubtypeLocale(subtype); - return StringUtils.toTitleCase(locale.getLanguage(), locale); + return StringUtils.capitalizeFirstCodePoint(locale.getLanguage(), locale); } // Get InputMethodSubtype's middle display name in its locale. diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java index 66c30149c..f81ab8dd6 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java @@ -73,10 +73,11 @@ public final class MoreKeysKeyboard extends Keyboard { final int rowHeight, final int coordXInParent, final int parentKeyboardWidth, final boolean isFixedColumnOrder, final int dividerWidth) { mIsFixedOrder = isFixedColumnOrder; - if (parentKeyboardWidth / keyWidth < maxColumns) { + if (parentKeyboardWidth / keyWidth < Math.min(numKeys, maxColumns)) { throw new IllegalArgumentException( "Keyboard is too small to hold more keys keyboard: " - + parentKeyboardWidth + " " + keyWidth + " " + maxColumns); + + parentKeyboardWidth + " " + keyWidth + " " + + numKeys + " " + maxColumns); } mDefaultKeyWidth = keyWidth; mDefaultRowHeight = rowHeight; diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java index 809ed6839..b77e378bf 100644 --- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java @@ -88,8 +88,9 @@ public class ProximityInfo { this("", 1, 1, 1, 1, 1, 1, EMPTY_KEY_ARRAY, null); mNativeProximityInfo = setProximityInfoNative("" /* locale */, gridWidth /* displayWidth */, gridHeight /* displayHeight */, - gridWidth, gridHeight, 1 /* mostCommonKeyWidth */, proximityCharsArray, - 0 /* keyCount */, null /*keyXCoordinates */, null /* keyYCoordinates */, + gridWidth, gridHeight, 1 /* mostCommonKeyWidth */, + 1 /* mostCommonKeyHeight */, proximityCharsArray, 0 /* keyCount */, + null /*keyXCoordinates */, null /* keyYCoordinates */, null /* keyWidths */, null /* keyHeights */, null /* keyCharCodes */, null /* sweetSpotCenterXs */, null /* sweetSpotCenterYs */, null /* sweetSpotRadii */); @@ -103,9 +104,10 @@ public class ProximityInfo { // TODO: Stop passing proximityCharsArray private static native long setProximityInfoNative(String locale, int displayWidth, int displayHeight, int gridWidth, int gridHeight, - int mostCommonKeyWidth, int[] proximityCharsArray, int keyCount, int[] keyXCoordinates, - int[] keyYCoordinates, int[] keyWidths, int[] keyHeights, int[] keyCharCodes, - float[] sweetSpotCenterXs, float[] sweetSpotCenterYs, float[] sweetSpotRadii); + int mostCommonKeyWidth, int mostCommonKeyHeight, int[] proximityCharsArray, + int keyCount, int[] keyXCoordinates, int[] keyYCoordinates, int[] keyWidths, + int[] keyHeights, int[] keyCharCodes, float[] sweetSpotCenterXs, + float[] sweetSpotCenterYs, float[] sweetSpotRadii); private static native void releaseProximityInfoNative(long nativeProximityInfo); @@ -232,9 +234,9 @@ public class ProximityInfo { // TODO: Stop passing proximityCharsArray return setProximityInfoNative(mLocaleStr, mKeyboardMinWidth, mKeyboardHeight, - mGridWidth, mGridHeight, mMostCommonKeyWidth, proximityCharsArray, keyCount, - keyXCoordinates, keyYCoordinates, keyWidths, keyHeights, keyCharCodes, - sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii); + mGridWidth, mGridHeight, mMostCommonKeyWidth, mMostCommonKeyHeight, + proximityCharsArray, keyCount, keyXCoordinates, keyYCoordinates, keyWidths, + keyHeights, keyCharCodes, sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii); } public long getNativeProximityInfo() { diff --git a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java index e3e6d39e4..f682b518f 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java +++ b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java @@ -37,6 +37,7 @@ import com.android.inputmethod.latin.ResizableIntArray; final class GesturePreviewTrail { private static final int DEFAULT_CAPACITY = GestureStrokeWithPreviewPoints.PREVIEW_CAPACITY; + // These three {@link ResizableIntArray}s should be synchronized by {@link #mEventTimes}. private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY); private final ResizableIntArray mYCoordinates = new ResizableIntArray(DEFAULT_CAPACITY); private final ResizableIntArray mEventTimes = new ResizableIntArray(DEFAULT_CAPACITY); @@ -90,7 +91,13 @@ final class GesturePreviewTrail { } public void addStroke(final GestureStrokeWithPreviewPoints stroke, final long downTime) { - final int trailSize = mEventTimes.getLength(); + synchronized (mEventTimes) { + addStrokeLocked(stroke, downTime); + } + } + + private void addStrokeLocked(final GestureStrokeWithPreviewPoints stroke, final long downTime) { + final int trailSize = mEventTimes.getLength(); stroke.appendPreviewStroke(mEventTimes, mXCoordinates, mYCoordinates); if (mEventTimes.getLength() == trailSize) { return; @@ -169,6 +176,13 @@ final class GesturePreviewTrail { */ public boolean drawGestureTrail(final Canvas canvas, final Paint paint, final Rect outBoundsRect, final Params params) { + synchronized (mEventTimes) { + return drawGestureTrailLocked(canvas, paint, outBoundsRect, params); + } + } + + private boolean drawGestureTrailLocked(final Canvas canvas, final Paint paint, + final Rect outBoundsRect, final Params params) { // Initialize bounds rectangle. outBoundsRect.setEmpty(); final int trailSize = mEventTimes.getLength(); diff --git a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java index 2df7e5cf5..6bc6acc0f 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java +++ b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java @@ -34,175 +34,197 @@ public final class PointerTrackerQueue { } private static final int INITIAL_CAPACITY = 10; + // Note: {@link #mExpandableArrayOfActivePointers} and {@link #mArraySize} are synchronized by + // {@link #mExpandableArrayOfActivePointers} private final ArrayList<Element> mExpandableArrayOfActivePointers = CollectionUtils.newArrayList(INITIAL_CAPACITY); private int mArraySize = 0; - public synchronized int size() { - return mArraySize; + public int size() { + synchronized (mExpandableArrayOfActivePointers) { + return mArraySize; + } } - public synchronized void add(final Element pointer) { - final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; - final int arraySize = mArraySize; - if (arraySize < expandableArray.size()) { - expandableArray.set(arraySize, pointer); - } else { - expandableArray.add(pointer); + public void add(final Element pointer) { + synchronized (mExpandableArrayOfActivePointers) { + final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; + final int arraySize = mArraySize; + if (arraySize < expandableArray.size()) { + expandableArray.set(arraySize, pointer); + } else { + expandableArray.add(pointer); + } + mArraySize = arraySize + 1; } - mArraySize = arraySize + 1; } - public synchronized void remove(final Element pointer) { - final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; - final int arraySize = mArraySize; - int newSize = 0; - for (int index = 0; index < arraySize; index++) { - final Element element = expandableArray.get(index); - if (element == pointer) { + public void remove(final Element pointer) { + synchronized (mExpandableArrayOfActivePointers) { + final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; + final int arraySize = mArraySize; + int newSize = 0; + for (int index = 0; index < arraySize; index++) { + final Element element = expandableArray.get(index); + if (element == pointer) { + if (newSize != index) { + Log.w(TAG, "Found duplicated element in remove: " + pointer); + } + continue; // Remove this element from the expandableArray. + } if (newSize != index) { - Log.w(TAG, "Found duplicated element in remove: " + pointer); + // Shift this element toward the beginning of the expandableArray. + expandableArray.set(newSize, element); } - continue; // Remove this element from the expandableArray. - } - if (newSize != index) { - // Shift this element toward the beginning of the expandableArray. - expandableArray.set(newSize, element); + newSize++; } - newSize++; + mArraySize = newSize; } - mArraySize = newSize; } - public synchronized Element getOldestElement() { - return (mArraySize == 0) ? null : mExpandableArrayOfActivePointers.get(0); + public Element getOldestElement() { + synchronized (mExpandableArrayOfActivePointers) { + return (mArraySize == 0) ? null : mExpandableArrayOfActivePointers.get(0); + } } - public synchronized void releaseAllPointersOlderThan(final Element pointer, - final long eventTime) { - if (DEBUG) { - Log.d(TAG, "releaseAllPoniterOlderThan: " + pointer + " " + this); - } - final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; - final int arraySize = mArraySize; - int newSize, index; - for (newSize = index = 0; index < arraySize; index++) { - final Element element = expandableArray.get(index); - if (element == pointer) { - break; // Stop releasing elements. - } - if (!element.isModifier()) { - element.onPhantomUpEvent(eventTime); - continue; // Remove this element from the expandableArray. + public void releaseAllPointersOlderThan(final Element pointer, final long eventTime) { + synchronized (mExpandableArrayOfActivePointers) { + if (DEBUG) { + Log.d(TAG, "releaseAllPoniterOlderThan: " + pointer + " " + this); } - if (newSize != index) { - // Shift this element toward the beginning of the expandableArray. - expandableArray.set(newSize, element); - } - newSize++; - } - // Shift rest of the expandableArray. - int count = 0; - for (; index < arraySize; index++) { - final Element element = expandableArray.get(index); - if (element == pointer) { - if (count > 0) { - Log.w(TAG, "Found duplicated element in releaseAllPointersOlderThan: " - + pointer); + final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; + final int arraySize = mArraySize; + int newSize, index; + for (newSize = index = 0; index < arraySize; index++) { + final Element element = expandableArray.get(index); + if (element == pointer) { + break; // Stop releasing elements. + } + if (!element.isModifier()) { + element.onPhantomUpEvent(eventTime); + continue; // Remove this element from the expandableArray. + } + if (newSize != index) { + // Shift this element toward the beginning of the expandableArray. + expandableArray.set(newSize, element); } - count++; - } - if (newSize != index) { - expandableArray.set(newSize, expandableArray.get(index)); newSize++; } + // Shift rest of the expandableArray. + int count = 0; + for (; index < arraySize; index++) { + final Element element = expandableArray.get(index); + if (element == pointer) { + if (count > 0) { + Log.w(TAG, "Found duplicated element in releaseAllPointersOlderThan: " + + pointer); + } + count++; + } + if (newSize != index) { + expandableArray.set(newSize, expandableArray.get(index)); + newSize++; + } + } + mArraySize = newSize; } - mArraySize = newSize; } public void releaseAllPointers(final long eventTime) { releaseAllPointersExcept(null, eventTime); } - public synchronized void releaseAllPointersExcept(final Element pointer, - final long eventTime) { - if (DEBUG) { - if (pointer == null) { - Log.d(TAG, "releaseAllPoniters: " + this); - } else { - Log.d(TAG, "releaseAllPoniterExcept: " + pointer + " " + this); - } - } - final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; - final int arraySize = mArraySize; - int newSize = 0, count = 0; - for (int index = 0; index < arraySize; index++) { - final Element element = expandableArray.get(index); - if (element == pointer) { - if (count > 0) { - Log.w(TAG, "Found duplicated element in releaseAllPointersExcept: " + pointer); + public void releaseAllPointersExcept(final Element pointer, final long eventTime) { + synchronized (mExpandableArrayOfActivePointers) { + if (DEBUG) { + if (pointer == null) { + Log.d(TAG, "releaseAllPoniters: " + this); + } else { + Log.d(TAG, "releaseAllPoniterExcept: " + pointer + " " + this); } - count++; - } else { - element.onPhantomUpEvent(eventTime); - continue; // Remove this element from the expandableArray. } - if (newSize != index) { - // Shift this element toward the beginning of the expandableArray. - expandableArray.set(newSize, element); + final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; + final int arraySize = mArraySize; + int newSize = 0, count = 0; + for (int index = 0; index < arraySize; index++) { + final Element element = expandableArray.get(index); + if (element == pointer) { + if (count > 0) { + Log.w(TAG, "Found duplicated element in releaseAllPointersExcept: " + + pointer); + } + count++; + } else { + element.onPhantomUpEvent(eventTime); + continue; // Remove this element from the expandableArray. + } + if (newSize != index) { + // Shift this element toward the beginning of the expandableArray. + expandableArray.set(newSize, element); + } + newSize++; } - newSize++; + mArraySize = newSize; } - mArraySize = newSize; } - public synchronized boolean hasModifierKeyOlderThan(final Element pointer) { - final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; - final int arraySize = mArraySize; - for (int index = 0; index < arraySize; index++) { - final Element element = expandableArray.get(index); - if (element == pointer) { - return false; // Stop searching modifier key. - } - if (element.isModifier()) { - return true; + public boolean hasModifierKeyOlderThan(final Element pointer) { + synchronized (mExpandableArrayOfActivePointers) { + final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; + final int arraySize = mArraySize; + for (int index = 0; index < arraySize; index++) { + final Element element = expandableArray.get(index); + if (element == pointer) { + return false; // Stop searching modifier key. + } + if (element.isModifier()) { + return true; + } } + return false; } - return false; } - public synchronized boolean isAnyInSlidingKeyInput() { - final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; - final int arraySize = mArraySize; - for (int index = 0; index < arraySize; index++) { - final Element element = expandableArray.get(index); - if (element.isInSlidingKeyInput()) { - return true; + public boolean isAnyInSlidingKeyInput() { + synchronized (mExpandableArrayOfActivePointers) { + final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; + final int arraySize = mArraySize; + for (int index = 0; index < arraySize; index++) { + final Element element = expandableArray.get(index); + if (element.isInSlidingKeyInput()) { + return true; + } } + return false; } - return false; } - public synchronized void cancelAllPointerTracker() { - final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; - final int arraySize = mArraySize; - for (int index = 0; index < arraySize; index++) { - final Element element = expandableArray.get(index); - element.cancelTracking(); + public void cancelAllPointerTracker() { + synchronized (mExpandableArrayOfActivePointers) { + final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; + final int arraySize = mArraySize; + for (int index = 0; index < arraySize; index++) { + final Element element = expandableArray.get(index); + element.cancelTracking(); + } } } @Override - public synchronized String toString() { - final StringBuilder sb = new StringBuilder(); - final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; - final int arraySize = mArraySize; - for (int index = 0; index < arraySize; index++) { - final Element element = expandableArray.get(index); - if (sb.length() > 0) - sb.append(" "); - sb.append(element.toString()); + public String toString() { + synchronized (mExpandableArrayOfActivePointers) { + final StringBuilder sb = new StringBuilder(); + final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; + final int arraySize = mArraySize; + for (int index = 0; index < arraySize; index++) { + final Element element = expandableArray.get(index); + if (sb.length() > 0) { + sb.append(" "); + } + sb.append(element.toString()); + } + return "[" + sb.toString() + "]"; } - return "[" + sb.toString() + "]"; } } diff --git a/java/src/com/android/inputmethod/latin/CapsModeUtils.java b/java/src/com/android/inputmethod/latin/CapsModeUtils.java index 1012cd519..4b8d1ac11 100644 --- a/java/src/com/android/inputmethod/latin/CapsModeUtils.java +++ b/java/src/com/android/inputmethod/latin/CapsModeUtils.java @@ -41,7 +41,7 @@ public final class CapsModeUtils { if (WordComposer.CAPS_MODE_AUTO_SHIFT_LOCKED == capitalizeMode) { return s.toUpperCase(locale); } else if (WordComposer.CAPS_MODE_AUTO_SHIFTED == capitalizeMode) { - return StringUtils.toTitleCase(s, locale); + return StringUtils.capitalizeFirstCodePoint(s, locale); } else { return s; } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 56b1c786e..0f1f14957 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1540,7 +1540,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction } } else { final int codePointBeforeCursor = mConnection.getCodePointBeforeCursor(); - if (mSettings.getCurrent().isUsuallyFollowedBySpace(codePointBeforeCursor)) { + if (Character.isLetter(codePointBeforeCursor) + || mSettings.getCurrent().isUsuallyFollowedBySpace(codePointBeforeCursor)) { mSpaceState = SPACE_STATE_PHANTOM; } } @@ -1551,7 +1552,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction private static final class BatchInputUpdater implements Handler.Callback { private final Handler mHandler; private LatinIME mLatinIme; - private boolean mInBatchInput; // synchronized using "this". + private final Object mLock = new Object(); + private boolean mInBatchInput; // synchronized using {@link #mLock}. private BatchInputUpdater() { final HandlerThread handlerThread = new HandlerThread( @@ -1582,21 +1584,25 @@ public final class LatinIME extends InputMethodService implements KeyboardAction } // Run in the UI thread. - public synchronized void onStartBatchInput(final LatinIME latinIme) { - mHandler.removeMessages(MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP); - mLatinIme = latinIme; - mInBatchInput = true; + public void onStartBatchInput(final LatinIME latinIme) { + synchronized (mLock) { + mHandler.removeMessages(MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP); + mLatinIme = latinIme; + mInBatchInput = true; + } } // Run in the Handler thread. - private synchronized void updateBatchInput(final InputPointers batchPointers) { - if (!mInBatchInput) { - // Batch input has ended or canceled while the message was being delivered. - return; + private void updateBatchInput(final InputPointers batchPointers) { + synchronized (mLock) { + if (!mInBatchInput) { + // Batch input has ended or canceled while the message was being delivered. + return; + } + final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(batchPointers); + mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip( + suggestedWords, false /* dismissGestureFloatingPreviewText */); } - final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(batchPointers); - mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip( - suggestedWords, false /* dismissGestureFloatingPreviewText */); } // Run in the UI thread. @@ -1609,19 +1615,23 @@ public final class LatinIME extends InputMethodService implements KeyboardAction .sendToTarget(); } - public synchronized void onCancelBatchInput() { - mInBatchInput = false; - mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip( - SuggestedWords.EMPTY, true /* dismissGestureFloatingPreviewText */); + public void onCancelBatchInput() { + synchronized (mLock) { + mInBatchInput = false; + mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip( + SuggestedWords.EMPTY, true /* dismissGestureFloatingPreviewText */); + } } // Run in the UI thread. - public synchronized SuggestedWords onEndBatchInput(final InputPointers batchPointers) { - mInBatchInput = false; - final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(batchPointers); - mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip( - suggestedWords, true /* dismissGestureFloatingPreviewText */); - return suggestedWords; + public SuggestedWords onEndBatchInput(final InputPointers batchPointers) { + synchronized (mLock) { + mInBatchInput = false; + final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(batchPointers); + mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip( + suggestedWords, true /* dismissGestureFloatingPreviewText */); + return suggestedWords; + } } // {@link LatinIME#getSuggestedWords(int)} method calls with same session id have to diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index ce659bf45..8fbe843cf 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -272,6 +272,11 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static boolean readShowSetupWizardIcon(final SharedPreferences prefs, final Context context) { + final boolean enableSetupWizardByConfig = context.getResources().getBoolean( + R.bool.config_setup_wizard_available); + if (!enableSetupWizardByConfig) { + return false; + } if (!prefs.contains(Settings.PREF_SHOW_SETUP_WIZARD_ICON)) { final ApplicationInfo appInfo = context.getApplicationInfo(); final boolean isApplicationInSystemImage = diff --git a/java/src/com/android/inputmethod/latin/SettingsActivity.java b/java/src/com/android/inputmethod/latin/SettingsActivity.java index 99b572e06..37ac2e35c 100644 --- a/java/src/com/android/inputmethod/latin/SettingsActivity.java +++ b/java/src/com/android/inputmethod/latin/SettingsActivity.java @@ -25,7 +25,10 @@ public final class SettingsActivity extends PreferenceActivity { @Override public Intent getIntent() { final Intent intent = super.getIntent(); - intent.putExtra(EXTRA_SHOW_FRAGMENT, DEFAULT_FRAGMENT); + final String fragment = intent.getStringExtra(EXTRA_SHOW_FRAGMENT); + if (fragment == null) { + intent.putExtra(EXTRA_SHOW_FRAGMENT, DEFAULT_FRAGMENT); + } intent.putExtra(EXTRA_NO_HEADERS, true); return intent; } diff --git a/java/src/com/android/inputmethod/latin/SettingsFragment.java b/java/src/com/android/inputmethod/latin/SettingsFragment.java index 928141c32..5405a5eb7 100644 --- a/java/src/com/android/inputmethod/latin/SettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/SettingsFragment.java @@ -165,6 +165,10 @@ public final class SettingsFragment extends InputMethodSettingsFragment Settings.readKeyPreviewPopupEnabled(prefs, res)); } + if (!res.getBoolean(R.bool.config_setup_wizard_available)) { + removePreference(Settings.PREF_SHOW_SETUP_WIZARD_ICON, advancedSettings); + } + setPreferenceEnabled(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, Settings.readShowsLanguageSwitchKey(prefs)); @@ -203,7 +207,9 @@ public final class SettingsFragment extends InputMethodSettingsFragment final SharedPreferences prefs = getPreferenceManager().getSharedPreferences(); final CheckBoxPreference showSetupWizardIcon = (CheckBoxPreference)findPreference(Settings.PREF_SHOW_SETUP_WIZARD_ICON); - showSetupWizardIcon.setChecked(Settings.readShowSetupWizardIcon(prefs, getActivity())); + if (showSetupWizardIcon != null) { + showSetupWizardIcon.setChecked(Settings.readShowSetupWizardIcon(prefs, getActivity())); + } updateShowCorrectionSuggestionsSummary(); updateKeyPreviewPopupDelaySummary(); updateCustomInputStylesSummary(); diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/StringUtils.java index 59ad28fc9..11ef60dc9 100644 --- a/java/src/com/android/inputmethod/latin/StringUtils.java +++ b/java/src/com/android/inputmethod/latin/StringUtils.java @@ -106,10 +106,19 @@ public final class StringUtils { } } - public static String toTitleCase(final String s, final Locale locale) { + public static String capitalizeFirstCodePoint(final String s, final Locale locale) { if (s.length() <= 1) { - // TODO: is this really correct? Shouldn't this be s.toUpperCase()? - return s; + return s.toUpperCase(locale); + } + // Please refer to the comment below in + // {@link #capitalizeFirstAndDowncaseRest(String,Locale)} as this has the same shortcomings + final int cutoff = s.offsetByCodePoints(0, 1); + return s.substring(0, cutoff).toUpperCase(locale) + s.substring(cutoff); + } + + public static String capitalizeFirstAndDowncaseRest(final String s, final Locale locale) { + if (s.length() <= 1) { + return s.toUpperCase(locale); } // TODO: fix the bugs below // - This does not work for Greek, because it returns upper case instead of title case. diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java index 5e28cc2d0..4d88ecc0c 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java +++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java @@ -183,7 +183,7 @@ public final class SubtypeLocale { final Locale locale = LocaleUtils.constructLocaleFromString(localeString); displayName = locale.getDisplayName(displayLocale); } - return StringUtils.toTitleCase(displayName, displayLocale); + return StringUtils.capitalizeFirstCodePoint(displayName, displayLocale); } // InputMethodSubtype's display name in its locale. @@ -243,7 +243,7 @@ public final class SubtypeLocale { } } }; - return StringUtils.toTitleCase( + return StringUtils.capitalizeFirstCodePoint( getSubtypeName.runInLocale(sResources, displayLocale), displayLocale); } diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 975664dca..6464bd0d7 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -394,7 +394,7 @@ public final class Suggest { if (isAllUpperCase) { sb.append(wordInfo.mWord.toUpperCase(locale)); } else if (isFirstCharCapitalized) { - sb.append(StringUtils.toTitleCase(wordInfo.mWord, locale)); + sb.append(StringUtils.capitalizeFirstCodePoint(wordInfo.mWord, locale)); } else { sb.append(wordInfo.mWord); } diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java index e7c7e2b8a..17d281518 100644 --- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java +++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java @@ -647,7 +647,7 @@ public final class FusionDictionary implements Iterable<Word> { if (index < codePoints.length) return null; if (!currentGroup.isTerminal()) return null; - if (DBG && !codePoints.equals(checker.toString())) return null; + if (DBG && !string.equals(checker.toString())) return null; return currentGroup; } @@ -853,16 +853,19 @@ public final class FusionDictionary implements Iterable<Word> { if (currentPos.pos.hasNext()) { final CharGroup currentGroup = currentPos.pos.next(); currentPos.length = mCurrentString.length(); - for (int i : currentGroup.mChars) + for (int i : currentGroup.mChars) { mCurrentString.append(Character.toChars(i)); + } if (null != currentGroup.mChildren) { currentPos = new Position(currentGroup.mChildren.mData); + currentPos.length = mCurrentString.length(); mPositions.addLast(currentPos); } - if (currentGroup.mFrequency >= 0) + if (currentGroup.mFrequency >= 0) { return new Word(mCurrentString.toString(), currentGroup.mFrequency, currentGroup.mShortcutTargets, currentGroup.mBigrams, currentGroup.mIsNotAWord, currentGroup.mIsBlacklistEntry); + } } else { mPositions.removeLast(); currentPos = mPositions.getLast(); diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index fbed139f3..2d0a89bb3 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -330,7 +330,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService } else if (StringUtils.CAPITALIZE_FIRST == capitalizeType) { for (int i = 0; i < mSuggestions.size(); ++i) { // Likewise - mSuggestions.set(i, StringUtils.toTitleCase( + mSuggestions.set(i, StringUtils.capitalizeFirstCodePoint( mSuggestions.get(i).toString(), locale)); } } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java index b15063235..96b2c818d 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java @@ -226,7 +226,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { // If the lower case version is not in the dictionary, it's still possible // that we have an all-caps version of a word that needs to be capitalized // according to the dictionary. E.g. "GERMANS" only exists in the dictionary as "Germans". - return dict.isValidWord(StringUtils.toTitleCase(lowerCaseText, mLocale)); + return dict.isValidWord(StringUtils.capitalizeFirstAndDowncaseRest(lowerCaseText, mLocale)); } // Note : this must be reentrant diff --git a/java/src/com/android/inputmethod/research/MotionEventReader.java b/java/src/com/android/inputmethod/research/MotionEventReader.java index e1cc2da73..fbfd9b531 100644 --- a/java/src/com/android/inputmethod/research/MotionEventReader.java +++ b/java/src/com/android/inputmethod/research/MotionEventReader.java @@ -22,6 +22,7 @@ import android.view.MotionEvent; import android.view.MotionEvent.PointerCoords; import android.view.MotionEvent.PointerProperties; +import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.define.ProductionFlag; import java.io.BufferedReader; @@ -64,6 +65,7 @@ public class MotionEventReader { return replayData; } + @UsedForTesting static class ReplayData { final ArrayList<Integer> mActions = new ArrayList<Integer>(); final ArrayList<PointerProperties[]> mPointerPropertiesArrays @@ -134,6 +136,7 @@ public class MotionEventReader { * }, * </pre> */ + @UsedForTesting /* package for test */ void readLogStatement(final JsonReader jsonReader, final ReplayData replayData) throws IOException { String logStatementType = null; diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java index e0bd37c1e..5aaced036 100644 --- a/java/src/com/android/inputmethod/research/ResearchLogger.java +++ b/java/src/com/android/inputmethod/research/ResearchLogger.java @@ -81,6 +81,7 @@ import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.regex.Pattern; /** * Logs the use of the LatinIME keyboard. @@ -1065,7 +1066,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang new LogStatement("LatinImeOnStartInputViewInternal", false, false, "uuid", "packageName", "inputType", "imeOptions", "fieldId", "display", "model", "prefs", "versionCode", "versionName", "outputFormatVersion", "logEverything", - "isUsingDevelopmentOnlyDiagnosticsDebug"); + "isDevTeamBuild"); public static void latinIME_onStartInputViewInternal(final EditorInfo editorInfo, final SharedPreferences prefs) { final ResearchLogger researchLogger = getInstance(); @@ -1087,13 +1088,29 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang Integer.toHexString(editorInfo.imeOptions), editorInfo.fieldId, Build.DISPLAY, Build.MODEL, prefs, versionCode, versionName, OUTPUT_FORMAT_VERSION, IS_LOGGING_EVERYTHING, - ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG); - } catch (NameNotFoundException e) { - e.printStackTrace(); + researchLogger.isDevTeamBuild()); + } catch (final NameNotFoundException e) { + Log.e(TAG, "NameNotFound", e); } } } + // TODO: Update this heuristic pattern to something more reliable. Developer builds tend to + // have the developer name and year embedded. + private static final Pattern developerBuildRegex = Pattern.compile("[A-Za-z]\\.20[1-9]"); + private boolean isDevTeamBuild() { + try { + final PackageInfo packageInfo; + packageInfo = mLatinIME.getPackageManager().getPackageInfo(mLatinIME.getPackageName(), + 0); + final String versionName = packageInfo.versionName; + return !(developerBuildRegex.matcher(versionName).find()); + } catch (final NameNotFoundException e) { + Log.e(TAG, "Could not determine package name", e); + return false; + } + } + /** * Log a change in preferences. * |