From 6f7218627eda110a8454053f8ecb7b80edfdc8ce Mon Sep 17 00:00:00 2001 From: satok Date: Wed, 19 Jan 2011 17:29:27 +0900 Subject: Dim previously suggested words Change-Id: Id673c03bfa22ea9ce1bedb5174d8309a37a2a460 --- java/src/com/android/inputmethod/voice/VoiceIMEConnector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'java/src/com/android/inputmethod/voice/VoiceIMEConnector.java') diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java index a02dbcb55..6c9b7d527 100644 --- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java +++ b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java @@ -437,7 +437,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { builder.addWord(word); } } else { - builder.addWords(suggestions); + builder.addWords(suggestions, null); } builder.setTypedWordValid(true).setHasMinimalSuggestion(true); mService.setSuggestions(builder.build()); -- cgit v1.2.3-83-g751a From 8cacb024cf400241f9885cccee782c286cbf1330 Mon Sep 17 00:00:00 2001 From: satok Date: Mon, 24 Jan 2011 17:38:49 +0900 Subject: Set minimum height for RecognitionView in the case that there is no keyboard view loaded. Bug: 3352322 Change-Id: I9a7b2a745b47bdc62a96a5cd2c0d8ad717e1b406 --- java/res/layout/recognition_status.xml | 2 +- java/src/com/android/inputmethod/latin/SubtypeSwitcher.java | 2 +- .../com/android/inputmethod/voice/VoiceIMEConnector.java | 13 +++++++++---- 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'java/src/com/android/inputmethod/voice/VoiceIMEConnector.java') diff --git a/java/res/layout/recognition_status.xml b/java/res/layout/recognition_status.xml index b2c9f4a51..b00432f0c 100644 --- a/java/res/layout/recognition_status.xml +++ b/java/res/layout/recognition_status.xml @@ -26,7 +26,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/popup_layout" android:orientation="vertical" - android:layout_height="0dip" + android:layout_height="371dip" android:layout_width="500dip" android:layout_centerInParent="true" android:background="@drawable/vs_dialog_red"> diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index ffce66e9b..d3aa70c28 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -435,7 +435,7 @@ public class SubtypeSwitcher { mVoiceInput = vi; if (isVoiceMode()) { if (DBG) { - Log.d(TAG, "Set and call voice input."); + Log.d(TAG, "Set and call voice input.: " + getInputLocaleStr()); } triggerVoiceIME(); return true; diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java index 6c9b7d527..a3a3ea88e 100644 --- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java +++ b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java @@ -78,6 +78,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { // given text field. For instance this is specified by the search dialog when the // dialog is already showing a voice search button. private static final String IME_OPTION_NO_MICROPHONE = "nm"; + private static final int RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO = 6; @SuppressWarnings("unused") private static final String TAG = "VoiceIMEConnector"; @@ -543,10 +544,14 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { // As we add mm, we don't know how the rounding is going to work // thus we may end up with few pixels extra (or less). if (keyboardView != null) { - int h = keyboardView.getHeight(); - if (h > 0) { - View popupLayout = v.findViewById(R.id.popup_layout); - popupLayout.getLayoutParams().height = h; + View popupLayout = v.findViewById(R.id.popup_layout); + final int displayHeight = + mService.getResources().getDisplayMetrics().heightPixels; + final int currentHeight = popupLayout.getLayoutParams().height; + final int keyboardHeight = keyboardView.getHeight(); + if (keyboardHeight > currentHeight || keyboardHeight + > (displayHeight / RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO)) { + popupLayout.getLayoutParams().height = keyboardHeight; } } mService.setInputView(v); -- cgit v1.2.3-83-g751a From 760884e027c4c678e6baed9a9857bd3c351abefb Mon Sep 17 00:00:00 2001 From: satok Date: Tue, 25 Jan 2011 20:55:23 +0900 Subject: Hide recognition view when switchToLastInputMethod failed. Change-Id: Ie5f3d267e1042b4379b51c2dc6c8756e394cfc0f --- .../com/android/inputmethod/voice/VoiceIMEConnector.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'java/src/com/android/inputmethod/voice/VoiceIMEConnector.java') diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java index a3a3ea88e..a30570aa2 100644 --- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java +++ b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java @@ -564,8 +564,18 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { } private void switchToLastInputMethod() { - IBinder token = mService.getWindow().getWindow().getAttributes().token; - mImm.switchToLastInputMethod(token); + final IBinder token = mService.getWindow().getWindow().getAttributes().token; + new Thread ("switchToLastInputMethod") { + @Override + public void run() { + if (!mImm.switchToLastInputMethod(token)) { + // Needs to reset here because LatinIME failed to back to any IME and + // the same voice subtype will be triggered in the next time. + mVoiceInput.reset(); + mService.requestHideSelf(0); + } + } + }.start(); } private void reallyStartListening(boolean swipe) { -- cgit v1.2.3-83-g751a From a42cc5303bae29a32ac87d907a6dc41c3b6a95a6 Mon Sep 17 00:00:00 2001 From: satok Date: Wed, 26 Jan 2011 22:04:21 +0900 Subject: If there is no keyboard view attached, use voice input view. Change-Id: Ibf0945f3bd70f02fe0d09229fc899641567c0d4c --- .../inputmethod/voice/VoiceIMEConnector.java | 29 ++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'java/src/com/android/inputmethod/voice/VoiceIMEConnector.java') diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java index a30570aa2..61a194a8d 100644 --- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java +++ b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java @@ -20,6 +20,7 @@ import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.latin.EditingUtils; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinIME.UIHandler; +import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SharedPreferencesCompat; import com.android.inputmethod.latin.SubtypeSwitcher; @@ -32,6 +33,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; import android.net.Uri; +import android.os.AsyncTask; import android.os.IBinder; import android.preference.PreferenceManager; import android.provider.Browser; @@ -43,6 +45,7 @@ import android.text.TextUtils; import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; import android.text.style.URLSpan; +import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -82,6 +85,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { @SuppressWarnings("unused") private static final String TAG = "VoiceIMEConnector"; + private static boolean DEBUG = LatinImeLogger.sDBG; private boolean mAfterVoiceInput; private boolean mHasUsedVoiceInput; @@ -565,17 +569,25 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { private void switchToLastInputMethod() { final IBinder token = mService.getWindow().getWindow().getAttributes().token; - new Thread ("switchToLastInputMethod") { + new AsyncTask() { @Override - public void run() { - if (!mImm.switchToLastInputMethod(token)) { + protected Boolean doInBackground(Void... params) { + return mImm.switchToLastInputMethod(token); + } + + @Override + protected void onPostExecute(Boolean result) { + if (!result) { + if (DEBUG) { + Log.d(TAG, "Couldn't switch back to last IME."); + } // Needs to reset here because LatinIME failed to back to any IME and // the same voice subtype will be triggered in the next time. mVoiceInput.reset(); mService.requestHideSelf(0); } } - }.start(); + }.execute(); } private void reallyStartListening(boolean swipe) { @@ -658,14 +670,17 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { } } - public void onStartInputView(IBinder token) { + public void onStartInputView(IBinder keyboardViewToken) { + // If keyboardViewToken is null, keyboardView is not attached but voiceView is attached. + IBinder windowToken = keyboardViewToken != null ? keyboardViewToken + : mVoiceInput.getView().getWindowToken(); // If IME is in voice mode, but still needs to show the voice warning dialog, // keep showing the warning. - if (mSubtypeSwitcher.isVoiceMode() && token != null) { + if (mSubtypeSwitcher.isVoiceMode() && windowToken != null) { // Close keyboard view if it is been shown. if (KeyboardSwitcher.getInstance().isInputViewShown()) KeyboardSwitcher.getInstance().getInputView().purgeKeyboardAndClosing(); - startListening(false, token); + startListening(false, windowToken); } // If we have no token, onAttachedToWindow will take care of showing dialog and start // listening. -- cgit v1.2.3-83-g751a From 34252baa8622878f2c28858a16508978da3fcdcb Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Tue, 1 Feb 2011 14:03:12 +0900 Subject: Use custom dialog builder building url link clickable from service This change is derived from I7611ebc1 (Honeycomb). Bug: 3246715 Change-Id: I6446bd785f1bd3d7b901e86661c91ca5a823f30e --- .../inputmethod/voice/VoiceIMEConnector.java | 130 +++++++++------------ 1 file changed, 58 insertions(+), 72 deletions(-) (limited to 'java/src/com/android/inputmethod/voice/VoiceIMEConnector.java') diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java index 61a194a8d..4ceaa1bb9 100644 --- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java +++ b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java @@ -38,16 +38,13 @@ import android.os.IBinder; import android.preference.PreferenceManager; import android.provider.Browser; import android.speech.SpeechRecognizer; -import android.text.Layout; -import android.text.Selection; -import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.Spanned; import android.text.TextUtils; import android.text.method.LinkMovementMethod; -import android.text.style.ClickableSpan; import android.text.style.URLSpan; import android.util.Log; import android.view.LayoutInflater; -import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; @@ -83,8 +80,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { private static final String IME_OPTION_NO_MICROPHONE = "nm"; private static final int RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO = 6; - @SuppressWarnings("unused") - private static final String TAG = "VoiceIMEConnector"; + private static final String TAG = VoiceIMEConnector.class.getSimpleName(); private static boolean DEBUG = LatinImeLogger.sDBG; private boolean mAfterVoiceInput; @@ -177,7 +173,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { if (mVoiceWarningDialog != null && mVoiceWarningDialog.isShowing()) { return; } - AlertDialog.Builder builder = new AlertDialog.Builder(mService); + AlertDialog.Builder builder = new UrlLinkAlertDialogBuilder(mService); builder.setCancelable(true); builder.setIcon(R.drawable.ic_mic_dialog); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @@ -215,90 +211,80 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { mService.getText(R.string.voice_warning_how_to_turn_off)); } builder.setMessage(message); - builder.setTitle(R.string.voice_warning_title); mVoiceWarningDialog = builder.create(); - Window window = mVoiceWarningDialog.getWindow(); - WindowManager.LayoutParams lp = window.getAttributes(); + final Window window = mVoiceWarningDialog.getWindow(); + final WindowManager.LayoutParams lp = window.getAttributes(); lp.token = token; lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; window.setAttributes(lp); window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); mVoiceInput.logKeyboardWarningDialogShown(); mVoiceWarningDialog.show(); - // Make URL in the dialog message clickable - TextView textView = (TextView) mVoiceWarningDialog.findViewById(android.R.id.message); - if (textView != null) { - final CustomLinkMovementMethod method = CustomLinkMovementMethod.getInstance(); - method.setVoiceWarningDialog(mVoiceWarningDialog); - textView.setMovementMethod(method); - } } - private static class CustomLinkMovementMethod extends LinkMovementMethod { - private static CustomLinkMovementMethod sLinkMovementMethodInstance = - new CustomLinkMovementMethod(); + private static class UrlLinkAlertDialogBuilder extends AlertDialog.Builder { private AlertDialog mAlertDialog; - public void setVoiceWarningDialog(AlertDialog alertDialog) { - mAlertDialog = alertDialog; + public UrlLinkAlertDialogBuilder(Context context) { + super(context); } - public static CustomLinkMovementMethod getInstance() { - return sLinkMovementMethodInstance; + @Override + public AlertDialog.Builder setMessage(CharSequence message) { + return super.setMessage(replaceURLSpan(message)); + } + + private Spanned replaceURLSpan(CharSequence message) { + // Replace all spans with the custom span + final SpannableStringBuilder ssb = new SpannableStringBuilder(message); + for (URLSpan span : ssb.getSpans(0, ssb.length(), URLSpan.class)) { + int spanStart = ssb.getSpanStart(span); + int spanEnd = ssb.getSpanEnd(span); + int spanFlags = ssb.getSpanFlags(span); + ssb.removeSpan(span); + ssb.setSpan(new ClickableSpan(span.getURL()), spanStart, spanEnd, spanFlags); + } + return ssb; } - // Almost the same as LinkMovementMethod.onTouchEvent(), but overrides it for - // FLAG_ACTIVITY_NEW_TASK and mAlertDialog.cancel(). @Override - public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { - int action = event.getAction(); - - if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { - int x = (int) event.getX(); - int y = (int) event.getY(); - - x -= widget.getTotalPaddingLeft(); - y -= widget.getTotalPaddingTop(); - - x += widget.getScrollX(); - y += widget.getScrollY(); - - Layout layout = widget.getLayout(); - int line = layout.getLineForVertical(y); - int off = layout.getOffsetForHorizontal(line, x); - - ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); - - if (link.length != 0) { - if (action == MotionEvent.ACTION_UP) { - if (link[0] instanceof URLSpan) { - URLSpan urlSpan = (URLSpan) link[0]; - Uri uri = Uri.parse(urlSpan.getURL()); - Context context = widget.getContext(); - Intent intent = new Intent(Intent.ACTION_VIEW, uri); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()); - if (mAlertDialog != null) { - // Go back to the previous IME for now. - // TODO: If we can find a way to bring the new activity to front - // while keeping the warning dialog, we don't need to cancel here. - mAlertDialog.cancel(); - } - context.startActivity(intent); - } else { - link[0].onClick(widget); - } - } else if (action == MotionEvent.ACTION_DOWN) { - Selection.setSelection(buffer, buffer.getSpanStart(link[0]), - buffer.getSpanEnd(link[0])); + public AlertDialog create() { + final AlertDialog dialog = super.create(); + + dialog.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface dialogInterface) { + // Make URL in the dialog message click-able. + TextView textView = (TextView) mAlertDialog.findViewById(android.R.id.message); + if (textView != null) { + textView.setMovementMethod(LinkMovementMethod.getInstance()); } - return true; - } else { - Selection.removeSelection(buffer); } + }); + mAlertDialog = dialog; + return dialog; + } + + class ClickableSpan extends URLSpan { + public ClickableSpan(String url) { + super(url); + } + + @Override + public void onClick(View widget) { + Uri uri = Uri.parse(getURL()); + Context context = widget.getContext(); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + // Add this flag to start an activity from service + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()); + // Dismiss the warning dialog and go back to the previous IME. + // TODO: If we can find a way to bring the new activity to front while keeping + // the warning dialog, we don't need to dismiss it here. + mAlertDialog.cancel(); + context.startActivity(intent); } - return super.onTouchEvent(widget, buffer, event); } } -- cgit v1.2.3-83-g751a From c98a943edaf03bb114172b31b041b0a6b952c043 Mon Sep 17 00:00:00 2001 From: satok Date: Fri, 4 Feb 2011 17:05:07 +0900 Subject: Duplicate enabled languages when there is only one enabled language Bug: 3415274 Change-Id: Ibc17733be888044cfa5d1787b8489e642d70d70f --- java/src/com/android/inputmethod/latin/SubtypeSwitcher.java | 9 ++++++++- java/src/com/android/inputmethod/voice/VoiceIMEConnector.java | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'java/src/com/android/inputmethod/voice/VoiceIMEConnector.java') diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index f4262cc99..d8c89a0d4 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -426,8 +426,15 @@ public class SubtypeSwitcher { if (mConfigUseSpacebarLanguageSwitcher) { return mLanguageSwitcher.getEnabledLanguages(); } else { + int enabledLanguageCount = mEnabledLanguagesOfCurrentInputMethod.size(); + // Workaround for explicitly specifying the voice language + if (enabledLanguageCount == 1) { + mEnabledLanguagesOfCurrentInputMethod.add( + mEnabledLanguagesOfCurrentInputMethod.get(0)); + ++enabledLanguageCount; + } return mEnabledLanguagesOfCurrentInputMethod.toArray( - new String[mEnabledLanguagesOfCurrentInputMethod.size()]); + new String[enabledLanguageCount]); } } diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java index 4ceaa1bb9..277ef7e65 100644 --- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java +++ b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java @@ -81,7 +81,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { private static final int RECOGNITIONVIEW_HEIGHT_THRESHOLD_RATIO = 6; private static final String TAG = VoiceIMEConnector.class.getSimpleName(); - private static boolean DEBUG = LatinImeLogger.sDBG; + private static final boolean DEBUG = LatinImeLogger.sDBG; private boolean mAfterVoiceInput; private boolean mHasUsedVoiceInput; @@ -715,7 +715,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { mHandler.updateVoiceResults(); } - public FieldContext makeFieldContext() { + private FieldContext makeFieldContext() { SubtypeSwitcher switcher = SubtypeSwitcher.getInstance(); return new FieldContext(mService.getCurrentInputConnection(), mService.getCurrentInputEditorInfo(), switcher.getInputLocaleStr(), -- cgit v1.2.3-83-g751a