Merge "[CB03] Pass whole events to the various input logic handlers."

This commit is contained in:
Jean Chalard 2014-03-13 12:12:30 +00:00 committed by Android (Google) Code Review
commit 309773c322
3 changed files with 137 additions and 134 deletions

View file

@ -130,6 +130,12 @@ public class Event {
return 0 != (FLAG_DEAD & mFlags); return 0 != (FLAG_DEAD & mFlags);
} }
// Returns whether this is a fake key press from the suggestion strip. This happens with
// punctuation signs selected from the suggestion strip.
public boolean isSuggestionStripPress() {
return EVENT_INPUT_KEYPRESS == mType && Constants.SUGGESTION_STRIP_COORDINATE == mX;
}
// TODO: remove this method - we should not have to test this // TODO: remove this method - we should not have to test this
public boolean isCommittable() { public boolean isCommittable() {
return EVENT_INPUT_KEYPRESS == mType || EVENT_MODE_KEY == mType || EVENT_TOGGLE == mType; return EVENT_INPUT_KEYPRESS == mType || EVENT_MODE_KEY == mType || EVENT_TOGGLE == mType;

View file

@ -33,11 +33,7 @@ public class InputTransaction {
// Initial conditions // Initial conditions
public final SettingsValues mSettingsValues; public final SettingsValues mSettingsValues;
// If the key inserts a code point, mKeyCode is always equal to the code points. Otherwise, public final Event mEvent;
// it's always a code that may not be a code point, typically a negative number.
public final int mKeyCode;
public final int mX; // Pressed x-coordinate, or one of Constants.*_COORDINATE
public final int mY; // Pressed y-coordinate, or one of Constants.*_COORDINATE
public final long mTimestamp; public final long mTimestamp;
public final int mSpaceState; public final int mSpaceState;
public final int mShiftState; public final int mShiftState;
@ -45,13 +41,10 @@ public class InputTransaction {
// Outputs // Outputs
private int mRequiredShiftUpdate = SHIFT_NO_UPDATE; private int mRequiredShiftUpdate = SHIFT_NO_UPDATE;
public InputTransaction(final SettingsValues settingsValues, final int keyCode, public InputTransaction(final SettingsValues settingsValues, final Event event,
final int x, final int y, final long timestamp, final int spaceState, final long timestamp, final int spaceState, final int shiftState) {
final int shiftState) {
mSettingsValues = settingsValues; mSettingsValues = settingsValues;
mKeyCode = keyCode; mEvent = event;
mX = x;
mY = y;
mTimestamp = timestamp; mTimestamp = timestamp;
mSpaceState = spaceState; mSpaceState = spaceState;
mShiftState = shiftState; mShiftState = shiftState;

View file

@ -368,16 +368,13 @@ public final class InputLogic {
// var because it's confusing. Instead the switch() should handle this in a readable manner. // var because it's confusing. Instead the switch() should handle this in a readable manner.
final int code = final int code =
Event.NOT_A_CODE_POINT == event.mCodePoint ? event.mKeyCode : event.mCodePoint; Event.NOT_A_CODE_POINT == event.mCodePoint ? event.mKeyCode : event.mCodePoint;
final int x = event.mX; final InputTransaction inputTransaction = new InputTransaction(settingsValues, event,
final int y = event.mY;
final InputTransaction inputTransaction = new InputTransaction(settingsValues, code, x, y,
SystemClock.uptimeMillis(), mSpaceState, SystemClock.uptimeMillis(), mSpaceState,
getActualCapsMode(settingsValues, keyboardShiftMode)); getActualCapsMode(settingsValues, keyboardShiftMode));
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_onCodeInput(inputTransaction.mKeyCode, ResearchLogger.latinIME_onCodeInput(code, event.mX, event.mY);
inputTransaction.mX, inputTransaction.mY);
} }
if (inputTransaction.mKeyCode != Constants.CODE_DELETE if (event.mKeyCode != Constants.CODE_DELETE
|| inputTransaction.mTimestamp > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) { || inputTransaction.mTimestamp > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) {
mDeleteCount = 0; mDeleteCount = 0;
} }
@ -388,15 +385,17 @@ public final class InputLogic {
} }
// TODO: Consolidate the double-space period timer, mLastKeyTime, and the space state. // TODO: Consolidate the double-space period timer, mLastKeyTime, and the space state.
if (inputTransaction.mKeyCode != Constants.CODE_SPACE) { if (event.mCodePoint != Constants.CODE_SPACE) {
handler.cancelDoubleSpacePeriodTimer(); handler.cancelDoubleSpacePeriodTimer();
} }
boolean didAutoCorrect = false; boolean didAutoCorrect = false;
switch (inputTransaction.mKeyCode) { if (Event.NOT_A_KEY_CODE != event.mKeyCode) {
// A special key, like delete, shift, emoji, or the settings key.
switch (event.mKeyCode) {
case Constants.CODE_DELETE: case Constants.CODE_DELETE:
handleBackspace(inputTransaction, handler); handleBackspace(inputTransaction, handler);
LatinImeLogger.logOnDelete(inputTransaction.mX, inputTransaction.mY); LatinImeLogger.logOnDelete(event.mX, event.mY);
break; break;
case Constants.CODE_SHIFT: case Constants.CODE_SHIFT:
performRecapitalization(inputTransaction.mSettingsValues); performRecapitalization(inputTransaction.mSettingsValues);
@ -434,13 +433,30 @@ public final class InputLogic {
// Note: Switching emoji keyboard is being handled in // Note: Switching emoji keyboard is being handled in
// {@link KeyboardState#onCodeInput(int,int)}. // {@link KeyboardState#onCodeInput(int,int)}.
break; break;
case Constants.CODE_ALPHA_FROM_EMOJI:
// Note: Switching back from Emoji keyboard to the main keyboard is being
// handled in {@link KeyboardState#onCodeInput(int,int)}.
break;
case Constants.CODE_SHIFT_ENTER:
// TODO: remove this object
final InputTransaction tmpTransaction = new InputTransaction(
inputTransaction.mSettingsValues, inputTransaction.mEvent,
inputTransaction.mTimestamp, inputTransaction.mSpaceState,
inputTransaction.mShiftState);
didAutoCorrect = handleNonSpecialCharacter(tmpTransaction, handler);
break;
default:
throw new RuntimeException("Unknown key code : " + event.mKeyCode);
}
} else {
switch (event.mCodePoint) {
case Constants.CODE_ENTER: case Constants.CODE_ENTER:
final EditorInfo editorInfo = getCurrentInputEditorInfo(); final EditorInfo editorInfo = getCurrentInputEditorInfo();
final int imeOptionsActionId = final int imeOptionsActionId =
InputTypeUtils.getImeOptionsActionIdFromEditorInfo(editorInfo); InputTypeUtils.getImeOptionsActionIdFromEditorInfo(editorInfo);
if (InputTypeUtils.IME_ACTION_CUSTOM_LABEL == imeOptionsActionId) { if (InputTypeUtils.IME_ACTION_CUSTOM_LABEL == imeOptionsActionId) {
// Either we have an actionLabel and we should performEditorAction with actionId // Either we have an actionLabel and we should performEditorAction with
// regardless of its value. // actionId regardless of its value.
performEditorAction(editorInfo.actionId); performEditorAction(editorInfo.actionId);
} else if (EditorInfo.IME_ACTION_NONE != imeOptionsActionId) { } else if (EditorInfo.IME_ACTION_NONE != imeOptionsActionId) {
// We didn't have an actionLabel, but we had another action to execute. // We didn't have an actionLabel, but we had another action to execute.
@ -457,28 +473,16 @@ public final class InputLogic {
didAutoCorrect = handleNonSpecialCharacter(inputTransaction, handler); didAutoCorrect = handleNonSpecialCharacter(inputTransaction, handler);
} }
break; break;
case Constants.CODE_SHIFT_ENTER:
// TODO: remove this object
final InputTransaction tmpTransaction = new InputTransaction(
inputTransaction.mSettingsValues, inputTransaction.mKeyCode,
inputTransaction.mX, inputTransaction.mY, inputTransaction.mTimestamp,
inputTransaction.mSpaceState, inputTransaction.mShiftState);
didAutoCorrect = handleNonSpecialCharacter(tmpTransaction, handler);
break;
case Constants.CODE_ALPHA_FROM_EMOJI:
// Note: Switching back from Emoji keyboard to the main keyboard is being handled in
// {@link KeyboardState#onCodeInput(int,int)}.
break;
default: default:
didAutoCorrect = handleNonSpecialCharacter(inputTransaction, handler); didAutoCorrect = handleNonSpecialCharacter(inputTransaction, handler);
break; break;
} }
// Reset after any single keystroke, except shift, capslock, and symbol-shift }
if (!didAutoCorrect && inputTransaction.mKeyCode != Constants.CODE_SHIFT if (!didAutoCorrect && event.mKeyCode != Constants.CODE_SHIFT
&& inputTransaction.mKeyCode != Constants.CODE_CAPSLOCK && event.mKeyCode != Constants.CODE_CAPSLOCK
&& inputTransaction.mKeyCode != Constants.CODE_SWITCH_ALPHA_SYMBOL) && event.mKeyCode != Constants.CODE_SWITCH_ALPHA_SYMBOL)
mLastComposedWord.deactivate(); mLastComposedWord.deactivate();
if (Constants.CODE_DELETE != inputTransaction.mKeyCode) { if (Constants.CODE_DELETE != event.mKeyCode) {
mEnteredText = null; mEnteredText = null;
} }
mConnection.endBatchEdit(); mConnection.endBatchEdit();
@ -632,15 +636,16 @@ public final class InputLogic {
private boolean handleNonSpecialCharacter(final InputTransaction inputTransaction, private boolean handleNonSpecialCharacter(final InputTransaction inputTransaction,
// TODO: remove this argument // TODO: remove this argument
final LatinIME.UIHandler handler) { final LatinIME.UIHandler handler) {
final int codePoint = inputTransaction.mEvent.mCodePoint;
mSpaceState = SpaceState.NONE; mSpaceState = SpaceState.NONE;
final boolean didAutoCorrect; final boolean didAutoCorrect;
if (inputTransaction.mSettingsValues.isWordSeparator(inputTransaction.mKeyCode) if (inputTransaction.mSettingsValues.isWordSeparator(codePoint)
|| Character.getType(inputTransaction.mKeyCode) == Character.OTHER_SYMBOL) { || Character.getType(codePoint) == Character.OTHER_SYMBOL) {
didAutoCorrect = handleSeparator(inputTransaction, didAutoCorrect = handleSeparator(inputTransaction,
Constants.SUGGESTION_STRIP_COORDINATE == inputTransaction.mX, handler); inputTransaction.mEvent.isSuggestionStripPress(), handler);
if (inputTransaction.mSettingsValues.mIsInternal) { if (inputTransaction.mSettingsValues.mIsInternal) {
LatinImeLoggerUtils.onSeparator((char)inputTransaction.mKeyCode, LatinImeLoggerUtils.onSeparator((char)codePoint,
inputTransaction.mX, inputTransaction.mY); inputTransaction.mEvent.mX, inputTransaction.mEvent.mY);
} }
} else { } else {
didAutoCorrect = false; didAutoCorrect = false;
@ -674,6 +679,7 @@ public final class InputLogic {
final InputTransaction inputTransaction, final InputTransaction inputTransaction,
// TODO: Remove this argument // TODO: Remove this argument
final LatinIME.UIHandler handler) { final LatinIME.UIHandler handler) {
final int codePoint = inputTransaction.mEvent.mCodePoint;
// TODO: refactor this method to stop flipping isComposingWord around all the time, and // TODO: refactor this method to stop flipping isComposingWord around all the time, and
// make it shorter (possibly cut into several pieces). Also factor handleNonSpecialCharacter // 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. // which has the same name as other handle* methods but is not the same.
@ -682,7 +688,7 @@ public final class InputLogic {
// TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead. // TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead.
// See onStartBatchInput() to see how to do it. // See onStartBatchInput() to see how to do it.
if (SpaceState.PHANTOM == inputTransaction.mSpaceState if (SpaceState.PHANTOM == inputTransaction.mSpaceState
&& !settingsValues.isWordConnector(inputTransaction.mKeyCode)) { && !settingsValues.isWordConnector(codePoint)) {
if (isComposingWord) { if (isComposingWord) {
// Sanity check // Sanity check
throw new RuntimeException("Should not be composing here"); throw new RuntimeException("Should not be composing here");
@ -704,7 +710,7 @@ public final class InputLogic {
if (!isComposingWord if (!isComposingWord
// We only start composing if this is a word code point. Essentially that means it's a // We only start composing if this is a word code point. Essentially that means it's a
// a letter or a word connector. // a letter or a word connector.
&& settingsValues.isWordCodePoint(inputTransaction.mKeyCode) && settingsValues.isWordCodePoint(codePoint)
// We never go into composing state if suggestions are not requested. // We never go into composing state if suggestions are not requested.
&& settingsValues.isSuggestionsRequested() && && settingsValues.isSuggestionsRequested() &&
// In languages with spaces, we only start composing a word when we are not already // In languages with spaces, we only start composing a word when we are not already
@ -715,8 +721,8 @@ public final class InputLogic {
// the character is a single quote or a dash. The idea here is, single quote and dash // the character is a single quote or a dash. The idea here is, single quote and dash
// are not separators and they should be treated as normal characters, except in the // are not separators and they should be treated as normal characters, except in the
// first position where they should not start composing a word. // first position where they should not start composing a word.
isComposingWord = (Constants.CODE_SINGLE_QUOTE != inputTransaction.mKeyCode isComposingWord = (Constants.CODE_SINGLE_QUOTE != codePoint
&& Constants.CODE_DASH != inputTransaction.mKeyCode); && Constants.CODE_DASH != codePoint);
// Here we don't need to reset the last composed word. It will be reset // Here we don't need to reset the last composed word. It will be reset
// when we commit this one, if we ever do; if on the other hand we backspace // when we commit this one, if we ever do; if on the other hand we backspace
// it entirely and resume suggestions on the previous word, we'd like to still // it entirely and resume suggestions on the previous word, we'd like to still
@ -724,7 +730,8 @@ public final class InputLogic {
resetComposingState(false /* alsoResetLastComposedWord */); resetComposingState(false /* alsoResetLastComposedWord */);
} }
if (isComposingWord) { if (isComposingWord) {
mWordComposer.add(inputTransaction.mKeyCode, inputTransaction.mX, inputTransaction.mY); // TODO: pass the entire event to the word composer.
mWordComposer.add(codePoint, inputTransaction.mEvent.mX, inputTransaction.mEvent.mY);
// If it's the first letter, make note of auto-caps state // If it's the first letter, make note of auto-caps state
if (mWordComposer.size() == 1) { if (mWordComposer.size() == 1) {
// We pass 1 to getPreviousWordForSuggestion because we were not composing a word // We pass 1 to getPreviousWordForSuggestion because we were not composing a word
@ -737,9 +744,9 @@ public final class InputLogic {
mWordComposer.getTypedWord()), 1); mWordComposer.getTypedWord()), 1);
} else { } else {
final boolean swapWeakSpace = maybeStripSpace(inputTransaction, final boolean swapWeakSpace = maybeStripSpace(inputTransaction,
Constants.SUGGESTION_STRIP_COORDINATE == inputTransaction.mX); inputTransaction.mEvent.isSuggestionStripPress());
sendKeyCodePoint(settingsValues, inputTransaction.mKeyCode); sendKeyCodePoint(settingsValues, codePoint);
if (swapWeakSpace) { if (swapWeakSpace) {
swapSwapperAndSpace(inputTransaction); swapSwapperAndSpace(inputTransaction);
@ -750,8 +757,8 @@ public final class InputLogic {
} }
handler.postUpdateSuggestionStrip(); handler.postUpdateSuggestionStrip();
if (settingsValues.mIsInternal) { if (settingsValues.mIsInternal) {
LatinImeLoggerUtils.onNonSeparator((char)inputTransaction.mKeyCode, inputTransaction.mX, LatinImeLoggerUtils.onNonSeparator((char)codePoint, inputTransaction.mEvent.mX,
inputTransaction.mY); inputTransaction.mEvent.mY);
} }
} }
@ -765,9 +772,10 @@ public final class InputLogic {
final boolean isFromSuggestionStrip, final boolean isFromSuggestionStrip,
// TODO: remove this argument // TODO: remove this argument
final LatinIME.UIHandler handler) { final LatinIME.UIHandler handler) {
final int codePoint = inputTransaction.mEvent.mCodePoint;
boolean didAutoCorrect = false; boolean didAutoCorrect = false;
// We avoid sending spaces in languages without spaces if we were composing. // We avoid sending spaces in languages without spaces if we were composing.
final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == inputTransaction.mKeyCode final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == codePoint
&& !inputTransaction.mSettingsValues.mSpacingAndPunctuations && !inputTransaction.mSettingsValues.mSpacingAndPunctuations
.mCurrentLanguageHasSpaces .mCurrentLanguageHasSpaces
&& mWordComposer.isComposingWord(); && mWordComposer.isComposingWord();
@ -781,46 +789,44 @@ public final class InputLogic {
if (mWordComposer.isComposingWord()) { if (mWordComposer.isComposingWord()) {
if (inputTransaction.mSettingsValues.mCorrectionEnabled) { if (inputTransaction.mSettingsValues.mCorrectionEnabled) {
final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR
: StringUtils.newSingleCodePointString(inputTransaction.mKeyCode); : StringUtils.newSingleCodePointString(codePoint);
commitCurrentAutoCorrection(inputTransaction.mSettingsValues, separator, handler); commitCurrentAutoCorrection(inputTransaction.mSettingsValues, separator, handler);
didAutoCorrect = true; didAutoCorrect = true;
} else { } else {
commitTyped(inputTransaction.mSettingsValues, commitTyped(inputTransaction.mSettingsValues,
StringUtils.newSingleCodePointString(inputTransaction.mKeyCode)); StringUtils.newSingleCodePointString(codePoint));
} }
} }
final boolean swapWeakSpace = maybeStripSpace(inputTransaction, isFromSuggestionStrip); final boolean swapWeakSpace = maybeStripSpace(inputTransaction, isFromSuggestionStrip);
final boolean isInsideDoubleQuoteOrAfterDigit = final boolean isInsideDoubleQuoteOrAfterDigit = Constants.CODE_DOUBLE_QUOTE == codePoint
Constants.CODE_DOUBLE_QUOTE == inputTransaction.mKeyCode
&& mConnection.isInsideDoubleQuoteOrAfterDigit(); && mConnection.isInsideDoubleQuoteOrAfterDigit();
final boolean needsPrecedingSpace; final boolean needsPrecedingSpace;
if (SpaceState.PHANTOM != inputTransaction.mSpaceState) { if (SpaceState.PHANTOM != inputTransaction.mSpaceState) {
needsPrecedingSpace = false; needsPrecedingSpace = false;
} else if (Constants.CODE_DOUBLE_QUOTE == inputTransaction.mKeyCode) { } else if (Constants.CODE_DOUBLE_QUOTE == codePoint) {
// Double quotes behave like they are usually preceded by space iff we are // Double quotes behave like they are usually preceded by space iff we are
// not inside a double quote or after a digit. // not inside a double quote or after a digit.
needsPrecedingSpace = !isInsideDoubleQuoteOrAfterDigit; needsPrecedingSpace = !isInsideDoubleQuoteOrAfterDigit;
} else { } else {
needsPrecedingSpace = inputTransaction.mSettingsValues.isUsuallyPrecededBySpace( needsPrecedingSpace = inputTransaction.mSettingsValues.isUsuallyPrecededBySpace(
inputTransaction.mKeyCode); codePoint);
} }
if (needsPrecedingSpace) { if (needsPrecedingSpace) {
promotePhantomSpace(inputTransaction.mSettingsValues); promotePhantomSpace(inputTransaction.mSettingsValues);
} }
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_handleSeparator(inputTransaction.mKeyCode, ResearchLogger.latinIME_handleSeparator(codePoint, mWordComposer.isComposingWord());
mWordComposer.isComposingWord());
} }
if (!shouldAvoidSendingCode) { if (!shouldAvoidSendingCode) {
sendKeyCodePoint(inputTransaction.mSettingsValues, inputTransaction.mKeyCode); sendKeyCodePoint(inputTransaction.mSettingsValues, codePoint);
} }
if (Constants.CODE_SPACE == inputTransaction.mKeyCode) { if (Constants.CODE_SPACE == codePoint) {
if (inputTransaction.mSettingsValues.isSuggestionsRequested()) { if (inputTransaction.mSettingsValues.isSuggestionsRequested()) {
if (maybeDoubleSpacePeriod(inputTransaction.mSettingsValues, handler)) { if (maybeDoubleSpacePeriod(inputTransaction.mSettingsValues, handler)) {
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
@ -837,9 +843,8 @@ public final class InputLogic {
swapSwapperAndSpace(inputTransaction); swapSwapperAndSpace(inputTransaction);
mSpaceState = SpaceState.SWAP_PUNCTUATION; mSpaceState = SpaceState.SWAP_PUNCTUATION;
} else if ((SpaceState.PHANTOM == inputTransaction.mSpaceState } else if ((SpaceState.PHANTOM == inputTransaction.mSpaceState
&& inputTransaction.mSettingsValues.isUsuallyFollowedBySpace( && inputTransaction.mSettingsValues.isUsuallyFollowedBySpace(codePoint))
inputTransaction.mKeyCode)) || (Constants.CODE_DOUBLE_QUOTE == codePoint
|| (Constants.CODE_DOUBLE_QUOTE == inputTransaction.mKeyCode
&& isInsideDoubleQuoteOrAfterDigit)) { && isInsideDoubleQuoteOrAfterDigit)) {
// If we are in phantom space state, and the user presses a separator, we want to // If we are in phantom space state, and the user presses a separator, we want to
// stay in phantom space state so that the next keypress has a chance to add the // stay in phantom space state so that the next keypress has a chance to add the
@ -1056,7 +1061,8 @@ public final class InputLogic {
*/ */
private boolean maybeStripSpace(final InputTransaction inputTransaction, private boolean maybeStripSpace(final InputTransaction inputTransaction,
final boolean isFromSuggestionStrip) { final boolean isFromSuggestionStrip) {
if (Constants.CODE_ENTER == inputTransaction.mKeyCode && final int codePoint = inputTransaction.mEvent.mCodePoint;
if (Constants.CODE_ENTER == codePoint &&
SpaceState.SWAP_PUNCTUATION == inputTransaction.mSpaceState) { SpaceState.SWAP_PUNCTUATION == inputTransaction.mSpaceState) {
mConnection.removeTrailingSpace(); mConnection.removeTrailingSpace();
return false; return false;
@ -1064,12 +1070,10 @@ public final class InputLogic {
if ((SpaceState.WEAK == inputTransaction.mSpaceState if ((SpaceState.WEAK == inputTransaction.mSpaceState
|| SpaceState.SWAP_PUNCTUATION == inputTransaction.mSpaceState) || SpaceState.SWAP_PUNCTUATION == inputTransaction.mSpaceState)
&& isFromSuggestionStrip) { && isFromSuggestionStrip) {
if (inputTransaction.mSettingsValues.isUsuallyPrecededBySpace( if (inputTransaction.mSettingsValues.isUsuallyPrecededBySpace(codePoint)) {
inputTransaction.mKeyCode)) {
return false; return false;
} }
if (inputTransaction.mSettingsValues.isUsuallyFollowedBySpace( if (inputTransaction.mSettingsValues.isUsuallyFollowedBySpace(codePoint)) {
inputTransaction.mKeyCode)) {
return true; return true;
} }
mConnection.removeTrailingSpace(); mConnection.removeTrailingSpace();