am e3247561: Merge "Support languages that don\'t use spaces."
* commit 'e32475611ce52671802ca8d2f9694bbb82c4b120': Support languages that don't use spaces.main
commit
5b0aeafb5e
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2013, 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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
|
<!-- Whether this language uses spaces -->
|
||||||
|
<bool name="current_language_has_spaces">false</bool>
|
||||||
|
</resources>
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
-->
|
-->
|
||||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
|
<!-- TODO: these settings depend on the language. They should be put either in the dictionary
|
||||||
|
header, or in the subtype maybe? -->
|
||||||
<!-- Symbols that are suggested between words -->
|
<!-- Symbols that are suggested between words -->
|
||||||
<string name="suggested_punctuations">!,?,\\,,:,;,\",(,),\',-,/,@,_</string>
|
<string name="suggested_punctuations">!,?,\\,,:,;,\",(,),\',-,/,@,_</string>
|
||||||
<!-- Symbols that are normally preceded by a space (used to add an auto-space before these) -->
|
<!-- Symbols that are normally preceded by a space (used to add an auto-space before these) -->
|
||||||
|
@ -29,6 +31,8 @@
|
||||||
<string name="symbols_word_separators">"	 \n"()[]{}*&<>+=|.,;:!?/_\"</string>
|
<string name="symbols_word_separators">"	 \n"()[]{}*&<>+=|.,;:!?/_\"</string>
|
||||||
<!-- Word connectors -->
|
<!-- Word connectors -->
|
||||||
<string name="symbols_word_connectors">\'-</string>
|
<string name="symbols_word_connectors">\'-</string>
|
||||||
|
<!-- Whether this language uses spaces -->
|
||||||
|
<bool name="current_language_has_spaces">true</bool>
|
||||||
|
|
||||||
<!-- Always show the suggestion strip -->
|
<!-- Always show the suggestion strip -->
|
||||||
<string name="prefs_suggestion_visibility_show_value">0</string>
|
<string name="prefs_suggestion_visibility_show_value">0</string>
|
||||||
|
|
|
@ -1948,7 +1948,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (currentSettings.isSuggestionsRequested(mDisplayOrientation)) {
|
if (currentSettings.isSuggestionsRequested(mDisplayOrientation)
|
||||||
|
&& currentSettings.mCurrentLanguageHasSpaces) {
|
||||||
restartSuggestionsOnWordBeforeCursorIfAtEndOfWord();
|
restartSuggestionsOnWordBeforeCursorIfAtEndOfWord();
|
||||||
}
|
}
|
||||||
// We just removed a character. We need to update the auto-caps state.
|
// We just removed a character. We need to update the auto-caps state.
|
||||||
|
@ -1977,6 +1978,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
|
|
||||||
private void handleCharacter(final int primaryCode, final int x,
|
private void handleCharacter(final int primaryCode, final int x,
|
||||||
final int y, final int spaceState) {
|
final int y, final int spaceState) {
|
||||||
|
// TODO: refactor this method to stop flipping isComposingWord around all the time, and
|
||||||
|
// make it shorter (possibly cut into several pieces). Also factor handleNonSpecialCharacter
|
||||||
|
// which has the same name as other handle* methods but is not the same.
|
||||||
boolean isComposingWord = mWordComposer.isComposingWord();
|
boolean isComposingWord = mWordComposer.isComposingWord();
|
||||||
|
|
||||||
// TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead.
|
// TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead.
|
||||||
|
@ -1996,12 +2000,20 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
resetEntireInputState(mLastSelectionStart);
|
resetEntireInputState(mLastSelectionStart);
|
||||||
isComposingWord = false;
|
isComposingWord = false;
|
||||||
}
|
}
|
||||||
// NOTE: isCursorTouchingWord() is a blocking IPC call, so it often takes several
|
// We want to find out whether to start composing a new word with this character. If so,
|
||||||
// dozen milliseconds. Avoid calling it as much as possible, since we are on the UI
|
// we need to reset the composing state and switch isComposingWord. The order of the
|
||||||
// thread here.
|
// tests is important for good performance.
|
||||||
if (!isComposingWord && currentSettings.isWordCodePoint(primaryCode)
|
// We only start composing if we're not already composing.
|
||||||
|
if (!isComposingWord
|
||||||
|
// We only start composing if this is a word code point. Essentially that means it's a
|
||||||
|
// a letter or a word connector.
|
||||||
|
&& currentSettings.isWordCodePoint(primaryCode)
|
||||||
|
// We never go into composing state if suggestions are not requested.
|
||||||
&& currentSettings.isSuggestionsRequested(mDisplayOrientation) &&
|
&& currentSettings.isSuggestionsRequested(mDisplayOrientation) &&
|
||||||
!mConnection.isCursorTouchingWord(currentSettings)) {
|
// In languages with spaces, we only start composing a word when we are not already
|
||||||
|
// touching a word. In languages without spaces, the above conditions are sufficient.
|
||||||
|
(!mConnection.isCursorTouchingWord(currentSettings)
|
||||||
|
|| !currentSettings.mCurrentLanguageHasSpaces)) {
|
||||||
// Reset entirely the composing state anyway, then start composing a new word unless
|
// Reset entirely the composing state anyway, then start composing a new word unless
|
||||||
// the character is a single quote. The idea here is, single quote is not a
|
// the character is a single quote. The idea here is, single quote is not a
|
||||||
// separator and it should be treated as a normal character, except in the first
|
// separator and it should be treated as a normal character, except in the first
|
||||||
|
@ -2089,16 +2101,20 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
private boolean handleSeparator(final int primaryCode, final int x, final int y,
|
private boolean handleSeparator(final int primaryCode, final int x, final int y,
|
||||||
final int spaceState) {
|
final int spaceState) {
|
||||||
boolean didAutoCorrect = false;
|
boolean didAutoCorrect = false;
|
||||||
|
final SettingsValues currentSettings = mSettings.getCurrent();
|
||||||
|
// We avoid sending spaces in languages without spaces if we were composing.
|
||||||
|
final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == primaryCode
|
||||||
|
&& !currentSettings.mCurrentLanguageHasSpaces && mWordComposer.isComposingWord();
|
||||||
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
|
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
|
||||||
// If we are in the middle of a recorrection, we need to commit the recorrection
|
// If we are in the middle of a recorrection, we need to commit the recorrection
|
||||||
// first so that we can insert the separator at the current cursor position.
|
// first so that we can insert the separator at the current cursor position.
|
||||||
resetEntireInputState(mLastSelectionStart);
|
resetEntireInputState(mLastSelectionStart);
|
||||||
}
|
}
|
||||||
final SettingsValues currentSettings = mSettings.getCurrent();
|
if (mWordComposer.isComposingWord()) { // May have changed since we stored wasComposing
|
||||||
if (mWordComposer.isComposingWord()) {
|
|
||||||
if (currentSettings.mCorrectionEnabled) {
|
if (currentSettings.mCorrectionEnabled) {
|
||||||
// TODO: maybe cache Strings in an <String> sparse array or something
|
final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR
|
||||||
commitCurrentAutoCorrection(new String(new int[]{primaryCode}, 0, 1));
|
: new String(new int[] { primaryCode }, 0, 1);
|
||||||
|
commitCurrentAutoCorrection(separator);
|
||||||
didAutoCorrect = true;
|
didAutoCorrect = true;
|
||||||
} else {
|
} else {
|
||||||
commitTyped(new String(new int[]{primaryCode}, 0, 1));
|
commitTyped(new String(new int[]{primaryCode}, 0, 1));
|
||||||
|
@ -2115,7 +2131,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
|
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
|
||||||
ResearchLogger.latinIME_handleSeparator(primaryCode, mWordComposer.isComposingWord());
|
ResearchLogger.latinIME_handleSeparator(primaryCode, mWordComposer.isComposingWord());
|
||||||
}
|
}
|
||||||
sendKeyCodePoint(primaryCode);
|
|
||||||
|
if (!shouldAvoidSendingCode) {
|
||||||
|
sendKeyCodePoint(primaryCode);
|
||||||
|
}
|
||||||
|
|
||||||
if (Constants.CODE_SPACE == primaryCode) {
|
if (Constants.CODE_SPACE == primaryCode) {
|
||||||
if (currentSettings.isSuggestionsRequested(mDisplayOrientation)) {
|
if (currentSettings.isSuggestionsRequested(mDisplayOrientation)) {
|
||||||
|
@ -2260,11 +2279,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// Get the word on which we should search the bigrams. If we are composing a word, it's
|
// Get the word on which we should search the bigrams. If we are composing a word, it's
|
||||||
// whatever is *before* the half-committed word in the buffer, hence 2; if we aren't, we
|
// whatever is *before* the half-committed word in the buffer, hence 2; if we aren't, we
|
||||||
// should just skip whitespace if any, so 1.
|
// should just skip whitespace if any, so 1.
|
||||||
// TODO: this is slow (2-way IPC) - we should probably cache this instead.
|
|
||||||
final SettingsValues currentSettings = mSettings.getCurrent();
|
final SettingsValues currentSettings = mSettings.getCurrent();
|
||||||
final String prevWord =
|
final String prevWord;
|
||||||
mConnection.getNthPreviousWord(currentSettings.mWordSeparators,
|
if (currentSettings.mCurrentLanguageHasSpaces) {
|
||||||
mWordComposer.isComposingWord() ? 2 : 1);
|
// If we are typing in a language with spaces we can just look up the previous
|
||||||
|
// word from textview.
|
||||||
|
prevWord = mConnection.getNthPreviousWord(currentSettings.mWordSeparators,
|
||||||
|
mWordComposer.isComposingWord() ? 2 : 1);
|
||||||
|
} else {
|
||||||
|
prevWord = LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ? null
|
||||||
|
: mLastComposedWord.mCommittedWord;
|
||||||
|
}
|
||||||
return suggest.getSuggestedWords(mWordComposer, prevWord, keyboard.getProximityInfo(),
|
return suggest.getSuggestedWords(mWordComposer, prevWord, keyboard.getProximityInfo(),
|
||||||
currentSettings.mBlockPotentiallyOffensive,
|
currentSettings.mBlockPotentiallyOffensive,
|
||||||
currentSettings.mCorrectionEnabled, sessionId);
|
currentSettings.mCorrectionEnabled, sessionId);
|
||||||
|
@ -2534,6 +2559,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// recorrection. This is a temporary, stopgap measure that will be removed later.
|
// recorrection. This is a temporary, stopgap measure that will be removed later.
|
||||||
// TODO: remove this.
|
// TODO: remove this.
|
||||||
if (mAppWorkAroundsUtils.isBrokenByRecorrection()) return;
|
if (mAppWorkAroundsUtils.isBrokenByRecorrection()) return;
|
||||||
|
// Recorrection is not supported in languages without spaces because we don't know
|
||||||
|
// how to segment them yet.
|
||||||
|
if (!mSettings.getCurrent().mCurrentLanguageHasSpaces) return;
|
||||||
// If the cursor is not touching a word, or if there is a selection, return right away.
|
// If the cursor is not touching a word, or if there is a selection, return right away.
|
||||||
if (mLastSelectionStart != mLastSelectionEnd) return;
|
if (mLastSelectionStart != mLastSelectionEnd) return;
|
||||||
// If we don't know the cursor location, return.
|
// If we don't know the cursor location, return.
|
||||||
|
@ -2656,7 +2684,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) {
|
if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) {
|
||||||
mUserHistoryPredictionDictionary.cancelAddingUserHistory(previousWord, committedWord);
|
mUserHistoryPredictionDictionary.cancelAddingUserHistory(previousWord, committedWord);
|
||||||
}
|
}
|
||||||
mConnection.commitText(originallyTypedWord + mLastComposedWord.mSeparatorString, 1);
|
final String stringToCommit = originallyTypedWord + mLastComposedWord.mSeparatorString;
|
||||||
|
if (mSettings.getCurrent().mCurrentLanguageHasSpaces) {
|
||||||
|
// For languages with spaces, we revert to the typed string, but the cursor is still
|
||||||
|
// after the separator so we don't resume suggestions. If the user wants to correct
|
||||||
|
// the word, they have to press backspace again.
|
||||||
|
mConnection.commitText(stringToCommit, 1);
|
||||||
|
} else {
|
||||||
|
// For languages without spaces, we revert the typed string but the cursor is flush
|
||||||
|
// with the typed word, so we need to resume suggestions right away.
|
||||||
|
mWordComposer.setComposingWord(stringToCommit, mKeyboardSwitcher.getKeyboard());
|
||||||
|
mConnection.setComposingText(stringToCommit, 1);
|
||||||
|
}
|
||||||
if (mSettings.isInternal()) {
|
if (mSettings.isInternal()) {
|
||||||
LatinImeLoggerUtils.onSeparator(mLastComposedWord.mSeparatorString,
|
LatinImeLoggerUtils.onSeparator(mLastComposedWord.mSeparatorString,
|
||||||
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
|
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
|
||||||
|
@ -2674,7 +2713,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
|
|
||||||
// This essentially inserts a space, and that's it.
|
// This essentially inserts a space, and that's it.
|
||||||
public void promotePhantomSpace() {
|
public void promotePhantomSpace() {
|
||||||
if (mSettings.getCurrent().shouldInsertSpacesAutomatically()
|
final SettingsValues currentSettings = mSettings.getCurrent();
|
||||||
|
if (currentSettings.shouldInsertSpacesAutomatically()
|
||||||
|
&& currentSettings.mCurrentLanguageHasSpaces
|
||||||
&& !mConnection.textBeforeCursorLooksLikeURL()) {
|
&& !mConnection.textBeforeCursorLooksLikeURL()) {
|
||||||
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
|
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
|
||||||
ResearchLogger.latinIME_promotePhantomSpace();
|
ResearchLogger.latinIME_promotePhantomSpace();
|
||||||
|
@ -2887,6 +2928,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
return mSuggest.hasMainDictionary();
|
return mSuggest.hasMainDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DO NOT USE THIS for any other purpose than testing. This can break the keyboard badly.
|
||||||
|
@UsedForTesting
|
||||||
|
/* package for test */ void replaceMainDictionaryForTest(final Locale locale) {
|
||||||
|
mSuggest.resetMainDict(this, locale, null);
|
||||||
|
}
|
||||||
|
|
||||||
public void debugDumpStateAndCrashWithException(final String context) {
|
public void debugDumpStateAndCrashWithException(final String context) {
|
||||||
final StringBuilder s = new StringBuilder(mAppWorkAroundsUtils.toString());
|
final StringBuilder s = new StringBuilder(mAppWorkAroundsUtils.toString());
|
||||||
s.append("\nAttributes : ").append(mSettings.getCurrent().mInputAttributes)
|
s.append("\nAttributes : ").append(mSettings.getCurrent().mInputAttributes)
|
||||||
|
|
|
@ -57,6 +57,7 @@ public final class SettingsValues {
|
||||||
public final SuggestedWords mSuggestPuncList;
|
public final SuggestedWords mSuggestPuncList;
|
||||||
public final String mWordSeparators;
|
public final String mWordSeparators;
|
||||||
public final CharSequence mHintToSaveText;
|
public final CharSequence mHintToSaveText;
|
||||||
|
public final boolean mCurrentLanguageHasSpaces;
|
||||||
|
|
||||||
// From preferences, in the same order as xml/prefs.xml:
|
// From preferences, in the same order as xml/prefs.xml:
|
||||||
public final boolean mAutoCap;
|
public final boolean mAutoCap;
|
||||||
|
@ -118,6 +119,7 @@ public final class SettingsValues {
|
||||||
mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
|
mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
|
||||||
mWordSeparators = res.getString(R.string.symbols_word_separators);
|
mWordSeparators = res.getString(R.string.symbols_word_separators);
|
||||||
mHintToSaveText = res.getText(R.string.hint_add_to_dictionary);
|
mHintToSaveText = res.getText(R.string.hint_add_to_dictionary);
|
||||||
|
mCurrentLanguageHasSpaces = res.getBoolean(R.bool.current_language_has_spaces);
|
||||||
|
|
||||||
// Store the input attributes
|
// Store the input attributes
|
||||||
if (null == inputAttributes) {
|
if (null == inputAttributes) {
|
||||||
|
@ -186,6 +188,7 @@ public final class SettingsValues {
|
||||||
mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
|
mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
|
||||||
mWordSeparators = "&\t \n()[]{}*&<>+=|.,;:!?/_\"";
|
mWordSeparators = "&\t \n()[]{}*&<>+=|.,;:!?/_\"";
|
||||||
mHintToSaveText = "Touch again to save";
|
mHintToSaveText = "Touch again to save";
|
||||||
|
mCurrentLanguageHasSpaces = true;
|
||||||
mInputAttributes = new InputAttributes(null, false /* isFullscreenMode */);
|
mInputAttributes = new InputAttributes(null, false /* isFullscreenMode */);
|
||||||
mAutoCap = true;
|
mAutoCap = true;
|
||||||
mVibrateOn = true;
|
mVibrateOn = true;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package com.android.inputmethod.latin;
|
package com.android.inputmethod.latin;
|
||||||
|
|
||||||
import android.test.suitebuilder.annotation.LargeTest;
|
import android.test.suitebuilder.annotation.LargeTest;
|
||||||
|
import android.view.inputmethod.BaseInputConnection;
|
||||||
|
|
||||||
@LargeTest
|
@LargeTest
|
||||||
public class InputLogicTests extends InputTestsBase {
|
public class InputLogicTests extends InputTestsBase {
|
||||||
|
@ -290,5 +291,19 @@ public class InputLogicTests extends InputTestsBase {
|
||||||
}
|
}
|
||||||
assertEquals("delete whole composing word", "", mEditText.getText().toString());
|
assertEquals("delete whole composing word", "", mEditText.getText().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testResumeSuggestionOnBackspace() {
|
||||||
|
final String WORD_TO_TYPE = "and this ";
|
||||||
|
type(WORD_TO_TYPE);
|
||||||
|
assertEquals("resume suggestion on backspace", -1,
|
||||||
|
BaseInputConnection.getComposingSpanStart(mEditText.getText()));
|
||||||
|
assertEquals("resume suggestion on backspace", -1,
|
||||||
|
BaseInputConnection.getComposingSpanEnd(mEditText.getText()));
|
||||||
|
type(Constants.CODE_DELETE);
|
||||||
|
assertEquals("resume suggestion on backspace", 4,
|
||||||
|
BaseInputConnection.getComposingSpanStart(mEditText.getText()));
|
||||||
|
assertEquals("resume suggestion on backspace", 8,
|
||||||
|
BaseInputConnection.getComposingSpanEnd(mEditText.getText()));
|
||||||
|
}
|
||||||
// TODO: Add some tests for non-BMP characters
|
// TODO: Add some tests for non-BMP characters
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013 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.test.suitebuilder.annotation.LargeTest;
|
||||||
|
import android.view.inputmethod.BaseInputConnection;
|
||||||
|
|
||||||
|
import com.android.inputmethod.latin.suggestions.SuggestionStripView;
|
||||||
|
|
||||||
|
@LargeTest
|
||||||
|
public class InputLogicTestsLanguageWithoutSpaces extends InputTestsBase {
|
||||||
|
public void testAutoCorrectForLanguageWithoutSpaces() {
|
||||||
|
final String STRING_TO_TYPE = "tgis is";
|
||||||
|
final String EXPECTED_RESULT = "thisis";
|
||||||
|
changeKeyboardLocaleAndDictLocale("th", "en_US");
|
||||||
|
type(STRING_TO_TYPE);
|
||||||
|
assertEquals("simple auto-correct for language without spaces", EXPECTED_RESULT,
|
||||||
|
mEditText.getText().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRevertAutoCorrectForLanguageWithoutSpaces() {
|
||||||
|
final String STRING_TO_TYPE = "tgis ";
|
||||||
|
final String EXPECTED_INTERMEDIATE_RESULT = "this";
|
||||||
|
final String EXPECTED_FINAL_RESULT = "tgis";
|
||||||
|
changeKeyboardLocaleAndDictLocale("th", "en_US");
|
||||||
|
type(STRING_TO_TYPE);
|
||||||
|
assertEquals("simple auto-correct for language without spaces",
|
||||||
|
EXPECTED_INTERMEDIATE_RESULT, mEditText.getText().toString());
|
||||||
|
type(Constants.CODE_DELETE);
|
||||||
|
assertEquals("simple auto-correct for language without spaces",
|
||||||
|
EXPECTED_FINAL_RESULT, mEditText.getText().toString());
|
||||||
|
// Check we are back to composing the word
|
||||||
|
assertEquals("don't resume suggestion on backspace", 0,
|
||||||
|
BaseInputConnection.getComposingSpanStart(mEditText.getText()));
|
||||||
|
assertEquals("don't resume suggestion on backspace", 4,
|
||||||
|
BaseInputConnection.getComposingSpanEnd(mEditText.getText()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDontResumeSuggestionOnBackspace() {
|
||||||
|
final String WORD_TO_TYPE = "and this ";
|
||||||
|
changeKeyboardLocaleAndDictLocale("th", "en_US");
|
||||||
|
type(WORD_TO_TYPE);
|
||||||
|
assertEquals("don't resume suggestion on backspace", -1,
|
||||||
|
BaseInputConnection.getComposingSpanStart(mEditText.getText()));
|
||||||
|
assertEquals("don't resume suggestion on backspace", -1,
|
||||||
|
BaseInputConnection.getComposingSpanEnd(mEditText.getText()));
|
||||||
|
type(" ");
|
||||||
|
type(Constants.CODE_DELETE);
|
||||||
|
assertEquals("don't resume suggestion on backspace", -1,
|
||||||
|
BaseInputConnection.getComposingSpanStart(mEditText.getText()));
|
||||||
|
assertEquals("don't resume suggestion on backspace", -1,
|
||||||
|
BaseInputConnection.getComposingSpanEnd(mEditText.getText()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testStartComposingInsideText() {
|
||||||
|
final String WORD_TO_TYPE = "abcdefgh ";
|
||||||
|
final int typedLength = WORD_TO_TYPE.length() - 1; // -1 because space gets eaten
|
||||||
|
final int CURSOR_POS = 4;
|
||||||
|
changeKeyboardLocaleAndDictLocale("th", "en_US");
|
||||||
|
type(WORD_TO_TYPE);
|
||||||
|
mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, -1, -1);
|
||||||
|
mInputConnection.setSelection(CURSOR_POS, CURSOR_POS);
|
||||||
|
mLatinIME.onUpdateSelection(typedLength, typedLength,
|
||||||
|
CURSOR_POS, CURSOR_POS, -1, -1);
|
||||||
|
sleep(DELAY_TO_WAIT_FOR_PREDICTIONS);
|
||||||
|
runMessages();
|
||||||
|
assertEquals("start composing inside text", -1,
|
||||||
|
BaseInputConnection.getComposingSpanStart(mEditText.getText()));
|
||||||
|
assertEquals("start composing inside text", -1,
|
||||||
|
BaseInputConnection.getComposingSpanEnd(mEditText.getText()));
|
||||||
|
type("xxxx");
|
||||||
|
assertEquals("start composing inside text", 4,
|
||||||
|
BaseInputConnection.getComposingSpanStart(mEditText.getText()));
|
||||||
|
assertEquals("start composing inside text", 8,
|
||||||
|
BaseInputConnection.getComposingSpanEnd(mEditText.getText()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPredictions() {
|
||||||
|
final String WORD_TO_TYPE = "Barack ";
|
||||||
|
changeKeyboardLocaleAndDictLocale("th", "en_US");
|
||||||
|
type(WORD_TO_TYPE);
|
||||||
|
sleep(DELAY_TO_WAIT_FOR_PREDICTIONS);
|
||||||
|
runMessages();
|
||||||
|
// Make sure there is no space
|
||||||
|
assertEquals("predictions in lang without spaces", "Barack",
|
||||||
|
mEditText.getText().toString());
|
||||||
|
// Test the first prediction is displayed
|
||||||
|
assertEquals("predictions in lang without spaces", "Obama",
|
||||||
|
mLatinIME.getFirstSuggestedWord());
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,6 +46,8 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
|
||||||
|
|
||||||
// The message that sets the underline is posted with a 100 ms delay
|
// The message that sets the underline is posted with a 100 ms delay
|
||||||
protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 200;
|
protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 200;
|
||||||
|
// The message that sets predictions is posted with a 100 ms delay
|
||||||
|
protected static final int DELAY_TO_WAIT_FOR_PREDICTIONS = 200;
|
||||||
|
|
||||||
protected LatinIME mLatinIME;
|
protected LatinIME mLatinIME;
|
||||||
protected Keyboard mKeyboard;
|
protected Keyboard mKeyboard;
|
||||||
|
@ -233,9 +235,6 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
|
||||||
--remainingAttempts;
|
--remainingAttempts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!mLatinIME.hasMainDictionary()) {
|
|
||||||
throw new RuntimeException("Can't initialize the main dictionary");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void changeLanguage(final String locale) {
|
protected void changeLanguage(final String locale) {
|
||||||
|
@ -247,6 +246,16 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
|
||||||
waitForDictionaryToBeLoaded();
|
waitForDictionaryToBeLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void changeKeyboardLocaleAndDictLocale(final String keyboardLocale,
|
||||||
|
final String dictLocale) {
|
||||||
|
changeLanguage(keyboardLocale);
|
||||||
|
if (!keyboardLocale.equals(dictLocale)) {
|
||||||
|
mLatinIME.replaceMainDictionaryForTest(
|
||||||
|
LocaleUtils.constructLocaleFromString(dictLocale));
|
||||||
|
}
|
||||||
|
waitForDictionaryToBeLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
protected void pickSuggestionManually(final int index, final String suggestion) {
|
protected void pickSuggestionManually(final int index, final String suggestion) {
|
||||||
mLatinIME.pickSuggestionManually(index, new SuggestedWordInfo(suggestion, 1,
|
mLatinIME.pickSuggestionManually(index, new SuggestedWordInfo(suggestion, 1,
|
||||||
SuggestedWordInfo.KIND_CORRECTION, "main"));
|
SuggestedWordInfo.KIND_CORRECTION, "main"));
|
||||||
|
|
Loading…
Reference in New Issue