From 4f1f2201bdd0e63a19e686caa3d17b16eb134f5e Mon Sep 17 00:00:00 2001 From: Maryam Garrett Date: Thu, 4 Mar 2010 09:34:21 -0500 Subject: [PATCH] Fixes the over-logging of TextModified We were overlogging the TextMoified action because the old implementation would log a cursor change as a text modification. This CL logs 4 specific actions (choose suggestion, delete text, insert text, insert punctuation) as a text modification rather than any action in the textbox I also add in logging of the length of the recognition result so that we can get some more context around the scope of the editing of the ime result. Change-Id: I172df24ddc0a7b62bcc5ed806fd70ef7e1c42310 --- .../android/inputmethod/latin/LatinIME.java | 44 ++++++- .../android/inputmethod/voice/VoiceInput.java | 107 +++++++++++++++++- .../inputmethod/voice/VoiceInputLogger.java | 39 ++++++- 3 files changed, 179 insertions(+), 11 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index ffa7b0a4b..70d49f564 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -234,6 +234,7 @@ public class LatinIME extends InputMethodService List candidates; Map> alternatives; } + private boolean mRefreshKeyboardRequired; Handler mHandler = new Handler() { @@ -552,6 +553,7 @@ public class LatinIME extends InputMethodService if (VOICE_INSTALLED && !mConfigurationChanging) { if (mAfterVoiceInput) { + mVoiceInput.flushAllTextModificationCounters(); mVoiceInput.logInputEnded(); } mVoiceInput.flushLogs(); @@ -567,8 +569,6 @@ public class LatinIME extends InputMethodService super.onUpdateExtractedText(token, text); InputConnection ic = getCurrentInputConnection(); if (!mImmediatelyAfterVoiceInput && mAfterVoiceInput && ic != null) { - mVoiceInput.logTextModified(); - if (mHints.showPunctuationHintIfNecessary(ic)) { mVoiceInput.logPunctuationHintDisplayed(); } @@ -592,6 +592,11 @@ public class LatinIME extends InputMethodService + ", ce=" + candidatesEnd); } + if (mAfterVoiceInput) { + mVoiceInput.setCursorPos(newSelEnd); + mVoiceInput.setSelectionSpan(newSelEnd - newSelStart); + } + mSuggestionShouldReplaceCurrentWord = false; // If the current selection in the text view changes, we should // clear whatever candidate text we have. @@ -997,12 +1002,27 @@ public class LatinIME extends InputMethodService private void handleBackspace() { if (VOICE_INSTALLED && mVoiceInputHighlighted) { + mVoiceInput.incrementTextModificationDeleteCount( + mVoiceResults.candidates.get(0).toString().length()); revertVoiceInput(); return; } boolean deleteChar = false; InputConnection ic = getCurrentInputConnection(); if (ic == null) return; + + if (mAfterVoiceInput) { + // Don't log delete if the user is pressing delete at + // the beginning of the text box (hence not deleting anything) + if (mVoiceInput.getCursorPos() > 0) { + // If anything was selected before the delete was pressed, increment the + // delete count by the length of the selection + int deleteLen = mVoiceInput.getSelectionSpan() > 0 ? + mVoiceInput.getSelectionSpan() : 1; + mVoiceInput.incrementTextModificationDeleteCount(deleteLen); + } + } + if (mPredicting) { final int length = mComposing.length(); if (length > 0) { @@ -1048,6 +1068,12 @@ public class LatinIME extends InputMethodService if (VOICE_INSTALLED && mVoiceInputHighlighted) { commitVoiceInput(); } + + if (mAfterVoiceInput) { + // Assume input length is 1. This assumption fails for smiley face insertions. + mVoiceInput.incrementTextModificationInsertCount(1); + } + if (isAlphabet(primaryCode) && isPredictionOn() && !isCursorTouchingWord()) { if (!mPredicting) { mPredicting = true; @@ -1091,6 +1117,12 @@ public class LatinIME extends InputMethodService if (VOICE_INSTALLED && mVoiceInputHighlighted) { commitVoiceInput(); } + + if (mAfterVoiceInput){ + // Assume input length is 1. This assumption fails for smiley face insertions. + mVoiceInput.incrementTextModificationInsertPunctuationCount(1); + } + boolean pickedDefault = false; // Handle separator InputConnection ic = getCurrentInputConnection(); @@ -1344,7 +1376,7 @@ public class LatinIME extends InputMethodService String bestResult = nBest.get(0).toString(); - mVoiceInput.logVoiceInputDelivered(); + mVoiceInput.logVoiceInputDelivered(bestResult.length()); mHints.registerVoiceResult(bestResult); @@ -1448,6 +1480,12 @@ public class LatinIME extends InputMethodService public void pickSuggestionManually(int index, CharSequence suggestion) { if (mAfterVoiceInput && mShowingVoiceSuggestions) mVoiceInput.logNBestChoose(index); + if (mAfterVoiceInput && !mShowingVoiceSuggestions) { + mVoiceInput.flushAllTextModificationCounters(); + // send this intent AFTER logging any prior aggregated edits. + mVoiceInput.logTextModifiedByChooseSuggestion(suggestion.length()); + } + InputConnection ic = getCurrentInputConnection(); if (ic != null) { ic.beginBatchEdit(); diff --git a/java/src/com/android/inputmethod/voice/VoiceInput.java b/java/src/com/android/inputmethod/voice/VoiceInput.java index e881856dd..72cb2f902 100644 --- a/java/src/com/android/inputmethod/voice/VoiceInput.java +++ b/java/src/com/android/inputmethod/voice/VoiceInput.java @@ -94,6 +94,12 @@ public class VoiceInput implements OnClickListener { public static final int WORKING = 2; public static final int ERROR = 3; + private int mAfterVoiceInputDeleteCount = 0; + private int mAfterVoiceInputInsertCount = 0; + private int mAfterVoiceInputInsertPunctuationCount = 0; + private int mAfterVoiceInputCursorPos = 0; + private int mAfterVoiceInputSelectionSpan = 0; + private int mState = DEFAULT; private final static int MSG_CLOSE_ERROR_DIALOG = 1; @@ -161,6 +167,87 @@ public class VoiceInput implements OnClickListener { mBlacklist.addApp("com.android.setupwizard"); } + public void setCursorPos(int pos) { + mAfterVoiceInputCursorPos = pos; + } + + public int getCursorPos() { + return mAfterVoiceInputCursorPos; + } + + public void setSelectionSpan(int span) { + mAfterVoiceInputSelectionSpan = span; + } + + public int getSelectionSpan() { + return mAfterVoiceInputSelectionSpan; + } + + public void incrementTextModificationDeleteCount(int count){ + mAfterVoiceInputDeleteCount += count; + // Send up intents for other text modification types + if (mAfterVoiceInputInsertCount > 0) { + logTextModifiedByTypingInsertion(mAfterVoiceInputInsertCount); + mAfterVoiceInputInsertCount = 0; + } + if (mAfterVoiceInputInsertPunctuationCount > 0) { + logTextModifiedByTypingInsertionPunctuation(mAfterVoiceInputInsertPunctuationCount); + mAfterVoiceInputInsertPunctuationCount = 0; + } + + } + + public void incrementTextModificationInsertCount(int count){ + mAfterVoiceInputInsertCount += count; + if (mAfterVoiceInputSelectionSpan > 0) { + // If text was highlighted before inserting the char, count this as + // a delete. + mAfterVoiceInputDeleteCount += mAfterVoiceInputSelectionSpan; + } + // Send up intents for other text modification types + if (mAfterVoiceInputDeleteCount > 0) { + logTextModifiedByTypingDeletion(mAfterVoiceInputDeleteCount); + mAfterVoiceInputDeleteCount = 0; + } + if (mAfterVoiceInputInsertPunctuationCount > 0) { + logTextModifiedByTypingInsertionPunctuation(mAfterVoiceInputInsertPunctuationCount); + mAfterVoiceInputInsertPunctuationCount = 0; + } + } + + public void incrementTextModificationInsertPunctuationCount(int count){ + mAfterVoiceInputInsertPunctuationCount += 1; + if (mAfterVoiceInputSelectionSpan > 0) { + // If text was highlighted before inserting the char, count this as + // a delete. + mAfterVoiceInputDeleteCount += mAfterVoiceInputSelectionSpan; + } + // Send up intents for aggregated non-punctuation insertions + if (mAfterVoiceInputDeleteCount > 0) { + logTextModifiedByTypingDeletion(mAfterVoiceInputDeleteCount); + mAfterVoiceInputDeleteCount = 0; + } + if (mAfterVoiceInputInsertCount > 0) { + logTextModifiedByTypingInsertion(mAfterVoiceInputInsertCount); + mAfterVoiceInputInsertCount = 0; + } + } + + public void flushAllTextModificationCounters() { + if (mAfterVoiceInputInsertCount > 0) { + logTextModifiedByTypingInsertion(mAfterVoiceInputInsertCount); + mAfterVoiceInputInsertCount = 0; + } + if (mAfterVoiceInputDeleteCount > 0) { + logTextModifiedByTypingDeletion(mAfterVoiceInputDeleteCount); + mAfterVoiceInputDeleteCount = 0; + } + if (mAfterVoiceInputInsertPunctuationCount > 0) { + logTextModifiedByTypingInsertionPunctuation(mAfterVoiceInputInsertPunctuationCount); + mAfterVoiceInputInsertPunctuationCount = 0; + } + } + /** * The configuration of the IME changed and may have caused the views to be layed out * again. Restore the state of the recognition view. @@ -302,8 +389,20 @@ public class VoiceInput implements OnClickListener { } } - public void logTextModified() { - mLogger.textModified(); + public void logTextModifiedByTypingInsertion(int length) { + mLogger.textModifiedByTypingInsertion(length); + } + + public void logTextModifiedByTypingInsertionPunctuation(int length) { + mLogger.textModifiedByTypingInsertionPunctuation(length); + } + + public void logTextModifiedByTypingDeletion(int length) { + mLogger.textModifiedByTypingDeletion(length); + } + + public void logTextModifiedByChooseSuggestion(int length) { + mLogger.textModifiedByChooseSuggestion(length); } public void logKeyboardWarningDialogShown() { @@ -330,8 +429,8 @@ public class VoiceInput implements OnClickListener { mLogger.punctuationHintDisplayed(); } - public void logVoiceInputDelivered() { - mLogger.voiceInputDelivered(); + public void logVoiceInputDelivered(int length) { + mLogger.voiceInputDelivered(length); } public void logNBestChoose(int index) { diff --git a/java/src/com/android/inputmethod/voice/VoiceInputLogger.java b/java/src/com/android/inputmethod/voice/VoiceInputLogger.java index 659033340..9d3a92037 100644 --- a/java/src/com/android/inputmethod/voice/VoiceInputLogger.java +++ b/java/src/com/android/inputmethod/voice/VoiceInputLogger.java @@ -147,12 +147,43 @@ public class VoiceInputLogger { mContext.sendBroadcast(i); } - public void voiceInputDelivered() { - mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.VOICE_INPUT_DELIVERED)); + public void voiceInputDelivered(int length) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.VOICE_INPUT_DELIVERED); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_LENGTH, length); + mContext.sendBroadcast(i); } - public void textModified() { - mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED)); + public void textModifiedByTypingInsertion(int length) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_LENGTH, length); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_TYPE, + LoggingEvents.VoiceIme.TEXT_MODIFIED_TYPE_TYPING_INSERTION); + mContext.sendBroadcast(i); + } + + public void textModifiedByTypingInsertionPunctuation(int length) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_LENGTH, length); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_TYPE, + LoggingEvents.VoiceIme.TEXT_MODIFIED_TYPE_TYPING_INSERTION_PUNCTUATION); + mContext.sendBroadcast(i); + } + + public void textModifiedByTypingDeletion(int length) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_LENGTH, length); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_TYPE, + LoggingEvents.VoiceIme.TEXT_MODIFIED_TYPE_TYPING_DELETION); + + mContext.sendBroadcast(i); + } + + public void textModifiedByChooseSuggestion(int length) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_LENGTH, length); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_TEXT_MODIFIED_TYPE, + LoggingEvents.VoiceIme.TEXT_MODIFIED_TYPE_CHOOSE_SUGGESTION); + mContext.sendBroadcast(i); } public void nBestChoose(int index) {