diff options
Diffstat (limited to 'java/src')
16 files changed, 153 insertions, 77 deletions
diff --git a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java index c937eeeaa..5af31795c 100644 --- a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java @@ -84,8 +84,8 @@ public final class CursorAnchorInfoCompatWrapper { } @UsedForTesting - public static boolean isAvailable() { - return sCursorAnchorInfoClass.exists(); + public boolean isAvailable() { + return sCursorAnchorInfoClass.exists() && mInstance != null; } private Object mInstance; @@ -96,7 +96,7 @@ public final class CursorAnchorInfoCompatWrapper { @UsedForTesting public static CursorAnchorInfoCompatWrapper fromObject(final Object instance) { - if (!isAvailable()) { + if (!sCursorAnchorInfoClass.exists()) { return new CursorAnchorInfoCompatWrapper(null); } return new CursorAnchorInfoCompatWrapper(instance); diff --git a/java/src/com/android/inputmethod/dictionarypack/DownloadManagerWrapper.java b/java/src/com/android/inputmethod/dictionarypack/DownloadManagerWrapper.java index 75cc7d4cb..3dbbc9b9b 100644 --- a/java/src/com/android/inputmethod/dictionarypack/DownloadManagerWrapper.java +++ b/java/src/com/android/inputmethod/dictionarypack/DownloadManagerWrapper.java @@ -54,15 +54,13 @@ public class DownloadManagerWrapper { if (null != mDownloadManager) { mDownloadManager.remove(ids); } + } catch (IllegalArgumentException e) { + // This is expected to happen on boot when the device is encrypted. } catch (SQLiteException e) { // We couldn't remove the file from DownloadManager. Apparently, the database can't // be opened. It may be a problem with file system corruption. In any case, there is // not much we can do apart from avoiding crashing. Log.e(TAG, "Can't remove files with ID " + ids + " from download manager", e); - } catch (IllegalArgumentException e) { - // Not sure how this can happen, but it could be another case where the provider - // is disabled. Or it could be a bug in older versions of the framework. - Log.e(TAG, "Can't find the content URL for DownloadManager?", e); } } @@ -71,10 +69,10 @@ public class DownloadManagerWrapper { if (null != mDownloadManager) { return mDownloadManager.openDownloadedFile(fileId); } + } catch (IllegalArgumentException e) { + // This is expected to happen on boot when the device is encrypted. } catch (SQLiteException e) { Log.e(TAG, "Can't open downloaded file with ID " + fileId, e); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Can't find the content URL for DownloadManager?", e); } // We come here if mDownloadManager is null or if an exception was thrown. throw new FileNotFoundException(); @@ -85,10 +83,10 @@ public class DownloadManagerWrapper { if (null != mDownloadManager) { return mDownloadManager.query(query); } + } catch (IllegalArgumentException e) { + // This is expected to happen on boot when the device is encrypted. } catch (SQLiteException e) { Log.e(TAG, "Can't query the download manager", e); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Can't find the content URL for DownloadManager?", e); } // We come here if mDownloadManager is null or if an exception was thrown. return null; @@ -99,10 +97,10 @@ public class DownloadManagerWrapper { if (null != mDownloadManager) { return mDownloadManager.enqueue(request); } + } catch (IllegalArgumentException e) { + // This is expected to happen on boot when the device is encrypted. } catch (SQLiteException e) { Log.e(TAG, "Can't enqueue a request with the download manager", e); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Can't find the content URL for DownloadManager?", e); } return 0; } diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index 6d0b2c2f1..2b16785c2 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -756,7 +756,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack public void onHideWindow() { onDismissMoreKeysPanel(); final MainKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; - if (accessibilityDelegate != null) { + if (accessibilityDelegate != null + && AccessibilityUtils.getInstance().isAccessibilityEnabled()) { accessibilityDelegate.onHideWindow(); } } @@ -767,7 +768,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack @Override public boolean onHoverEvent(final MotionEvent event) { final MainKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; - if (accessibilityDelegate != null) { + if (accessibilityDelegate != null + && AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { return accessibilityDelegate.onHoverEvent(event); } return super.onHoverEvent(event); diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java index a9d1239ed..841283b7f 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java @@ -105,7 +105,7 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel super.setKeyboard(keyboard); mKeyDetector.setKeyboard( keyboard, -getPaddingLeft(), -getPaddingTop() + getVerticalCorrection()); - if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { + if (AccessibilityUtils.getInstance().isAccessibilityEnabled()) { if (mAccessibilityDelegate == null) { mAccessibilityDelegate = new MoreKeysKeyboardAccessibilityDelegate( this, mKeyDetector); @@ -142,7 +142,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel mOriginY = y + container.getPaddingTop(); controller.onShowMoreKeysPanel(this); final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; - if (accessibilityDelegate != null) { + if (accessibilityDelegate != null + && AccessibilityUtils.getInstance().isAccessibilityEnabled()) { accessibilityDelegate.onShowMoreKeysKeyboard(); } } @@ -239,7 +240,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel return; } final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; - if (accessibilityDelegate != null) { + if (accessibilityDelegate != null + && AccessibilityUtils.getInstance().isAccessibilityEnabled()) { accessibilityDelegate.onDismissMoreKeysKeyboard(); } mController.onDismissMoreKeysPanel(); @@ -285,7 +287,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel @Override public boolean onHoverEvent(final MotionEvent event) { final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; - if (accessibilityDelegate != null) { + if (accessibilityDelegate != null + && AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { return accessibilityDelegate.onHoverEvent(event); } return super.onHoverEvent(event); diff --git a/java/src/com/android/inputmethod/keyboard/TextDecorator.java b/java/src/com/android/inputmethod/keyboard/TextDecorator.java index 315d36313..c22717f95 100644 --- a/java/src/com/android/inputmethod/keyboard/TextDecorator.java +++ b/java/src/com/android/inputmethod/keyboard/TextDecorator.java @@ -49,7 +49,7 @@ public class TextDecorator { private int mMode = MODE_MONITOR; private String mLastComposingText = null; - private RectF mIndicatorBoundsForLastComposingText = new RectF(); + private boolean mHasRtlCharsInLastComposingText = false; private RectF mComposingTextBoundsForLastComposingText = new RectF(); private boolean mIsFullScreenMode = false; @@ -182,7 +182,7 @@ public class TextDecorator { private void layoutMain() { final CursorAnchorInfoCompatWrapper info = mCursorAnchorInfoWrapper; - if (info == null) { + if (info == null || !info.isAvailable()) { cancelLayoutInternalExpectedly("CursorAnchorInfo isn't available."); return; } @@ -241,20 +241,8 @@ public class TextDecorator { right = Math.max(characterBounds.right, right); } mLastComposingText = composingTextString; + mHasRtlCharsInLastComposingText = useRtlLayout; mComposingTextBoundsForLastComposingText.set(left, top, right, bottom); - // The height and width of the indicator is the same as the height of the composing - // text. - final float indicatorSize = bottom - top; - mIndicatorBoundsForLastComposingText.set(0.0f, 0.0f, indicatorSize, indicatorSize); - // The horizontal position of the indicator depends on the text direction. - final float indicatorTop = top; - final float indicatorLeft; - if (useRtlLayout) { - indicatorLeft = left - indicatorSize; - } else { - indicatorLeft = right; - } - mIndicatorBoundsForLastComposingText.offset(indicatorLeft, indicatorTop); } final int selectionStart = info.getSelectionStart(); @@ -295,8 +283,8 @@ public class TextDecorator { return; } - mUiOperator.layoutUi(matrix, mIndicatorBoundsForLastComposingText, - mComposingTextBoundsForLastComposingText); + mUiOperator.layoutUi(matrix, mComposingTextBoundsForLastComposingText, + mHasRtlCharsInLastComposingText); } private void onClickIndicator() { @@ -374,7 +362,7 @@ public class TextDecorator { public void setOnClickListener(Runnable listener) { } @Override - public void layoutUi(Matrix matrix, RectF indicatorBounds, RectF composingTextBounds) { + public void layoutUi(Matrix matrix, RectF composingTextBounds, boolean useRtlLayout) { } }; } diff --git a/java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java b/java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java index b67d17789..d87dc1bfa 100644 --- a/java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java +++ b/java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java @@ -26,6 +26,7 @@ import android.graphics.Path; import android.graphics.RectF; import android.graphics.drawable.ColorDrawable; import android.inputmethodservice.InputMethodService; +import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.Gravity; import android.view.View; @@ -50,6 +51,7 @@ public final class TextDecoratorUi implements TextDecoratorUiOperator { private final PopupWindow mTouchEventWindow; private final View mTouchEventWindowClickListenerView; private final float mHitAreaMarginInPixels; + private final RectF mDisplayRect; /** * This constructor is designed to be called from {@link InputMethodService#setInputView(View)}. @@ -64,6 +66,9 @@ public final class TextDecoratorUi implements TextDecoratorUiOperator { R.integer.text_decorator_hit_area_margin_in_dp); mHitAreaMarginInPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, hitAreaMarginInDP, resources.getDisplayMetrics()); + final DisplayMetrics displayMetrics = resources.getDisplayMetrics(); + mDisplayRect = new RectF(0.0f, 0.0f, displayMetrics.widthPixels, + displayMetrics.heightPixels); mLocalRootView = new RelativeLayout(context); mLocalRootView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, @@ -111,17 +116,40 @@ public final class TextDecoratorUi implements TextDecoratorUiOperator { mTouchEventWindow.dismiss(); } + private static final RectF getIndicatorBoundsInScreenCoordinates(final Matrix matrix, + final RectF composingTextBounds, final boolean showAtLeftSide) { + final float indicatorSize = composingTextBounds.height(); + final RectF indicatorBounds; + if (showAtLeftSide) { + indicatorBounds = new RectF(composingTextBounds.left - indicatorSize, + composingTextBounds.top, composingTextBounds.left, + composingTextBounds.top + indicatorSize); + } else { + indicatorBounds = new RectF(composingTextBounds.right, composingTextBounds.top, + composingTextBounds.right + indicatorSize, + composingTextBounds.top + indicatorSize); + } + matrix.mapRect(indicatorBounds); + return indicatorBounds; + } + @Override - public void layoutUi(final Matrix matrix, final RectF indicatorBounds, - final RectF composingTextBounds) { - final RectF indicatorBoundsInScreenCoordinates = new RectF(); - matrix.mapRect(indicatorBoundsInScreenCoordinates, indicatorBounds); + public void layoutUi(final Matrix matrix, final RectF composingTextBounds, + final boolean useRtlLayout) { + RectF indicatorBoundsInScreenCoordinates = getIndicatorBoundsInScreenCoordinates(matrix, + composingTextBounds, useRtlLayout /* showAtLeftSide */); + if (indicatorBoundsInScreenCoordinates.left < mDisplayRect.left || + mDisplayRect.right < indicatorBoundsInScreenCoordinates.right) { + // The indicator is clipped by the screen. Show the indicator at the opposite side. + indicatorBoundsInScreenCoordinates = getIndicatorBoundsInScreenCoordinates(matrix, + composingTextBounds, !useRtlLayout /* showAtLeftSide */); + } + mAddToDictionaryIndicatorView.setBounds(indicatorBoundsInScreenCoordinates); - final RectF hitAreaBounds = new RectF(composingTextBounds); - hitAreaBounds.union(indicatorBounds); final RectF hitAreaBoundsInScreenCoordinates = new RectF(); - matrix.mapRect(hitAreaBoundsInScreenCoordinates, hitAreaBounds); + matrix.mapRect(hitAreaBoundsInScreenCoordinates, composingTextBounds); + hitAreaBoundsInScreenCoordinates.union(indicatorBoundsInScreenCoordinates); hitAreaBoundsInScreenCoordinates.inset(-mHitAreaMarginInPixels, -mHitAreaMarginInPixels); final int[] originScreen = new int[2]; diff --git a/java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java b/java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java index 9c0b64ad4..9e30e417e 100644 --- a/java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java +++ b/java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java @@ -17,7 +17,6 @@ package com.android.inputmethod.keyboard; import android.graphics.Matrix; -import android.graphics.PointF; import android.graphics.RectF; /** @@ -45,9 +44,8 @@ public interface TextDecoratorUiOperator { /** * Called when the layout should be updated. * @param matrix The matrix that transforms the local coordinates into the screen coordinates. - * @param indicatorBounds The bounding box of the indicator, in local coordinates. * @param composingTextBounds The bounding box of the composing text, in local coordinates. + * @param useRtlLayout {@code true} if the indicator should be optimized for RTL layout. */ - void layoutUi(final Matrix matrix, final RectF indicatorBounds, - final RectF composingTextBounds); + void layoutUi(final Matrix matrix, final RectF composingTextBounds, final boolean useRtlLayout); } diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java index 17dfc9cce..925ec6bfb 100644 --- a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java @@ -104,7 +104,8 @@ final class EmojiPageKeyboardView extends KeyboardView implements public boolean onHoverEvent(final MotionEvent event) { final KeyboardAccessibilityDelegate<EmojiPageKeyboardView> accessibilityDelegate = mAccessibilityDelegate; - if (accessibilityDelegate != null) { + if (accessibilityDelegate != null + && AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { return accessibilityDelegate.onHoverEvent(event); } return super.onHoverEvent(event); diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java index 36a02669d..fd1f51dd6 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java @@ -491,8 +491,9 @@ public class DictionaryFacilitator { final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId) { final Dictionaries dictionaries = mDictionaries; - final SuggestionResults suggestionResults = - new SuggestionResults(dictionaries.mLocale, SuggestedWords.MAX_SUGGESTIONS); + final SuggestionResults suggestionResults = new SuggestionResults( + dictionaries.mLocale, SuggestedWords.MAX_SUGGESTIONS, + prevWordsInfo.mPrevWordsInfo[0].mIsBeginningOfSentence); final float[] languageWeight = new float[] { Dictionary.NOT_A_LANGUAGE_WEIGHT }; for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) { final Dictionary dictionary = dictionaries.getDict(dictType); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 81953221e..d57db8e9a 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1033,7 +1033,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // with cursor movement when we have a hardware keyboard since we are not in charge. final SettingsValues settingsValues = mSettings.getCurrent(); if ((!settingsValues.mHasHardwareKeyboard || ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) - && mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd)) { + && mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, + settingsValues)) { mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(), getCurrentRecapitalizeState()); } @@ -1488,19 +1489,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final boolean isEmptyApplicationSpecifiedCompletions = currentSettingsValues.isApplicationSpecifiedCompletionsOn() && suggestedWords.isEmpty(); - final boolean noSuggestionsToShow = (SuggestedWords.EMPTY == suggestedWords) + final boolean noSuggestionsFromDictionaries = (SuggestedWords.EMPTY == suggestedWords) || suggestedWords.isPunctuationSuggestions() || isEmptyApplicationSpecifiedCompletions; - if (shouldShowImportantNotice && noSuggestionsToShow) { + final boolean isBeginningOfSentencePrediction = (suggestedWords.mInputStyle + == SuggestedWords.INPUT_STYLE_BEGINNING_OF_SENTENCE_PREDICTION); + final boolean noSuggestionsToOverrideImportantNotice = noSuggestionsFromDictionaries + || isBeginningOfSentencePrediction; + if (shouldShowImportantNotice && noSuggestionsToOverrideImportantNotice) { if (mSuggestionStripView.maybeShowImportantNoticeTitle()) { return; } } if (currentSettingsValues.isSuggestionsEnabledPerUserSettings() - // We should clear suggestions if there is no suggestion to show. - || noSuggestionsToShow - || currentSettingsValues.isApplicationSpecifiedCompletionsOn()) { + || currentSettingsValues.isApplicationSpecifiedCompletionsOn() + // We should clear the contextual strip if there is no suggestion from dictionaries. + || noSuggestionsFromDictionaries) { mSuggestionStripView.setSuggestions(suggestedWords, SubtypeLocaleUtils.isRtlLanguage(mSubtypeSwitcher.getCurrentSubtype())); } diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 6779351fd..b03818c1d 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -186,8 +186,14 @@ public final class Suggest { suggestionsList = suggestionsContainer; } - final int inputStyle = resultsArePredictions ? SuggestedWords.INPUT_STYLE_PREDICTION : - inputStyleIfNotPrediction; + final int inputStyle; + if (resultsArePredictions) { + inputStyle = suggestionResults.mIsBeginningOfSentence + ? SuggestedWords.INPUT_STYLE_BEGINNING_OF_SENTENCE_PREDICTION + : SuggestedWords.INPUT_STYLE_PREDICTION; + } else { + inputStyle = inputStyleIfNotPrediction; + } callback.onGetSuggestedWords(new SuggestedWords(suggestionsList, suggestionResults.mRawSuggestions, // TODO: this first argument is lying. If this is a whitelisted word which is an @@ -240,6 +246,8 @@ public final class Suggest { // In the batch input mode, the most relevant suggested word should act as a "typed word" // (typedWordValid=true), not as an "auto correct word" (willAutoCorrect=false). + // Note that because this method is never used to get predictions, there is no need to + // modify inputType such in getSuggestedWordsForNonBatchInput. callback.onGetSuggestedWords(new SuggestedWords(suggestionsContainer, suggestionResults.mRawSuggestions, true /* typedWordValid */, diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index 6bc3da885..1d221b77f 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -39,6 +39,7 @@ public class SuggestedWords { public static final int INPUT_STYLE_APPLICATION_SPECIFIED = 4; public static final int INPUT_STYLE_RECORRECTION = 5; public static final int INPUT_STYLE_PREDICTION = 6; + public static final int INPUT_STYLE_BEGINNING_OF_SENTENCE_PREDICTION = 7; // The maximum number of suggestions available. public static final int MAX_SUGGESTIONS = 18; @@ -80,10 +81,9 @@ public class SuggestedWords { final int inputStyle, final int sequenceNumber) { this(suggestedWordInfoList, rawSuggestions, - (suggestedWordInfoList.isEmpty() || INPUT_STYLE_PREDICTION == inputStyle) ? null + (suggestedWordInfoList.isEmpty() || isPrediction(inputStyle)) ? null : suggestedWordInfoList.get(INDEX_OF_TYPED_WORD).mWord, - typedWordValid, willAutoCorrect, isObsoleteSuggestions, inputStyle, - sequenceNumber); + typedWordValid, willAutoCorrect, isObsoleteSuggestions, inputStyle, sequenceNumber); } public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList, @@ -171,6 +171,7 @@ public class SuggestedWords { return "SuggestedWords:" + " mTypedWordValid=" + mTypedWordValid + " mWillAutoCorrect=" + mWillAutoCorrect + + " mInputStyle=" + mInputStyle + " words=" + Arrays.toString(mSuggestedWordInfoList.toArray()); } @@ -377,8 +378,13 @@ public class SuggestedWords { } } + private static boolean isPrediction(final int inputStyle) { + return INPUT_STYLE_PREDICTION == inputStyle + || INPUT_STYLE_BEGINNING_OF_SENTENCE_PREDICTION == inputStyle; + } + public boolean isPrediction() { - return INPUT_STYLE_PREDICTION == mInputStyle; + return isPrediction(mInputStyle); } // SuggestedWords is an immutable object, as much as possible. We must not just remove diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index 21e2a1c10..fdab7f25f 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -358,10 +358,11 @@ public final class InputLogic { * @param oldSelEnd old selection end * @param newSelStart new selection start * @param newSelEnd new selection end + * @param settingsValues the current values of the settings. * @return whether the cursor has moved as a result of user interaction. */ public boolean onUpdateSelection(final int oldSelStart, final int oldSelEnd, - final int newSelStart, final int newSelEnd) { + final int newSelStart, final int newSelEnd, final SettingsValues settingsValues) { if (mConnection.isBelatedExpectedUpdate(oldSelStart, newSelStart, oldSelEnd, newSelEnd)) { return false; } @@ -386,8 +387,9 @@ public final class InputLogic { // should be true, but that is if the framework had taken that wrong cursor position // into account, which means we have to reset the entire composing state whenever there // is or was a selection regardless of whether it changed or not. - if (hasOrHadSelection || (selectionChangedOrSafeToReset - && !mWordComposer.moveCursorByAndReturnIfInsideComposingWord(moveAmount))) { + if (hasOrHadSelection || !settingsValues.needsToLookupSuggestions() + || (selectionChangedOrSafeToReset + && !mWordComposer.moveCursorByAndReturnIfInsideComposingWord(moveAmount))) { // If we are composing a word and moving the cursor, we would want to set a // suggestion span for recorrection to work correctly. Unfortunately, that // would involve the keyboard committing some new text, which would move the diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java index 33745a846..0fd5e139e 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java @@ -408,8 +408,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick // Decided to be in the sliding suggestion mode only when the touch point has been moved // upward. Further {@link MotionEvent}s will be delivered to // {@link #onTouchEvent(MotionEvent)}. - mNeedsToTransformTouchEventToHoverEvent = AccessibilityUtils.getInstance() - .isTouchExplorationEnabled(); + mNeedsToTransformTouchEventToHoverEvent = + AccessibilityUtils.getInstance().isTouchExplorationEnabled(); mIsDispatchingHoverEventToMoreSuggestions = false; return true; } diff --git a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java index 8b7077879..ea406fa75 100644 --- a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java @@ -23,15 +23,24 @@ import android.provider.Settings.SettingNotFoundException; import android.text.TextUtils; import android.util.Log; +import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.R; +import java.util.concurrent.TimeUnit; + public final class ImportantNoticeUtils { private static final String TAG = ImportantNoticeUtils.class.getSimpleName(); // {@link SharedPreferences} name to save the last important notice version that has been // displayed to users. private static final String PREFERENCE_NAME = "important_notice_pref"; - private static final String KEY_IMPORTANT_NOTICE_VERSION = "important_notice_version"; + @UsedForTesting + static final String KEY_IMPORTANT_NOTICE_VERSION = "important_notice_version"; + @UsedForTesting + static final String KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE = + "timestamp_of_first_important_notice"; + @UsedForTesting + static final long TIMEOUT_OF_IMPORTANT_NOTICE = TimeUnit.HOURS.toMillis(23); public static final int VERSION_TO_ENABLE_PERSONALIZED_SUGGESTIONS = 1; // Copy of the hidden {@link Settings.Secure#USER_SETUP_COMPLETE} settings key. @@ -56,15 +65,18 @@ public final class ImportantNoticeUtils { } } - private static SharedPreferences getImportantNoticePreferences(final Context context) { + @UsedForTesting + static SharedPreferences getImportantNoticePreferences(final Context context) { return context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); } - private static int getCurrentImportantNoticeVersion(final Context context) { + @UsedForTesting + static int getCurrentImportantNoticeVersion(final Context context) { return context.getResources().getInteger(R.integer.config_important_notice_version); } - private static int getLastImportantNoticeVersion(final Context context) { + @UsedForTesting + static int getLastImportantNoticeVersion(final Context context) { return getImportantNoticePreferences(context).getInt(KEY_IMPORTANT_NOTICE_VERSION, 0); } @@ -77,6 +89,20 @@ public final class ImportantNoticeUtils { return getCurrentImportantNoticeVersion(context) > lastVersion; } + @UsedForTesting + static boolean hasTimeoutPassed(final Context context, final long currentTimeInMillis) { + final SharedPreferences prefs = getImportantNoticePreferences(context); + if (!prefs.contains(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE)) { + prefs.edit() + .putLong(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE, currentTimeInMillis) + .apply(); + } + final long firstDisplayTimeInMillis = prefs.getLong( + KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE, currentTimeInMillis); + final long elapsedTime = currentTimeInMillis - firstDisplayTimeInMillis; + return elapsedTime >= TIMEOUT_OF_IMPORTANT_NOTICE; + } + public static boolean shouldShowImportantNotice(final Context context) { if (!hasNewImportantNotice(context)) { return false; @@ -88,6 +114,10 @@ public final class ImportantNoticeUtils { if (isInSystemSetupWizard(context)) { return false; } + if (hasTimeoutPassed(context, System.currentTimeMillis())) { + updateLastImportantNoticeVersion(context); + return false; + } return true; } @@ -95,11 +125,12 @@ public final class ImportantNoticeUtils { getImportantNoticePreferences(context) .edit() .putInt(KEY_IMPORTANT_NOTICE_VERSION, getNextImportantNoticeVersion(context)) + .remove(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE) .apply(); } public static String getNextImportantNoticeTitle(final Context context) { - final int nextVersion = getCurrentImportantNoticeVersion(context); + final int nextVersion = getNextImportantNoticeVersion(context); final String[] importantNoticeTitleArray = context.getResources().getStringArray( R.array.important_notice_title_array); if (nextVersion > 0 && nextVersion < importantNoticeTitleArray.length) { diff --git a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java index 7170bd789..8cd49509f 100644 --- a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java +++ b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java @@ -32,14 +32,18 @@ import java.util.TreeSet; public final class SuggestionResults extends TreeSet<SuggestedWordInfo> { public final Locale mLocale; public final ArrayList<SuggestedWordInfo> mRawSuggestions; + // TODO: Instead of a boolean , we may want to include the context of this suggestion results, + // such as {@link PrevWordsInfo}. + public final boolean mIsBeginningOfSentence; private final int mCapacity; - public SuggestionResults(final Locale locale, final int capacity) { - this(locale, sSuggestedWordInfoComparator, capacity); + public SuggestionResults(final Locale locale, final int capacity, + final boolean isBeginningOfSentence) { + this(locale, sSuggestedWordInfoComparator, capacity, isBeginningOfSentence); } - public SuggestionResults(final Locale locale, final Comparator<SuggestedWordInfo> comparator, - final int capacity) { + private SuggestionResults(final Locale locale, final Comparator<SuggestedWordInfo> comparator, + final int capacity, final boolean isBeginningOfSentence) { super(comparator); mLocale = locale; mCapacity = capacity; @@ -48,6 +52,7 @@ public final class SuggestionResults extends TreeSet<SuggestedWordInfo> { } else { mRawSuggestions = null; } + mIsBeginningOfSentence = isBeginningOfSentence; } @Override |