From e276d8ddaaff91d5940a71cefb5ecd94fd48ba98 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Fri, 14 Jan 2011 16:12:36 +0900 Subject: [PATCH 01/28] Add SubtypeLocale class Change-Id: Ic4c73c313f976ad6df1b4ddf48b914d05a08d283 --- java/res/values/donottranslate.xml | 10 ++++ .../inputmethod/latin/SubtypeLocale.java | 46 +++++++++++++++++++ .../inputmethod/latin/SubtypeSwitcher.java | 5 +- 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 java/src/com/android/inputmethod/latin/SubtypeLocale.java diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml index 8dc212279..6a1069e99 100644 --- a/java/res/values/donottranslate.xml +++ b/java/res/values/donottranslate.xml @@ -138,4 +138,14 @@ 4 5 + + + + en_US + en_GB + + + English (US) + English (UK) + diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java new file mode 100644 index 000000000..917521c40 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011 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.content.Context; +import android.content.res.Resources; + +import java.util.Locale; + +public class SubtypeLocale { + private static String[] sExceptionKeys; + private static String[] sExceptionValues; + + private SubtypeLocale() { + // Intentional empty constructor for utility class. + } + + public static void init(Context context) { + final Resources res = context.getResources(); + sExceptionKeys = res.getStringArray(R.array.subtype_locale_exception_keys); + sExceptionValues = res.getStringArray(R.array.subtype_locale_exception_values); + } + + public static String getFullDisplayName(Locale locale) { + String localeCode = locale.toString(); + for (int index = 0; index < sExceptionKeys.length; index++) { + if (sExceptionKeys[index].equals(localeCode)) + return sExceptionValues[index]; + } + return locale.getDisplayName(locale); + } +} diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index d696834e9..f75e2953e 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -16,7 +16,6 @@ package com.android.inputmethod.latin; -import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.voice.SettingsUtil; import com.android.inputmethod.voice.VoiceIMEConnector; @@ -90,6 +89,8 @@ public class SubtypeSwitcher { } sInstance.updateAllParameters(); + + SubtypeLocale.init(service); } private SubtypeSwitcher() { @@ -445,7 +446,7 @@ public class SubtypeSwitcher { public static String getFullDisplayName(Locale locale, boolean returnsNameInThisLocale) { if (returnsNameInThisLocale) { - return toTitleCase(locale.getDisplayName(locale)); + return toTitleCase(SubtypeLocale.getFullDisplayName(locale)); } else { return toTitleCase(locale.getDisplayName()); } From 297d6619b3fd450e6e300de6bda4b537068ff2fe Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Fri, 14 Jan 2011 18:29:35 +0900 Subject: [PATCH 02/28] Add CHAR LIMIT to string resources Bug: 2988183 Bug: 3276544 Change-Id: Ib5c2c86972b1ab32468cd0ab9370ec629255c54d --- java/res/values/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml index 22040d591..6f0f2fb72 100644 --- a/java/res/values/strings.xml +++ b/java/res/values/strings.xml @@ -22,7 +22,7 @@ Android keyboard Android keyboard settings - + Input options @@ -111,15 +111,15 @@ Voice input is not currently supported for your language, but does work in English. + the first time, or turns it on in settings. [CHAR LIMIT=200] --> Voice input uses Google\'s speech recognition. The Mobile Privacy Policy applies. + actually initiates voice input, rather than just turning it on in settings. [CHAR LIMIT=200] --> To turn off voice input, go to input method settings. + "Press the microphone button"). [CHAR LIMIT=100] --> To use voice input, press the microphone button. From de0c8874a4eb1250e8439d9e4e1badca88316670 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Wed, 12 Jan 2011 20:33:54 +0900 Subject: [PATCH 03/28] Notify keyboard language on space bar when it has changed This change also introduces the following. * space bar language switcher is enabled for phone device. * get rid of spcae key icon from number keyboard of tablet. * slightly lower the position of language name on space bar of tablet. Bug: 3290290 Change-Id: I432be8f757bcc84c257770112ff1f6fa7970c584 --- java/res/values-xlarge/config.xml | 3 + java/res/values/config.xml | 4 ++ java/res/xml-xlarge/kbd_key_styles.xml | 3 - java/res/xml-xlarge/kbd_numkey_styles.xml | 2 - .../keyboard/KeyboardSwitcher.java | 21 ++++-- .../inputmethod/keyboard/KeyboardView.java | 3 +- .../inputmethod/keyboard/LatinKeyboard.java | 55 ++++++++++------ .../keyboard/LatinKeyboardView.java | 8 +++ .../android/inputmethod/latin/LatinIME.java | 56 +++++++++++----- .../inputmethod/latin/SubtypeSwitcher.java | 65 +++++++------------ 10 files changed, 135 insertions(+), 85 deletions(-) diff --git a/java/res/values-xlarge/config.xml b/java/res/values-xlarge/config.xml index 56b9a166f..410b5e19e 100644 --- a/java/res/values-xlarge/config.xml +++ b/java/res/values-xlarge/config.xml @@ -28,6 +28,9 @@ false false + false + + 1200 5 medium diff --git a/java/res/values/config.xml b/java/res/values/config.xml index 63af9a9ba..adfec4c25 100644 --- a/java/res/values/config.xml +++ b/java/res/values/config.xml @@ -31,6 +31,10 @@ true true + true + + -1 + 50 0 10 0 diff --git a/java/res/xml-xlarge/kbd_key_styles.xml b/java/res/xml-xlarge/kbd_key_styles.xml index c6b785896..efbad5bab 100644 --- a/java/res/xml-xlarge/kbd_key_styles.xml +++ b/java/res/xml-xlarge/kbd_key_styles.xml @@ -57,7 +57,6 @@ diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 331c8db6a..25ef847cd 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -157,7 +157,14 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha boolean voiceButtonOnPrimary) { mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA; try { + if (mInputView == null) return; + final Keyboard oldKeyboard = mInputView.getKeyboard(); loadKeyboardInternal(mode, imeOptions, voiceKeyEnabled, voiceButtonOnPrimary, false); + final Keyboard newKeyboard = mInputView.getKeyboard(); + if (newKeyboard.isAlphaKeyboard() && (oldKeyboard == null + || !newKeyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale))) { + mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(); + } } catch (RuntimeException e) { Log.w(TAG, e); LatinImeLogger.logOnException(mode + "," + imeOptions, e); @@ -167,6 +174,11 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha private void loadKeyboardInternal(int mode, int imeOptions, boolean voiceButtonEnabled, boolean voiceButtonOnPrimary, boolean isSymbols) { if (mInputView == null) return; + final Keyboard oldKeyboard = mInputView.getKeyboard(); + final KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols); + if (oldKeyboard != null && oldKeyboard.mId.equals(id)) + return; + mInputView.setPreviewEnabled(mInputMethodService.getPopupOn()); mMode = mode; @@ -178,11 +190,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha mHasSettingsKey = getSettingsKeyMode(mPrefs, mInputMethodService); makeSymbolsKeyboardIds(); - KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols); - LatinKeyboard keyboard = getKeyboard(id); - mCurrentId = id; - mInputView.setKeyboard(keyboard); + mInputView.setKeyboard(getKeyboard(id)); } private LatinKeyboard getKeyboard(KeyboardId id) { @@ -210,6 +219,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha keyboard.onAutoCorrectionStateChanged(mIsAutoCorrectionActive); keyboard.setShifted(false); + // If the cached keyboard had been switched to another keyboard while the language was + // displayed on its spacebar, it might have had arbitrary text fade factor. In such case, + // we should reset the text fade factor. + keyboard.setSpacebarTextFadeFactor(0.0f, null); return keyboard; } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index e7dd716fb..a952acf8b 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -912,9 +912,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { // We should re-draw popup preview when 1) we need to hide the preview, 2) we will show // the space key preview and 3) pointer moves off the space key to other letter key, we // should hide the preview of the previous key. - @SuppressWarnings("unused") final boolean hidePreviewOrShowSpaceKeyPreview = (tracker == null) - || (SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER + || (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher() && SubtypeSwitcher.getInstance().needsToDisplayLanguage() && (tracker.isSpaceKey(keyIndex) || tracker.isSpaceKey(oldKeyIndex))); // If key changed and preview is on or the key is space (language switch is enabled) diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java index 77dde8d1b..db8934049 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java @@ -24,6 +24,7 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.PorterDuff; @@ -47,7 +48,9 @@ public class LatinKeyboard extends Keyboard { private final Drawable mSpaceAutoCorrectionIndicator; private final Drawable mButtonArrowLeftIcon; private final Drawable mButtonArrowRightIcon; - private final int mSpaceBarTextShadowColor; + private final int mSpacebarTextColor; + private final int mSpacebarTextShadowColor; + private float mSpacebarTextFadeFactor = 0.0f; private final int[] mSpaceKeyIndexArray; private int mSpaceDragStartX; private int mSpaceDragLastDiff; @@ -67,6 +70,7 @@ public class LatinKeyboard extends Keyboard { private static final float SPACEBAR_POPUP_MIN_RATIO = 0.4f; // Height in space key the language name will be drawn. (proportional to space key height) public static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f; + private static final float SPACEBAR_LANGUAGE_BASELINE_WITHOUT_ICON = 0.65f; // If the full language name needs to be smaller than this value to be drawn on space key, // its short language name will be used instead. private static final float MINIMUM_SCALE_OF_LANGUAGE_NAME = 0.8f; @@ -80,11 +84,12 @@ public class LatinKeyboard extends Keyboard { super(context, id.getXmlId(), id); final Resources res = context.getResources(); mContext = context; + mSpacebarTextColor = res.getColor(R.color.latinkeyboard_bar_language_text); if (id.mColorScheme == KeyboardView.COLOR_SCHEME_BLACK) { - mSpaceBarTextShadowColor = res.getColor( + mSpacebarTextShadowColor = res.getColor( R.color.latinkeyboard_bar_language_shadow_black); } else { // default color scheme is KeyboardView.COLOR_SCHEME_WHITE - mSpaceBarTextShadowColor = res.getColor( + mSpacebarTextShadowColor = res.getColor( R.color.latinkeyboard_bar_language_shadow_white); } mSpaceAutoCorrectionIndicator = res.getDrawable(R.drawable.sym_keyboard_space_led); @@ -96,25 +101,38 @@ public class LatinKeyboard extends Keyboard { mSpaceKeyIndexArray = new int[] { indexOf(CODE_SPACE) }; } + public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboardView view) { + mSpacebarTextFadeFactor = fadeFactor; + updateSpacebarForLocale(false); + if (view != null) + view.invalidateKey(mSpaceKey); + } + + private static int getSpacebarTextColor(int color, float fadeFactor) { + final int newColor = Color.argb((int)(Color.alpha(color) * fadeFactor), + Color.red(color), Color.green(color), Color.blue(color)); + return newColor; + } + /** * @return a key which should be invalidated. */ public Key onAutoCorrectionStateChanged(boolean isAutoCorrection) { - updateSpaceBarForLocale(isAutoCorrection); + updateSpacebarForLocale(isAutoCorrection); return mSpaceKey; } - private void updateSpaceBarForLocale(boolean isAutoCorrection) { + private void updateSpacebarForLocale(boolean isAutoCorrection) { final Resources res = mContext.getResources(); // If application locales are explicitly selected. if (SubtypeSwitcher.getInstance().needsToDisplayLanguage()) { mSpaceKey.setIcon(new BitmapDrawable(res, - drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCorrection))); + drawSpacebar(OPACITY_FULLY_OPAQUE, isAutoCorrection))); } else { // sym_keyboard_space_led can be shared with Black and White symbol themes. if (isAutoCorrection) { mSpaceKey.setIcon(new BitmapDrawable(res, - drawSpaceBar(OPACITY_FULLY_OPAQUE, isAutoCorrection))); + drawSpacebar(OPACITY_FULLY_OPAQUE, isAutoCorrection))); } else { mSpaceKey.setIcon(mSpaceIcon); } @@ -128,8 +146,8 @@ public class LatinKeyboard extends Keyboard { return bounds.width(); } - // Layout local language name and left and right arrow on space bar. - private static String layoutSpaceBar(Paint paint, Locale locale, Drawable lArrow, + // Layout local language name and left and right arrow on spacebar. + private static String layoutSpacebar(Paint paint, Locale locale, Drawable lArrow, Drawable rArrow, int width, int height, float origTextSize, boolean allowVariableTextSize) { final float arrowWidth = lArrow.getIntrinsicWidth(); @@ -138,7 +156,7 @@ public class LatinKeyboard extends Keyboard { final Rect bounds = new Rect(); // Estimate appropriate language name text size to fit in maxTextWidth. - String language = SubtypeSwitcher.getDisplayLanguage(locale); + String language = SubtypeSwitcher.getFullDisplayName(locale, true); int textWidth = getTextWidth(paint, language, origTextSize, bounds); // Assuming text width and text size are proportional to each other. float textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f); @@ -171,8 +189,7 @@ public class LatinKeyboard extends Keyboard { return language; } - @SuppressWarnings("unused") - private Bitmap drawSpaceBar(int opacity, boolean isAutoCorrection) { + private Bitmap drawSpacebar(int opacity, boolean isAutoCorrection) { final int width = mSpaceKey.mWidth; final int height = mSpaceIcon != null ? mSpaceIcon.getIntrinsicHeight() : mSpaceKey.mHeight; final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); @@ -202,21 +219,22 @@ public class LatinKeyboard extends Keyboard { } final boolean allowVariableTextSize = true; - final String language = layoutSpaceBar(paint, subtypeSwitcher.getInputLocale(), + final String language = layoutSpacebar(paint, subtypeSwitcher.getInputLocale(), mButtonArrowLeftIcon, mButtonArrowRightIcon, width, height, getTextSizeFromTheme(textStyle, defaultTextSize), allowVariableTextSize); // Draw language text with shadow - final float baseline = height * SPACEBAR_LANGUAGE_BASELINE; + final float baseline = height * (mSpaceIcon != null ? SPACEBAR_LANGUAGE_BASELINE + : SPACEBAR_LANGUAGE_BASELINE_WITHOUT_ICON); final float descent = paint.descent(); - paint.setColor(mSpaceBarTextShadowColor); + paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, mSpacebarTextFadeFactor)); canvas.drawText(language, width / 2, baseline - descent - 1, paint); - paint.setColor(res.getColor(R.color.latinkeyboard_bar_language_text)); + paint.setColor(getSpacebarTextColor(mSpacebarTextColor, mSpacebarTextFadeFactor)); canvas.drawText(language, width / 2, baseline - descent, paint); // Put arrows that are already layed out on either side of the text - if (SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER + if (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher() && subtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) { mButtonArrowLeftIcon.draw(canvas); mButtonArrowRightIcon.draw(canvas); @@ -291,7 +309,6 @@ public class LatinKeyboard extends Keyboard { * switching input languages. */ @Override - @SuppressWarnings("unused") // SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER is constant public boolean isInside(Key key, int pointX, int pointY) { int x = pointX; int y = pointY; @@ -302,7 +319,7 @@ public class LatinKeyboard extends Keyboard { if (code == CODE_DELETE) x -= key.mWidth / 6; } else if (code == CODE_SPACE) { y += LatinKeyboard.sSpacebarVerticalCorrection; - if (SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER + if (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher() && SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() > 1) { if (mCurrentlyInSpace) { int diff = x - mSpaceDragStartX; diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 51bfbf1f9..ef41cb6e4 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -85,6 +85,14 @@ public class LatinKeyboardView extends KeyboardView { } } + public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboard oldKeyboard) { + final LatinKeyboard currentKeyboard = getLatinKeyboard(); + // We should not set text fade factor to the keyboard which does not display the language on + // its spacebar. + if (currentKeyboard != null && currentKeyboard == oldKeyboard) + currentKeyboard.setSpacebarTextFadeFactor(fadeFactor, this); + } + @Override protected boolean onLongPress(Key key) { int primaryCode = key.mCode; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 5e701c1f0..b93b07ffb 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -21,6 +21,7 @@ import com.android.inputmethod.keyboard.KeyboardActionListener; import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.KeyboardView; +import com.android.inputmethod.keyboard.LatinKeyboard; import com.android.inputmethod.keyboard.LatinKeyboardView; import com.android.inputmethod.latin.Utils.RingCharBuffer; import com.android.inputmethod.voice.VoiceIMEConnector; @@ -151,6 +152,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private boolean mAutoCap; private boolean mQuickFixes; private boolean mConfigSwipeDownDismissKeyboardEnabled; + private int mConfigDelayBeforeFadeoutLanguageOnSpacebar; + private int mConfigDurationOfFadeoutLanguageOnSpacebar; private int mCorrectionMode; private int mCommittedLength; @@ -241,9 +244,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private static final int MSG_UPDATE_OLD_SUGGESTIONS = 1; private static final int MSG_UPDATE_SHIFT_STATE = 2; private static final int MSG_VOICE_RESULTS = 3; + private static final int MSG_FADEOUT_LANGUAGE_ON_SPACEBAR = 4; + private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 5; @Override public void handleMessage(Message msg) { + final KeyboardSwitcher switcher = mKeyboardSwitcher; + final LatinKeyboardView inputView = switcher.getInputView(); switch (msg.what) { case MSG_UPDATE_SUGGESTIONS: updateSuggestions(); @@ -252,12 +259,21 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen setOldSuggestions(); break; case MSG_UPDATE_SHIFT_STATE: - mKeyboardSwitcher.updateShiftState(); + switcher.updateShiftState(); break; case MSG_VOICE_RESULTS: mVoiceConnector.handleVoiceResults(preferCapitalization() - || (mKeyboardSwitcher.isAlphabetMode() - && mKeyboardSwitcher.isShiftedOrShiftLocked())); + || (switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked())); + break; + case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR: + if (inputView != null) + inputView.setSpacebarTextFadeFactor(0.5f, (LatinKeyboard)msg.obj); + sendMessageDelayed(obtainMessage(MSG_DISMISS_LANGUAGE_ON_SPACEBAR, msg.obj), + mConfigDurationOfFadeoutLanguageOnSpacebar); + break; + case MSG_DISMISS_LANGUAGE_ON_SPACEBAR: + if (inputView != null) + inputView.setSpacebarTextFadeFactor(0.0f, (LatinKeyboard)msg.obj); break; } } @@ -297,6 +313,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void updateVoiceResults() { sendMessage(obtainMessage(MSG_VOICE_RESULTS)); } + + public void startDisplayLanguageOnSpacebar() { + removeMessages(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR); + removeMessages(MSG_DISMISS_LANGUAGE_ON_SPACEBAR); + final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); + if (inputView != null) { + final LatinKeyboard keyboard = inputView.getLatinKeyboard(); + // The language is never displayed when the delay is zero. + if (mConfigDelayBeforeFadeoutLanguageOnSpacebar != 0) + inputView.setSpacebarTextFadeFactor(1.0f, keyboard); + // The language is always displayed when the delay is negative. + if (mConfigDelayBeforeFadeoutLanguageOnSpacebar > 0) { + sendMessageDelayed(obtainMessage(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR, keyboard), + mConfigDelayBeforeFadeoutLanguageOnSpacebar); + } + } + } } @Override @@ -319,6 +352,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen res.getBoolean(R.bool.default_recorrection_enabled)); mConfigSwipeDownDismissKeyboardEnabled = res.getBoolean( R.bool.config_swipe_down_dismiss_keyboard_enabled); + mConfigDelayBeforeFadeoutLanguageOnSpacebar = res.getInteger( + R.integer.config_delay_before_fadeout_language_on_spacebar); + mConfigDurationOfFadeoutLanguageOnSpacebar = res.getInteger( + R.integer.config_duration_of_fadeout_language_on_spacebar); Utils.GCUtils.getInstance().reset(); boolean tryGC = true; @@ -401,23 +438,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void onConfigurationChanged(Configuration conf) { - mSubtypeSwitcher.onConfigurationChanged(conf); - if (mSubtypeSwitcher.isKeyboardMode()) - onKeyboardLanguageChanged(); - updateAutoTextEnabled(); - // If orientation changed while predicting, commit the change if (conf.orientation != mOrientation) { InputConnection ic = getCurrentInputConnection(); commitTyped(ic); if (ic != null) ic.finishComposingText(); // For voice input mOrientation = conf.orientation; - final int mode = mKeyboardSwitcher.getKeyboardMode(); - final EditorInfo attribute = getCurrentInputEditorInfo(); - final int imeOptions = (attribute != null) ? attribute.imeOptions : 0; - mKeyboardSwitcher.loadKeyboard(mode, imeOptions, - mVoiceConnector.isVoiceButtonEnabled(), - mVoiceConnector.isVoiceButtonOnPrimary()); } mConfigurationChanging = true; @@ -1817,7 +1843,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER. private void toggleLanguage(boolean reset, boolean next) { - if (SubtypeSwitcher.USE_SPACEBAR_LANGUAGE_SWITCHER) { + if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) { mSubtypeSwitcher.toggleLanguage(reset, next); } // Reload keyboard because the current language has been changed. diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index e1852b2ad..91044685e 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -41,10 +41,6 @@ import java.util.Locale; import java.util.Map; public class SubtypeSwitcher { - // TODO: This should be configurable by resource - // This flag indicates if we support language switching by swipe on space bar. - // We may or may not draw the current language on space bar regardless of this flag. - public static final boolean USE_SPACEBAR_LANGUAGE_SWITCHER = false; private static final boolean DBG = false; private static final String TAG = "SubtypeSwitcher"; @@ -63,6 +59,8 @@ public class SubtypeSwitcher { new ArrayList(); private final ArrayList mEnabledLanguagesOfCurrentInputMethod = new ArrayList(); + private boolean mConfigUseSpacebarLanguageSwitcher; + /*-----------------------------------------------------------*/ // Variants which should be changed only by reload functions. private boolean mNeedsToDisplayLanguage; @@ -84,10 +82,6 @@ public class SubtypeSwitcher { public static void init(LatinIME service, SharedPreferences prefs) { sInstance.mPrefs = prefs; sInstance.resetParams(service); - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { - sInstance.initLanguageSwitcher(service); - } - sInstance.updateAllParameters(); } @@ -109,6 +103,10 @@ public class SubtypeSwitcher { mAllEnabledSubtypesOfCurrentInputMethod = null; // TODO: Voice input should be created here mVoiceInput = null; + mConfigUseSpacebarLanguageSwitcher = mResources.getBoolean( + R.bool.config_use_spacebar_language_switcher); + if (mConfigUseSpacebarLanguageSwitcher) + initLanguageSwitcher(service); } // Update all parameters stored in SubtypeSwitcher. @@ -122,8 +120,8 @@ public class SubtypeSwitcher { // Update parameters which are changed outside LatinIME. This parameters affect UI so they // should be updated every time onStartInputview. public void updateParametersOnStartInputView() { - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { - updateForSpaceBarLanguageSwitch(); + if (mConfigUseSpacebarLanguageSwitcher) { + updateForSpacebarLanguageSwitch(); } else { updateEnabledSubtypes(); } @@ -307,19 +305,23 @@ public class SubtypeSwitcher { ////////////////////////////////// public int getEnabledKeyboardLocaleCount() { - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { + if (mConfigUseSpacebarLanguageSwitcher) { return mLanguageSwitcher.getLocaleCount(); } else { return mEnabledKeyboardSubtypesOfCurrentInputMethod.size(); } } + public boolean useSpacebarLanguageSwitcher() { + return mConfigUseSpacebarLanguageSwitcher; + } + public boolean needsToDisplayLanguage() { return mNeedsToDisplayLanguage; } public Locale getInputLocale() { - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { + if (mConfigUseSpacebarLanguageSwitcher) { return mLanguageSwitcher.getInputLocale(); } else { return mInputLocale; @@ -327,7 +329,7 @@ public class SubtypeSwitcher { } public String getInputLocaleStr() { - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { + if (mConfigUseSpacebarLanguageSwitcher) { String inputLanguage = null; inputLanguage = mLanguageSwitcher.getInputLanguage(); // Should return system locale if there is no Language available. @@ -341,7 +343,7 @@ public class SubtypeSwitcher { } public String[] getEnabledLanguages() { - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { + if (mConfigUseSpacebarLanguageSwitcher) { return mLanguageSwitcher.getEnabledLanguages(); } else { return mEnabledLanguagesOfCurrentInputMethod.toArray( @@ -350,7 +352,7 @@ public class SubtypeSwitcher { } public Locale getSystemLocale() { - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { + if (mConfigUseSpacebarLanguageSwitcher) { return mLanguageSwitcher.getSystemLocale(); } else { return mSystemLocale; @@ -358,7 +360,7 @@ public class SubtypeSwitcher { } public boolean isSystemLanguageSameAsInputLanguage() { - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { + if (mConfigUseSpacebarLanguageSwitcher) { return getSystemLocale().getLanguage().equalsIgnoreCase( getInputLocaleStr().substring(0, 2)); } else { @@ -366,25 +368,8 @@ public class SubtypeSwitcher { } } - public void onConfigurationChanged(Configuration conf) { - final Locale systemLocale = conf.locale; - // If system configuration was changed, update all parameters. - if (!TextUtils.equals(systemLocale.toString(), mSystemLocale.toString())) { - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { - // If the system locale changes and is different from the saved - // locale (mSystemLocale), then reload the input locale list from the - // latin ime settings (shared prefs) and reset the input locale - // to the first one. - mLanguageSwitcher.loadLocales(mPrefs); - mLanguageSwitcher.setSystemLocale(systemLocale); - } else { - updateAllParameters(); - } - } - } - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { + if (mConfigUseSpacebarLanguageSwitcher) { if (Settings.PREF_SELECTED_LANGUAGES.equals(key)) { mLanguageSwitcher.loadLocales(sharedPreferences); } @@ -438,7 +423,7 @@ public class SubtypeSwitcher { } ////////////////////////////////////// - // SpaceBar Language Switch support // + // Spacebar Language Switch support // ////////////////////////////////////// private LanguageSwitcher mLanguageSwitcher; @@ -466,7 +451,7 @@ public class SubtypeSwitcher { return Character.toUpperCase(s.charAt(0)) + s.substring(1); } - private void updateForSpaceBarLanguageSwitch() { + private void updateForSpacebarLanguageSwitch() { // We need to update mNeedsToDisplayLanguage in onStartInputView because // getEnabledKeyboardLocaleCount could have been changed. mNeedsToDisplayLanguage = !(getEnabledKeyboardLocaleCount() <= 1 @@ -479,7 +464,7 @@ public class SubtypeSwitcher { } public String getNextInputLanguageName() { - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { + if (mConfigUseSpacebarLanguageSwitcher) { return getDisplayLanguage(mLanguageSwitcher.getNextInputLocale()); } else { return ""; @@ -487,7 +472,7 @@ public class SubtypeSwitcher { } public String getPreviousInputLanguageName() { - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { + if (mConfigUseSpacebarLanguageSwitcher) { return getDisplayLanguage(mLanguageSwitcher.getPrevInputLocale()); } else { return ""; @@ -524,13 +509,13 @@ public class SubtypeSwitcher { } public void loadSettings() { - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { + if (mConfigUseSpacebarLanguageSwitcher) { mLanguageSwitcher.loadLocales(mPrefs); } } public void toggleLanguage(boolean reset, boolean next) { - if (USE_SPACEBAR_LANGUAGE_SWITCHER) { + if (mConfigUseSpacebarLanguageSwitcher) { if (reset) { mLanguageSwitcher.reset(); } else { From 34cee317d8c475b5200789143723f86ccd7f47da Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Fri, 14 Jan 2011 22:24:10 +0900 Subject: [PATCH 04/28] Fix froyo-ub-LatinImeGoogle compatibility Change-Id: I46fca4735d08552dfb414b2b302b4ed97ae96ab0 --- .../com/android/inputmethod/keyboard/MiniKeyboardBuilder.java | 2 +- java/src/com/android/inputmethod/latin/Settings.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java index 458a9eed4..c150baadb 100644 --- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java +++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java @@ -71,7 +71,7 @@ public class MiniKeyboardBuilder { for (CharSequence popupSpec : popupCharacters) { final CharSequence label = PopupCharactersParser.getLabel(popupSpec.toString()); // If the label is single letter, minKeyWidth is enough to hold the label. - if (label.length() > 1) { + if (label != null && label.length() > 1) { if (paint == null) { paint = new Paint(); paint.setAntiAlias(true); diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index 8efeeda35..064a80fe1 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -182,7 +182,7 @@ public class Settings extends PreferenceActivity if (pref == mInputLanguageSelection) { final String action; if (android.os.Build.VERSION.SDK_INT - >= /* android.os.Build.VERSION_CODES.HONEYCOMB */ 10) { + >= /* android.os.Build.VERSION_CODES.HONEYCOMB */ 11) { action = "android.settings.INPUT_METHOD_AND_SUBTYPE_ENABLER"; } else { action = "com.android.inputmethod.latin.INPUT_LANGUAGE_SELECTION"; From 67e08bb0fb922532d21e9a03c4e1627f62703935 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Sat, 15 Jan 2011 02:26:00 +0900 Subject: [PATCH 05/28] Invoke voice recognition certainly onStartInputView Bug: 3352347 Change-Id: I80763c0a48ebf1ecd23549d78269421ebb40d206 --- .../android/inputmethod/voice/VoiceIMEConnector.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java index d9528eb40..1ac4391f1 100644 --- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java +++ b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java @@ -630,9 +630,15 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { public void onStartInputView(IBinder token) { // If IME is in voice mode, but still needs to show the voice warning dialog, // keep showing the warning. - if (mSubtypeSwitcher.isVoiceMode() && needsToShowWarningDialog() && token != null) { - showVoiceWarningDialog(false, token, false); + if (mSubtypeSwitcher.isVoiceMode() && token != null) { + if (needsToShowWarningDialog()) { + showVoiceWarningDialog(false, token, false); + } else { + startListening(false, token, false); + } } + // If we have no token, onAttachedToWindow will take care of showing dialog and start + // listening. } public void onAttachedToWindow() { From 7e438300db9b36c00597fccb95cbbc9cc5baf029 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Fri, 14 Jan 2011 23:58:15 +0900 Subject: [PATCH 06/28] Add unit test for SubtypeLocale Change-Id: Id0605a64786b96176960b6ea0eb2add2f0c30a64 --- .../inputmethod/latin/SubtypeLocaleTests.java | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java diff --git a/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java b/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java new file mode 100644 index 000000000..004ddb61a --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2011 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.content.Context; +import android.content.res.Resources; +import android.test.AndroidTestCase; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; +import android.view.inputmethod.InputMethodSubtype; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public class SubtypeLocaleTests extends AndroidTestCase { + private static final String PACKAGE = LatinIME.class.getPackage().getName(); + + private Resources mRes; + private List mKeyboardSubtypes; + + public interface Predicator { + public boolean evaluate(T object); + } + + private static List filter(List source, Predicator predicator) { + final ArrayList filtered = new ArrayList(); + for (final T element : source) { + if (predicator.evaluate(element)) + filtered.add(element); + } + return filtered; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + final Context context = getContext(); + mRes = context.getResources(); + + SubtypeLocale.init(context); + + final InputMethodManager imm = (InputMethodManager) context.getSystemService( + Context.INPUT_METHOD_SERVICE); + for (final InputMethodInfo imi : imm.getInputMethodList()) { + if (imi.getPackageName().equals(PACKAGE)) { + mKeyboardSubtypes = filter(imi.getSubtypes(), + new Predicator() { + @Override + public boolean evaluate(InputMethodSubtype ims) { + return ims.getMode().equals("keyboard"); + } + }); + break; + } + } + assertNotNull("Can not find input method " + PACKAGE, mKeyboardSubtypes); + assertTrue("Can not find keyboard subtype", mKeyboardSubtypes.size() > 0); + } + + // Copied from {@link java.junit.Assert#format(String, Object, Object)} + private static String format(String message, Object expected, Object actual) { + return message + " expected:<" + expected + "> but was:<" + actual + ">"; + } + + private String getStringWithLocale(int resId, Locale locale) { + final Locale savedLocale = Locale.getDefault(); + try { + Locale.setDefault(locale); + return mRes.getString(resId); + } finally { + Locale.setDefault(savedLocale); + } + } + + public void testSubtypeLocale() { + for (final InputMethodSubtype subtype : mKeyboardSubtypes) { + final String localeCode = subtype.getLocale(); + final Locale locale = new Locale(localeCode); + // The locale name which will be displayed on spacebar. For example 'English (US)' or + // 'Francais (Canada)'. (c=\u008d) + final String displayName = SubtypeLocale.getFullDisplayName(locale); + // The subtype name in its locale. For example 'English (US) Keyboard' or + // 'Clavier Francais (Canada)'. (c=\u008d) + final String subtypeName = getStringWithLocale(subtype.getNameResId(), locale); + assertTrue( + format("subtype display name of " + localeCode + ":", subtypeName, displayName), + subtypeName.contains(displayName)); + } + } +} From f250c56a3830a8ed848d2f41cf7cc38ff9cacb58 Mon Sep 17 00:00:00 2001 From: satok Date: Mon, 17 Jan 2011 14:46:25 +0900 Subject: [PATCH 07/28] Allow implicitly enabled subtypes in subtype switcher. Change-Id: I30cd9df85fd1927ee9c3bfbe0574167d4953a765 --- java/src/com/android/inputmethod/latin/SubtypeSwitcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index f04f3efe7..968495b8e 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -134,7 +134,7 @@ public class SubtypeSwitcher { private void updateEnabledSubtypes() { boolean foundCurrentSubtypeBecameDisabled = true; mAllEnabledSubtypesOfCurrentInputMethod = mImm.getEnabledInputMethodSubtypeList( - null, false); + null, true); mEnabledLanguagesOfCurrentInputMethod.clear(); mEnabledKeyboardSubtypesOfCurrentInputMethod.clear(); for (InputMethodSubtype ims: mAllEnabledSubtypesOfCurrentInputMethod) { From da50e1e98dadc3733c615dfb8d87fe8b4688c782 Mon Sep 17 00:00:00 2001 From: Ken Wakasa Date: Mon, 17 Jan 2011 15:13:45 +0900 Subject: [PATCH 08/28] Fixes in close() in BinaryDictionary. Avoid using 'synchronized' in finalizer as well. bug: 3340837 Change-Id: I9b28f54e4490ecb844ba33a379f71b625e4246a2 --- .../inputmethod/latin/BinaryDictionary.java | 34 +++++++++++++++---- .../latin/InputLanguageSelection.java | 2 +- .../android/inputmethod/latin/Suggest.java | 8 ++--- ...oid_inputmethod_latin_BinaryDictionary.cpp | 2 +- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index f7e67673a..813f7d32f 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -42,6 +42,7 @@ public class BinaryDictionary extends Dictionary { private static final int TYPED_LETTER_MULTIPLIER = 2; + private static final BinaryDictionary sInstance = new BinaryDictionary(); private int mDicTypeId; private int mNativeDict; private long mDictLength; @@ -59,16 +60,24 @@ public class BinaryDictionary extends Dictionary { } } + private BinaryDictionary() { + } + /** - * Create a dictionary from a raw resource file + * Initialize a dictionary from a raw resource file * @param context application context for reading resources * @param resId the resource containing the raw binary dictionary + * @return initialized instance of BinaryDictionary */ - public BinaryDictionary(Context context, int resId, int dicTypeId) { - if (resId != 0) { - loadDictionary(context, resId); + public static BinaryDictionary initDictionary(Context context, int resId, int dicTypeId) { + synchronized (sInstance) { + sInstance.closeInternal(); + if (resId != 0) { + sInstance.loadDictionary(context, resId); + sInstance.mDicTypeId = dicTypeId; + } } - mDicTypeId = dicTypeId; + return sInstance; } private native int openNative(String sourceDir, long dictOffset, long dictSize, @@ -104,6 +113,8 @@ public class BinaryDictionary extends Dictionary { @Override public void getBigrams(final WordComposer codes, final CharSequence previousWord, final WordCallback callback, int[] nextLettersFrequencies) { + if (mNativeDict == 0) return; + char[] chars = previousWord.toString().toCharArray(); Arrays.fill(mOutputChars_bigrams, (char) 0); Arrays.fill(mFrequencies_bigrams, 0); @@ -135,6 +146,8 @@ public class BinaryDictionary extends Dictionary { @Override public void getWords(final WordComposer codes, final WordCallback callback, int[] nextLettersFrequencies) { + if (mNativeDict == 0) return; + final int codesSize = codes.size(); // Won't deal with really long words. if (codesSize > MAX_WORD_LENGTH - 1) return; @@ -179,6 +192,10 @@ public class BinaryDictionary extends Dictionary { @Override public synchronized void close() { + closeInternal(); + } + + private void closeInternal() { if (mNativeDict != 0) { closeNative(mNativeDict); mNativeDict = 0; @@ -188,7 +205,10 @@ public class BinaryDictionary extends Dictionary { @Override protected void finalize() throws Throwable { - close(); - super.finalize(); + try { + closeInternal(); + } finally { + super.finalize(); + } } } diff --git a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java index faee38eda..a9f2c2c22 100644 --- a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java +++ b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java @@ -107,7 +107,7 @@ public class InputLanguageSelection extends PreferenceActivity { res.updateConfiguration(conf, res.getDisplayMetrics()); int mainDicResId = LatinIME.getMainDictionaryResourceId(res); - BinaryDictionary bd = new BinaryDictionary(this, mainDicResId, Suggest.DIC_MAIN); + BinaryDictionary bd = BinaryDictionary.initDictionary(this, mainDicResId, Suggest.DIC_MAIN); // Is the dictionary larger than a placeholder? Arbitrarily chose a lower limit of // 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words. diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 9ea9c2f3e..a8454b23e 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -103,7 +103,7 @@ public class Suggest implements Dictionary.WordCallback { private int mCorrectionMode = CORRECTION_BASIC; public Suggest(Context context, int dictionaryResId) { - mMainDict = new BinaryDictionary(context, dictionaryResId, DIC_MAIN); + mMainDict = BinaryDictionary.initDictionary(context, dictionaryResId, DIC_MAIN); initPool(); } @@ -127,7 +127,7 @@ public class Suggest implements Dictionary.WordCallback { } public boolean hasMainDictionary() { - return mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD; + return mMainDict != null && mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD; } public int getApproxMaxWordLength() { @@ -276,7 +276,7 @@ public class Suggest implements Dictionary.WordCallback { mHaveCorrection = true; } } - mMainDict.getWords(wordComposer, this, mNextLettersFrequencies); + if (mMainDict != null) mMainDict.getWords(wordComposer, this, mNextLettersFrequencies); if ((mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM) && mSuggestions.size() > 0 && mPriorities.length > 0) { // TODO: when the normalized score of the first suggestion is nearly equals to @@ -496,7 +496,7 @@ public class Suggest implements Dictionary.WordCallback { } public boolean isValidWord(final CharSequence word) { - if (word == null || word.length() == 0) { + if (word == null || word.length() == 0 || mMainDict == null) { return false; } return mMainDict.isValidWord(word) diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp index 6e4e97138..25580f4b1 100644 --- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp +++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp @@ -89,7 +89,7 @@ static jint latinime_BinaryDictionary_open(JNIEnv *env, jobject object, return 0; } dictBuf = malloc(sizeof(char) * dictSize); - if (dictBuf == NULL) { + if (!dictBuf) { LOGE("DICT: Can't allocate memory region for dictionary. errno=%d", errno); return 0; } From 66432cfc9b7680a653bcf19d0d4250db21155ece Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 17 Jan 2011 13:43:51 +0900 Subject: [PATCH 09/28] Place language name at center of spacebar if no space icon This change also leaves the language name as light grayed after fading out. Bug: 3290290 Change-Id: I71adf80c9a3b77d2fd34bca458845d85d55cbee7 --- java/res/values/config.xml | 1 + .../android/inputmethod/keyboard/LatinKeyboard.java | 8 +++++--- java/src/com/android/inputmethod/latin/LatinIME.java | 10 ++++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/java/res/values/config.xml b/java/res/values/config.xml index adfec4c25..11b92e7c3 100644 --- a/java/res/values/config.xml +++ b/java/res/values/config.xml @@ -35,6 +35,7 @@ -1 50 + 15 0 10 0 diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java index db8934049..888375b93 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java @@ -70,7 +70,6 @@ public class LatinKeyboard extends Keyboard { private static final float SPACEBAR_POPUP_MIN_RATIO = 0.4f; // Height in space key the language name will be drawn. (proportional to space key height) public static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f; - private static final float SPACEBAR_LANGUAGE_BASELINE_WITHOUT_ICON = 0.65f; // If the full language name needs to be smaller than this value to be drawn on space key, // its short language name will be used instead. private static final float MINIMUM_SCALE_OF_LANGUAGE_NAME = 0.8f; @@ -225,9 +224,12 @@ public class LatinKeyboard extends Keyboard { allowVariableTextSize); // Draw language text with shadow - final float baseline = height * (mSpaceIcon != null ? SPACEBAR_LANGUAGE_BASELINE - : SPACEBAR_LANGUAGE_BASELINE_WITHOUT_ICON); + // In case there is no space icon, we will place the language text at the center of + // spacebar. final float descent = paint.descent(); + final float textHeight = -paint.ascent() + descent; + final float baseline = (mSpaceIcon != null) ? height * SPACEBAR_LANGUAGE_BASELINE + : height / 2 + textHeight / 2; paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, mSpacebarTextFadeFactor)); canvas.drawText(language, width / 2, baseline - descent - 1, paint); paint.setColor(getSpacebarTextColor(mSpacebarTextColor, mSpacebarTextFadeFactor)); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index b93b07ffb..bea44eef2 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -154,6 +154,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private boolean mConfigSwipeDownDismissKeyboardEnabled; private int mConfigDelayBeforeFadeoutLanguageOnSpacebar; private int mConfigDurationOfFadeoutLanguageOnSpacebar; + private float mConfigFinalFadeoutFactorOfLanugageOnSpacebar; private int mCorrectionMode; private int mCommittedLength; @@ -267,13 +268,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen break; case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR: if (inputView != null) - inputView.setSpacebarTextFadeFactor(0.5f, (LatinKeyboard)msg.obj); + inputView.setSpacebarTextFadeFactor( + (1.0f + mConfigFinalFadeoutFactorOfLanugageOnSpacebar) / 2, + (LatinKeyboard)msg.obj); sendMessageDelayed(obtainMessage(MSG_DISMISS_LANGUAGE_ON_SPACEBAR, msg.obj), mConfigDurationOfFadeoutLanguageOnSpacebar); break; case MSG_DISMISS_LANGUAGE_ON_SPACEBAR: if (inputView != null) - inputView.setSpacebarTextFadeFactor(0.0f, (LatinKeyboard)msg.obj); + inputView.setSpacebarTextFadeFactor( + mConfigFinalFadeoutFactorOfLanugageOnSpacebar, (LatinKeyboard)msg.obj); break; } } @@ -356,6 +360,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen R.integer.config_delay_before_fadeout_language_on_spacebar); mConfigDurationOfFadeoutLanguageOnSpacebar = res.getInteger( R.integer.config_duration_of_fadeout_language_on_spacebar); + mConfigFinalFadeoutFactorOfLanugageOnSpacebar = res.getInteger( + R.integer.config_final_fadeout_percentage_of_language_on_spacebar) / 100.0f; Utils.GCUtils.getInstance().reset(); boolean tryGC = true; From dc64b138b5e3fb3706c0818d0a308fe6e36985b0 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 17 Jan 2011 17:52:15 +0900 Subject: [PATCH 10/28] Revert I432be8f7 partially This change reverts removing SubtypeSwitcher.onConfigurationChanged by careless in I432be8f7. Bug: 3290290 Change-Id: I796ea01877d61eb750dabdeb3fdbf87666646c56 --- .../com/android/inputmethod/latin/LatinIME.java | 1 + .../inputmethod/latin/SubtypeSwitcher.java | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index bea44eef2..4a78c2e7a 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -444,6 +444,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void onConfigurationChanged(Configuration conf) { + mSubtypeSwitcher.onConfigurationChanged(conf); // If orientation changed while predicting, commit the change if (conf.orientation != mOrientation) { InputConnection ic = getCurrentInputConnection(); diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index 968495b8e..21c99fe09 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -370,6 +370,23 @@ public class SubtypeSwitcher { } } + public void onConfigurationChanged(Configuration conf) { + final Locale systemLocale = conf.locale; + // If system configuration was changed, update all parameters. + if (!TextUtils.equals(systemLocale.toString(), mSystemLocale.toString())) { + if (mConfigUseSpacebarLanguageSwitcher) { + // If the system locale changes and is different from the saved + // locale (mSystemLocale), then reload the input locale list from the + // latin ime settings (shared prefs) and reset the input locale + // to the first one. + mLanguageSwitcher.loadLocales(mPrefs); + mLanguageSwitcher.setSystemLocale(systemLocale); + } else { + updateAllParameters(); + } + } + } + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (mConfigUseSpacebarLanguageSwitcher) { if (Settings.PREF_SELECTED_LANGUAGES.equals(key)) { From 8bec4aa912c193135bebacfc75dc15f06c5dce6e Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 17 Jan 2011 19:27:39 +0900 Subject: [PATCH 11/28] Fix voice key enable status has not been reflected to keyboard id Bug: 3355428 Change-Id: Id4e572357a7b5603e9a609b7e80b81d8e2c500f6 --- .../inputmethod/keyboard/KeyboardSwitcher.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 25ef847cd..42af8a8d6 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -174,12 +174,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha private void loadKeyboardInternal(int mode, int imeOptions, boolean voiceButtonEnabled, boolean voiceButtonOnPrimary, boolean isSymbols) { if (mInputView == null) return; - final Keyboard oldKeyboard = mInputView.getKeyboard(); - final KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols); - if (oldKeyboard != null && oldKeyboard.mId.equals(id)) - return; - - mInputView.setPreviewEnabled(mInputMethodService.getPopupOn()); mMode = mode; mImeOptions = imeOptions; @@ -188,9 +182,15 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha mIsSymbols = isSymbols; // Update the settings key state because number of enabled IMEs could have been changed mHasSettingsKey = getSettingsKeyMode(mPrefs, mInputMethodService); - makeSymbolsKeyboardIds(); + final KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols); + final Keyboard oldKeyboard = mInputView.getKeyboard(); + if (oldKeyboard != null && oldKeyboard.mId.equals(id)) + return; + + makeSymbolsKeyboardIds(); mCurrentId = id; + mInputView.setPreviewEnabled(mInputMethodService.getPopupOn()); mInputView.setKeyboard(getKeyboard(id)); } From 90a916170f34865a1941933c4afe143d489b29b1 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 17 Jan 2011 19:59:33 +0900 Subject: [PATCH 12/28] Disable suggestion strip by default for tablet Bug: 3352374 Change-Id: Ic2fed4ecd6d73f6c2d0ad81061ecd266f4704b10 --- java/res/values-xlarge/donottranslate.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/res/values-xlarge/donottranslate.xml b/java/res/values-xlarge/donottranslate.xml index 6f4e9b1f0..672dea589 100644 --- a/java/res/values-xlarge/donottranslate.xml +++ b/java/res/values-xlarge/donottranslate.xml @@ -19,5 +19,5 @@ --> - 1 + 2 From 504e8d5171edae36ec464a5e0c72cee22bb9ac4d Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Thu, 13 Jan 2011 17:14:27 +0900 Subject: [PATCH 13/28] Preserve punctuation character after canceling auto correction Bug: 3230708 Change-Id: I939ca19c9c08d9b79658261b1e654a66af5cc493 --- .../android/inputmethod/latin/LatinIME.java | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index b93b07ffb..f839a806c 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1132,14 +1132,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private void handleBackspace() { if (mVoiceConnector.logAndRevertVoiceInput()) return; - boolean deleteChar = false; - InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; + final InputConnection ic = getCurrentInputConnection(); + if (ic == null) return; ic.beginBatchEdit(); mVoiceConnector.handleBackspace(); + boolean deleteChar = false; if (mHasValidSuggestions) { final int length = mComposing.length(); if (length > 0) { @@ -1157,12 +1157,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen deleteChar = true; } mHandler.postUpdateShiftKeyState(); + TextEntryState.backspace(); if (TextEntryState.getState() == TextEntryState.State.UNDO_COMMIT) { revertLastWord(deleteChar); ic.endBatchEdit(); return; - } else if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) { + } + + if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) { ic.deleteSurroundingText(mEnteredText.length(), 0); } else if (deleteChar) { if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) { @@ -1796,16 +1799,25 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final InputConnection ic = getCurrentInputConnection(); mHasValidSuggestions = true; mJustReverted = true; + final CharSequence punctuation = ic.getTextBeforeCursor(1, 0); if (deleteChar) ic.deleteSurroundingText(1, 0); int toDelete = mCommittedLength; - CharSequence toTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0); - if (toTheLeft != null && toTheLeft.length() > 0 - && isWordSeparator(toTheLeft.charAt(0))) { + final CharSequence toTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0); + if (!TextUtils.isEmpty(toTheLeft) && isWordSeparator(toTheLeft.charAt(0))) { toDelete--; } ic.deleteSurroundingText(toDelete, 0); - ic.setComposingText(mComposing, 1); - TextEntryState.backspace(); + if (deleteChar) { + ic.commitText(mComposing, 1); + TextEntryState.acceptedTyped(mComposing); + if (!TextUtils.isEmpty(punctuation) && isWordSeparator(punctuation.charAt(0))) { + ic.commitText(punctuation, 1); + TextEntryState.typedCharacter(punctuation.charAt(0), true); + } + } else { + ic.setComposingText(mComposing, 1); + TextEntryState.backspace(); + } mHandler.postUpdateSuggestions(); } else { sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); From 04f815eca4088ece879b1d9fb482bb7a342bfe4f Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Sat, 15 Jan 2011 08:44:25 +0900 Subject: [PATCH 14/28] Make sure that keyboard is not displayed when voice mode Bug: 3352347 Change-Id: I43cf5159f8bdcf2bc2c9a48662ea44a43ad4e25d --- .../inputmethod/keyboard/KeyboardView.java | 10 +- .../android/inputmethod/latin/LatinIME.java | 2 +- .../inputmethod/voice/RecognitionView.java | 4 +- .../inputmethod/voice/VoiceIMEConnector.java | 97 +++++++++---------- 4 files changed, 53 insertions(+), 60 deletions(-) diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index a952acf8b..b1815a146 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -298,8 +298,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView); - LayoutInflater inflate = - (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); int previewLayout = 0; int keyTextSize = 0; @@ -365,7 +363,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { mPreviewPopup = new PopupWindow(context); if (previewLayout != 0) { - mPreviewText = (TextView) inflate.inflate(previewLayout, null); + mPreviewText = (TextView) LayoutInflater.from(context).inflate(previewLayout, null); mPreviewTextSizeLarge = (int) res.getDimension(R.dimen.key_preview_text_size_large); mPreviewPopup.setContentView(mPreviewText); mPreviewPopup.setBackgroundDrawable(null); @@ -1080,9 +1078,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { private View inflateMiniKeyboardContainer(Key popupKey) { int popupKeyboardResId = mKeyboard.getPopupKeyboardResId(); - LayoutInflater inflater = (LayoutInflater)getContext().getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - View container = inflater.inflate(mPopupLayout, null); + View container = LayoutInflater.from(getContext()).inflate(mPopupLayout, null); if (container == null) throw new NullPointerException(); @@ -1408,7 +1404,9 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { dismissPopupKeyboard(); mBuffer = null; mCanvas = null; + mKeyboard = null; mMiniKeyboardCache.clear(); + requestLayout(); } @Override diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 4a78c2e7a..e3b4072c4 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -615,7 +615,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen checkReCorrectionOnStart(); inputView.setForeground(true); - mVoiceConnector.onStartInputView(mKeyboardSwitcher.getInputView().getWindowToken()); + mVoiceConnector.onStartInputView(inputView.getWindowToken()); if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); } diff --git a/java/src/com/android/inputmethod/voice/RecognitionView.java b/java/src/com/android/inputmethod/voice/RecognitionView.java index 12d0de852..d6d0721e2 100644 --- a/java/src/com/android/inputmethod/voice/RecognitionView.java +++ b/java/src/com/android/inputmethod/voice/RecognitionView.java @@ -103,9 +103,7 @@ public class RecognitionView { public RecognitionView(Context context, OnClickListener clickListener) { mUiHandler = new Handler(); - LayoutInflater inflater = (LayoutInflater) context.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - mView = inflater.inflate(R.layout.recognition_status, null); + mView = LayoutInflater.from(context).inflate(R.layout.recognition_status, null); ContentResolver cr = context.getContentResolver(); mMinMicrophoneLevel = SettingsUtil.getSettingsFloat( cr, SettingsUtil.LATIN_IME_MIN_MICROPHONE_LEVEL, 15.f); diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java index 1ac4391f1..715486147 100644 --- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java +++ b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java @@ -16,6 +16,7 @@ package com.android.inputmethod.voice; +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; @@ -91,7 +92,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { private boolean mVoiceInputHighlighted; private InputMethodManager mImm; - private LatinIME mContext; + private LatinIME mService; private AlertDialog mVoiceWarningDialog; private VoiceInput mVoiceInput; private final VoiceResults mVoiceResults = new VoiceResults(); @@ -111,21 +112,19 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { return sInstance; } - private void initInternal(LatinIME context, SharedPreferences prefs, UIHandler h) { - mContext = context; + private void initInternal(LatinIME service, SharedPreferences prefs, UIHandler h) { + mService = service; mHandler = h; - mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + mImm = (InputMethodManager) service.getSystemService(Context.INPUT_METHOD_SERVICE); mSubtypeSwitcher = SubtypeSwitcher.getInstance(); if (VOICE_INSTALLED) { - mVoiceInput = new VoiceInput(context, this); - mHints = new Hints(context, prefs, new Hints.Display() { + mVoiceInput = new VoiceInput(service, this); + mHints = new Hints(service, prefs, new Hints.Display() { @Override public void showHint(int viewResource) { - LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - View view = inflater.inflate(viewResource, null); - mContext.setCandidatesView(view); - mContext.setCandidatesViewShown(true); + View view = LayoutInflater.from(mService).inflate(viewResource, null); + mService.setCandidatesView(view); + mService.setCandidatesViewShown(true); mIsShowingHint = true; } }); @@ -161,7 +160,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { mVoiceInput.flushAllTextModificationCounters(); // send this intent AFTER logging any prior aggregated edits. mVoiceInput.logTextModifiedByChooseSuggestion(suggestion.toString(), index, - wordSeparators, mContext.getCurrentInputConnection()); + wordSeparators, mService.getCurrentInputConnection()); } } @@ -170,7 +169,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { if (mVoiceWarningDialog != null && mVoiceWarningDialog.isShowing()) { return; } - AlertDialog.Builder builder = new AlertDialog.Builder(mContext); + AlertDialog.Builder builder = new AlertDialog.Builder(mService); builder.setCancelable(true); builder.setIcon(R.drawable.ic_mic_dialog); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @@ -199,13 +198,13 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { final CharSequence message; if (mLocaleSupportedForVoiceInput) { message = TextUtils.concat( - mContext.getText(R.string.voice_warning_may_not_understand), "\n\n", - mContext.getText(R.string.voice_warning_how_to_turn_off)); + mService.getText(R.string.voice_warning_may_not_understand), "\n\n", + mService.getText(R.string.voice_warning_how_to_turn_off)); } else { message = TextUtils.concat( - mContext.getText(R.string.voice_warning_locale_not_supported), "\n\n", - mContext.getText(R.string.voice_warning_may_not_understand), "\n\n", - mContext.getText(R.string.voice_warning_how_to_turn_off)); + mService.getText(R.string.voice_warning_locale_not_supported), "\n\n", + mService.getText(R.string.voice_warning_may_not_understand), "\n\n", + mService.getText(R.string.voice_warning_how_to_turn_off)); } builder.setMessage(message); @@ -296,7 +295,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { } public void showPunctuationHintIfNecessary() { - InputConnection ic = mContext.getCurrentInputConnection(); + InputConnection ic = mService.getCurrentInputConnection(); if (!mImmediatelyAfterVoiceInput && mAfterVoiceInput && ic != null) { if (mHints.showPunctuationHintIfNecessary(ic)) { mVoiceInput.logPunctuationHintDisplayed(); @@ -364,17 +363,17 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { } private void revertVoiceInput() { - InputConnection ic = mContext.getCurrentInputConnection(); + InputConnection ic = mService.getCurrentInputConnection(); if (ic != null) ic.commitText("", 1); - mContext.updateSuggestions(); + mService.updateSuggestions(); mVoiceInputHighlighted = false; } public void commitVoiceInput() { if (VOICE_INSTALLED && mVoiceInputHighlighted) { - InputConnection ic = mContext.getCurrentInputConnection(); + InputConnection ic = mService.getCurrentInputConnection(); if (ic != null) ic.finishComposingText(); - mContext.updateSuggestions(); + mService.updateSuggestions(); mVoiceInputHighlighted = false; } } @@ -394,7 +393,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { if (mShowingVoiceSuggestions) { // Retain the replaced word in the alternatives array. String wordToBeReplaced = EditingUtils.getWordAtCursor( - mContext.getCurrentInputConnection(), wordSeparators); + mService.getCurrentInputConnection(), wordSeparators); if (!mWordToSuggestions.containsKey(wordToBeReplaced)) { wordToBeReplaced = wordToBeReplaced.toLowerCase(); } @@ -438,8 +437,8 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { builder.addWords(suggestions); } builder.setTypedWordValid(true).setHasMinimalSuggestion(true); - mContext.setSuggestions(builder.build()); - mContext.setCandidatesViewShown(true); + mService.setSuggestions(builder.build()); + mService.setCandidatesViewShown(true); return true; } return false; @@ -486,15 +485,15 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { mAfterVoiceInput = true; mImmediatelyAfterVoiceInput = true; - InputConnection ic = mContext.getCurrentInputConnection(); - if (!mContext.isFullscreenMode()) { + InputConnection ic = mService.getCurrentInputConnection(); + if (!mService.isFullscreenMode()) { // Start listening for updates to the text from typing, etc. if (ic != null) { ExtractedTextRequest req = new ExtractedTextRequest(); ic.getExtractedText(req, InputConnection.GET_EXTRACTED_TEXT_MONITOR); } } - mContext.vibrate(); + mService.vibrate(); final List nBest = new ArrayList(); for (String c : mVoiceResults.candidates) { @@ -511,7 +510,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { mHints.registerVoiceResult(bestResult); if (ic != null) ic.beginBatchEdit(); // To avoid extra updates on committing older text - mContext.commitTyped(ic); + mService.commitTyped(ic); EditingUtils.appendText(ic, bestResult); if (ic != null) ic.endBatchEdit(); @@ -525,15 +524,15 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { mHandler.post(new Runnable() { @Override public void run() { - mContext.setCandidatesViewShown(false); + mService.setCandidatesViewShown(false); mRecognizing = true; View v = mVoiceInput.getView(); ViewParent p = v.getParent(); if (p != null && p instanceof ViewGroup) { ((ViewGroup)p).removeView(v); } - mContext.setInputView(v); - mContext.updateInputViewShown(); + mService.setInputView(v); + mService.updateInputViewShown(); if (configChanged) { mVoiceInput.onConfigurationChanged(); } @@ -541,7 +540,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { } private void switchToLastInputMethod() { - IBinder token = mContext.getWindow().getWindow().getAttributes().token; + IBinder token = mService.getWindow().getWindow().getAttributes().token; mImm.switchToLastInputMethod(token); } @@ -553,7 +552,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { // The user has started a voice input, so remember that in the // future (so we don't show the warning dialog after the first run). SharedPreferences.Editor editor = - PreferenceManager.getDefaultSharedPreferences(mContext).edit(); + PreferenceManager.getDefaultSharedPreferences(mService).edit(); editor.putBoolean(PREF_HAS_USED_VOICE_INPUT, true); SharedPreferencesCompat.apply(editor); mHasUsedVoiceInput = true; @@ -563,14 +562,14 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { // The user has started a voice input from an unsupported locale, so remember that // in the future (so we don't show the warning dialog the next time they do this). SharedPreferences.Editor editor = - PreferenceManager.getDefaultSharedPreferences(mContext).edit(); + PreferenceManager.getDefaultSharedPreferences(mService).edit(); editor.putBoolean(PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE, true); SharedPreferencesCompat.apply(editor); mHasUsedVoiceInputUnsupportedLocale = true; } // Clear N-best suggestions - mContext.clearSuggestions(); + mService.clearSuggestions(); FieldContext context = makeFieldContext(); mVoiceInput.startListening(context, swipe); @@ -579,7 +578,6 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { public void startListening(final boolean swipe, IBinder token, final boolean configurationChanging) { - // TODO: remove swipe which is no longer used. if (VOICE_INSTALLED) { if (needsToShowWarningDialog()) { // Calls reallyStartListening if user clicks OK, does nothing if user clicks Cancel. @@ -601,7 +599,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { return ENABLE_VOICE_BUTTON && fieldCanDoVoice(fieldContext) && !(attribute != null && IME_OPTION_NO_MICROPHONE.equals(attribute.privateImeOptions)) - && SpeechRecognizer.isRecognitionAvailable(mContext); + && SpeechRecognizer.isRecognitionAvailable(mService); } public void loadSettings(EditorInfo attribute, SharedPreferences sp) { @@ -614,10 +612,10 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { if (VOICE_INSTALLED) { final String voiceMode = sp.getString(PREF_VOICE_MODE, - mContext.getString(R.string.voice_mode_main)); - mVoiceButtonEnabled = !voiceMode.equals(mContext.getString(R.string.voice_mode_off)) + mService.getString(R.string.voice_mode_main)); + mVoiceButtonEnabled = !voiceMode.equals(mService.getString(R.string.voice_mode_off)) && shouldShowVoiceButton(makeFieldContext(), attribute); - mVoiceButtonOnPrimary = voiceMode.equals(mContext.getString(R.string.voice_mode_main)); + mVoiceButtonOnPrimary = voiceMode.equals(mService.getString(R.string.voice_mode_main)); } } @@ -631,11 +629,10 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { // 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 (needsToShowWarningDialog()) { - showVoiceWarningDialog(false, token, false); - } else { - startListening(false, token, false); - } + // Close keyboard view if it is been shown. + if (KeyboardSwitcher.getInstance().isInputViewShown()) + KeyboardSwitcher.getInstance().getInputView().closing(); + startListening(false, token, false); } // If we have no token, onAttachedToWindow will take care of showing dialog and start // listening. @@ -668,7 +665,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { // onCurrentInputMethodSubtypeChanged() will be called first. LatinIME will know // that it's in keyboard mode and SubtypeSwitcher will call onCancelVoice(). mRecognizing = false; - mContext.switchToKeyboardView(); + mService.switchToKeyboardView(); } } } @@ -686,8 +683,8 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { public FieldContext makeFieldContext() { SubtypeSwitcher switcher = SubtypeSwitcher.getInstance(); - return new FieldContext(mContext.getCurrentInputConnection(), - mContext.getCurrentInputEditorInfo(), switcher.getInputLocaleStr(), + return new FieldContext(mService.getCurrentInputConnection(), + mService.getCurrentInputEditorInfo(), switcher.getInputLocaleStr(), switcher.getEnabledLanguages()); } From d5a6b910e83de6dea3c5813cbf5e219abaccdf8a Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 17 Jan 2011 23:47:52 +0900 Subject: [PATCH 15/28] Purge keyboard only when voice input will be invoked This change also draws the language name in light gray on spacebar without fading out even when the keyboard locale has not been changed. Bug: 3362369 Bug: 3361915 Change-Id: I66538b03ce2e48c3441091319d0377176f8118ec --- .../inputmethod/keyboard/KeyboardSwitcher.java | 7 ++++--- .../inputmethod/keyboard/KeyboardView.java | 6 +++++- .../com/android/inputmethod/latin/LatinIME.java | 15 ++++++++------- .../inputmethod/voice/VoiceIMEConnector.java | 2 +- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 42af8a8d6..68d3ccd84 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -161,9 +161,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha final Keyboard oldKeyboard = mInputView.getKeyboard(); loadKeyboardInternal(mode, imeOptions, voiceKeyEnabled, voiceButtonOnPrimary, false); final Keyboard newKeyboard = mInputView.getKeyboard(); - if (newKeyboard.isAlphaKeyboard() && (oldKeyboard == null - || !newKeyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale))) { - mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(); + if (newKeyboard.isAlphaKeyboard()) { + final boolean localeChanged = (oldKeyboard == null) + || !newKeyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale); + mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged); } } catch (RuntimeException e) { Log.w(TAG, e); diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index b1815a146..766fdf0e6 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -1404,11 +1404,15 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { dismissPopupKeyboard(); mBuffer = null; mCanvas = null; - mKeyboard = null; mMiniKeyboardCache.clear(); requestLayout(); } + public void purgeKeyboardAndClosing() { + mKeyboard = null; + closing(); + } + @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 5766f6b38..cd4143e78 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -154,7 +154,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private boolean mConfigSwipeDownDismissKeyboardEnabled; private int mConfigDelayBeforeFadeoutLanguageOnSpacebar; private int mConfigDurationOfFadeoutLanguageOnSpacebar; - private float mConfigFinalFadeoutFactorOfLanugageOnSpacebar; + private float mConfigFinalFadeoutFactorOfLanguageOnSpacebar; private int mCorrectionMode; private int mCommittedLength; @@ -269,7 +269,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR: if (inputView != null) inputView.setSpacebarTextFadeFactor( - (1.0f + mConfigFinalFadeoutFactorOfLanugageOnSpacebar) / 2, + (1.0f + mConfigFinalFadeoutFactorOfLanguageOnSpacebar) / 2, (LatinKeyboard)msg.obj); sendMessageDelayed(obtainMessage(MSG_DISMISS_LANGUAGE_ON_SPACEBAR, msg.obj), mConfigDurationOfFadeoutLanguageOnSpacebar); @@ -277,7 +277,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen case MSG_DISMISS_LANGUAGE_ON_SPACEBAR: if (inputView != null) inputView.setSpacebarTextFadeFactor( - mConfigFinalFadeoutFactorOfLanugageOnSpacebar, (LatinKeyboard)msg.obj); + mConfigFinalFadeoutFactorOfLanguageOnSpacebar, (LatinKeyboard)msg.obj); break; } } @@ -318,7 +318,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen sendMessage(obtainMessage(MSG_VOICE_RESULTS)); } - public void startDisplayLanguageOnSpacebar() { + public void startDisplayLanguageOnSpacebar(boolean localeChanged) { removeMessages(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR); removeMessages(MSG_DISMISS_LANGUAGE_ON_SPACEBAR); final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); @@ -326,9 +326,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final LatinKeyboard keyboard = inputView.getLatinKeyboard(); // The language is never displayed when the delay is zero. if (mConfigDelayBeforeFadeoutLanguageOnSpacebar != 0) - inputView.setSpacebarTextFadeFactor(1.0f, keyboard); + inputView.setSpacebarTextFadeFactor(localeChanged ? 1.0f + : mConfigFinalFadeoutFactorOfLanguageOnSpacebar, keyboard); // The language is always displayed when the delay is negative. - if (mConfigDelayBeforeFadeoutLanguageOnSpacebar > 0) { + if (localeChanged && mConfigDelayBeforeFadeoutLanguageOnSpacebar > 0) { sendMessageDelayed(obtainMessage(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR, keyboard), mConfigDelayBeforeFadeoutLanguageOnSpacebar); } @@ -360,7 +361,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen R.integer.config_delay_before_fadeout_language_on_spacebar); mConfigDurationOfFadeoutLanguageOnSpacebar = res.getInteger( R.integer.config_duration_of_fadeout_language_on_spacebar); - mConfigFinalFadeoutFactorOfLanugageOnSpacebar = res.getInteger( + mConfigFinalFadeoutFactorOfLanguageOnSpacebar = res.getInteger( R.integer.config_final_fadeout_percentage_of_language_on_spacebar) / 100.0f; Utils.GCUtils.getInstance().reset(); diff --git a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java index 715486147..9a6c3a83a 100644 --- a/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java +++ b/java/src/com/android/inputmethod/voice/VoiceIMEConnector.java @@ -631,7 +631,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener { if (mSubtypeSwitcher.isVoiceMode() && token != null) { // Close keyboard view if it is been shown. if (KeyboardSwitcher.getInstance().isInputViewShown()) - KeyboardSwitcher.getInstance().getInputView().closing(); + KeyboardSwitcher.getInstance().getInputView().purgeKeyboardAndClosing(); startListening(false, token, false); } // If we have no token, onAttachedToWindow will take care of showing dialog and start From 7766340cac9b79408c307e05460e30d7aca899e0 Mon Sep 17 00:00:00 2001 From: satok Date: Mon, 17 Jan 2011 23:26:18 +0900 Subject: [PATCH 16/28] Add debug log for subtypes. Change-Id: I7941adeab3357db1ceb7bc0c9c01a01d6ac9cf98 --- java/src/com/android/inputmethod/latin/SubtypeSwitcher.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index 21c99fe09..b765fad3f 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -155,6 +155,7 @@ public class SubtypeSwitcher { && mIsSystemLanguageSameAsInputLanguage); if (foundCurrentSubtypeBecameDisabled) { if (DBG) { + Log.w(TAG, "Current subtype: " + mInputLocaleStr + ", " + mMode); Log.w(TAG, "Last subtype was disabled. Update to the current one."); } updateSubtype(mImm.getCurrentInputMethodSubtype()); From 6c381b38cc19cc8174a7620e5726314a79ed7e43 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Tue, 18 Jan 2011 15:20:35 +0900 Subject: [PATCH 17/28] Remove the keyboard popup option by default. Add an option to mask the sound on keypress preference, and make it false on xlarge terminals by default. bug: 3282448 Change-Id: I747272d9edf854dc229aa620836cfa35a437d13f --- java/res/values-xlarge/config.xml | 1 + java/res/values/config.xml | 1 + java/src/com/android/inputmethod/latin/Settings.java | 6 ++++++ 3 files changed, 8 insertions(+) diff --git a/java/res/values-xlarge/config.xml b/java/res/values-xlarge/config.xml index 410b5e19e..912971793 100644 --- a/java/res/values-xlarge/config.xml +++ b/java/res/values-xlarge/config.xml @@ -22,6 +22,7 @@ false false false + false false false false diff --git a/java/res/values/config.xml b/java/res/values/config.xml index 11b92e7c3..e5821075e 100644 --- a/java/res/values/config.xml +++ b/java/res/values/config.xml @@ -25,6 +25,7 @@ true true true + true true true true diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index 064a80fe1..5db63b719 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -134,6 +134,12 @@ public class Settings extends PreferenceActivity if (!showSubtypeSettings) { getPreferenceScreen().removePreference(findPreference(PREF_SUBTYPES)); } + + final boolean showPopupOption = getResources().getBoolean( + R.bool.config_enable_show_popup_on_keypress_option); + if (!showPopupOption) { + getPreferenceScreen().removePreference(findPreference(PREF_POPUP_ON)); + } } @Override From 7ab9f601cc93335a29686044e38ddeb939693375 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Tue, 18 Jan 2011 14:08:40 +0900 Subject: [PATCH 18/28] Add settings key to table keyboard Bug: 3351762 Change-Id: Ibee1cf42af2f53017d83034f069b19be6657acbb --- .../drawable-mdpi/sym_keyboard_settings_holo.png | Bin 0 -> 3448 bytes java/res/xml-xlarge/kbd_key_styles.xml | 12 ++++++++++++ java/res/xml-xlarge/kbd_number.xml | 5 ++++- java/res/xml-xlarge/kbd_phone.xml | 7 +++++-- java/res/xml-xlarge/kbd_phone_symbols.xml | 5 ++++- java/res/xml-xlarge/kbd_qwerty_row4.xml | 4 +++- java/res/xml-xlarge/kbd_symbols.xml | 4 +++- java/res/xml-xlarge/kbd_symbols_shift.xml | 4 +++- 8 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 java/res/drawable-mdpi/sym_keyboard_settings_holo.png diff --git a/java/res/drawable-mdpi/sym_keyboard_settings_holo.png b/java/res/drawable-mdpi/sym_keyboard_settings_holo.png new file mode 100644 index 0000000000000000000000000000000000000000..ad7618fa00abb4adb0639527651b5e5cf6c74b9e GIT binary patch literal 3448 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 literal 0 HcmV?d00001 diff --git a/java/res/xml-xlarge/kbd_key_styles.xml b/java/res/xml-xlarge/kbd_key_styles.xml index efbad5bab..26659a2ad 100644 --- a/java/res/xml-xlarge/kbd_key_styles.xml +++ b/java/res/xml-xlarge/kbd_key_styles.xml @@ -65,6 +65,12 @@ latin:keyHintIcon="@drawable/hint_popup_holo" latin:popupCharacters="@string/alternates_for_smiley" latin:maxPopupKeyboardColumn="5" /> + + + latin:horizontalGap="8.362%p" /> + diff --git a/java/res/xml-xlarge/kbd_phone.xml b/java/res/xml-xlarge/kbd_phone.xml index c320ebbbc..b9444ad50 100644 --- a/java/res/xml-xlarge/kbd_phone.xml +++ b/java/res/xml-xlarge/kbd_phone.xml @@ -128,10 +128,13 @@ + latin:horizontalGap="12.340%p" /> + + latin:keyWidth="16.084%p" /> + latin:horizontalGap="8.362%p" /> + diff --git a/java/res/xml-xlarge/kbd_qwerty_row4.xml b/java/res/xml-xlarge/kbd_qwerty_row4.xml index 98acfc162..9d0fd81c7 100644 --- a/java/res/xml-xlarge/kbd_qwerty_row4.xml +++ b/java/res/xml-xlarge/kbd_qwerty_row4.xml @@ -26,7 +26,9 @@ latin:keyWidth="8.042%p" > + latin:horizontalGap="8.362%p" /> + + latin:horizontalGap="8.362%p" /> + + latin:horizontalGap="24.446%p" /> + From fd7d814c81132bdd59146a39dd668532f9514cd1 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Tue, 18 Jan 2011 17:45:22 +0900 Subject: [PATCH 19/28] Simplify latin IME settings page. Do not show the recorrection option on xlarge terminals, and make it true by default. Also, bring the Auto-capitalization at the top of the settings page. Issue: 3282448 Change-Id: I51a9ae6c7e496be2970107277f0a4ac65b12821e --- java/res/values-xlarge/config.xml | 1 + java/res/values/config.xml | 1 + java/res/xml/prefs.xml | 14 +++++++------- .../com/android/inputmethod/latin/LatinIME.java | 12 ++++++++++-- .../com/android/inputmethod/latin/Settings.java | 6 ++++++ 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/java/res/values-xlarge/config.xml b/java/res/values-xlarge/config.xml index 912971793..d6864608d 100644 --- a/java/res/values-xlarge/config.xml +++ b/java/res/values-xlarge/config.xml @@ -23,6 +23,7 @@ false false false + false false false false diff --git a/java/res/values/config.xml b/java/res/values/config.xml index e5821075e..a523635ca 100644 --- a/java/res/values/config.xml +++ b/java/res/values/config.xml @@ -26,6 +26,7 @@ true true true + true true true true diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml index 9c780cb2d..4bcb1d7d8 100644 --- a/java/res/xml/prefs.xml +++ b/java/res/xml/prefs.xml @@ -18,6 +18,13 @@ android:title="@string/english_ime_settings" android:key="english_ime_settings"> + + - - Date: Tue, 18 Jan 2011 15:48:29 +0900 Subject: [PATCH 20/28] Clear composing text when the auto-corrected word is reverted Bug: 3363133 Change-Id: Ib7582ad354ba16eb8ebc9f0b4f51c8ec3790f578 --- .../com/android/inputmethod/latin/LatinIME.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index cd4143e78..93d5ef616 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1805,7 +1805,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final int length = mComposing.length(); if (!mHasValidSuggestions && length > 0) { final InputConnection ic = getCurrentInputConnection(); - mHasValidSuggestions = true; mJustReverted = true; final CharSequence punctuation = ic.getTextBeforeCursor(1, 0); if (deleteChar) ic.deleteSurroundingText(1, 0); @@ -1815,14 +1814,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen toDelete--; } ic.deleteSurroundingText(toDelete, 0); - if (deleteChar) { + // Re-insert punctuation only when the deleted character was word separator and the + // composing text wasn't equal to the auto-corrected text. + if (deleteChar + && !TextUtils.isEmpty(punctuation) && isWordSeparator(punctuation.charAt(0)) + && !TextUtils.equals(mComposing, toTheLeft)) { ic.commitText(mComposing, 1); TextEntryState.acceptedTyped(mComposing); - if (!TextUtils.isEmpty(punctuation) && isWordSeparator(punctuation.charAt(0))) { - ic.commitText(punctuation, 1); - TextEntryState.typedCharacter(punctuation.charAt(0), true); - } + ic.commitText(punctuation, 1); + TextEntryState.typedCharacter(punctuation.charAt(0), true); + // Clear composing text + mComposing.setLength(0); } else { + mHasValidSuggestions = true; ic.setComposingText(mComposing, 1); TextEntryState.backspace(); } From c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bf Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Tue, 18 Jan 2011 15:28:21 +0900 Subject: [PATCH 21/28] Load keyboard correctly when subtype has been changed to keyboard Bug: 3299191 Change-Id: I5d75898aca5de25d9955efac52979097e529990b --- .../android/inputmethod/latin/LatinIME.java | 123 +++++++++--------- .../inputmethod/latin/SubtypeSwitcher.java | 6 +- 2 files changed, 68 insertions(+), 61 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index cd4143e78..02ad5bcef 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -133,14 +133,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private Resources mResources; private SharedPreferences mPrefs; + // These variables are initialized according to the {@link EditorInfo#inputType}. + private boolean mAutoSpace; + private boolean mInputTypeNoAutoCorrect; + private boolean mIsSettingsSuggestionStripOn; + private boolean mApplicationSpecifiedCompletionOn; + private final StringBuilder mComposing = new StringBuilder(); private WordComposer mWord = new WordComposer(); private CharSequence mBestWord; private boolean mHasValidSuggestions; - private boolean mIsSettingsSuggestionStripOn; - private boolean mApplicationSpecifiedCompletionOn; private boolean mHasDictionary; - private boolean mAutoSpace; private boolean mJustAddedAutoSpace; private boolean mAutoCorrectEnabled; private boolean mReCorrectionEnabled; @@ -164,9 +167,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private int mLastSelectionEnd; private SuggestedWords mSuggestPuncList; - // Input type is such that we should not auto-correct - private boolean mInputTypeNoAutoCorrect; - // Indicates whether the suggestion strip is to be on in landscape private boolean mJustAccepted; private boolean mJustReverted; @@ -507,24 +507,62 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (mRefreshKeyboardRequired) { mRefreshKeyboardRequired = false; - onKeyboardLanguageChanged(); + onRefreshKeyboard(); } TextEntryState.newSession(this); - // Most such things we decide below in the switch statement, but we need to know - // now whether this is a password text field, because we need to know now (before - // the switch statement) whether we want to enable the voice button. - int variation = attribute.inputType & InputType.TYPE_MASK_VARIATION; - mVoiceConnector.resetVoiceStates(isPasswordVariation(variation)); + // Most such things we decide below in initializeInputAttributesAndGetMode, but we need to + // know now whether this is a password text field, because we need to know now whether we + // want to enable the voice button. + mVoiceConnector.resetVoiceStates(isPasswordVariation( + attribute.inputType & InputType.TYPE_MASK_VARIATION)); + + final int mode = initializeInputAttributesAndGetMode(attribute.inputType); + + inputView.closing(); + mEnteredText = null; + mComposing.setLength(0); + mHasValidSuggestions = false; + mDeleteCount = 0; + mJustAddedAutoSpace = false; + + loadSettings(attribute); + if (mSubtypeSwitcher.isKeyboardMode()) { + switcher.loadKeyboard(mode, attribute.imeOptions, + mVoiceConnector.isVoiceButtonEnabled(), + mVoiceConnector.isVoiceButtonOnPrimary()); + switcher.updateShiftState(); + } + + setCandidatesViewShownInternal(isCandidateStripVisible(), + false /* needsInputViewShown */ ); + // Delay updating suggestions because keyboard input view may not be shown at this point. + mHandler.postUpdateSuggestions(); + + updateCorrectionMode(); + + inputView.setPreviewEnabled(mPopupOn); + inputView.setProximityCorrectionEnabled(true); + // If we just entered a text field, maybe it has some old text that requires correction + checkReCorrectionOnStart(); + inputView.setForeground(true); + + mVoiceConnector.onStartInputView(inputView.getWindowToken()); + + if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); + } + + private int initializeInputAttributesAndGetMode(int inputType) { + final int variation = inputType & InputType.TYPE_MASK_VARIATION; + mAutoSpace = false; mInputTypeNoAutoCorrect = false; mIsSettingsSuggestionStripOn = false; mApplicationSpecifiedCompletionOn = false; mApplicationSpecifiedCompletions = null; - mEnteredText = null; final int mode; - switch (attribute.inputType & InputType.TYPE_MASK_CLASS) { + switch (inputType & InputType.TYPE_MASK_CLASS) { case InputType.TYPE_CLASS_NUMBER: case InputType.TYPE_CLASS_DATETIME: mode = KeyboardId.MODE_NUMBER; @@ -559,7 +597,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mode = KeyboardId.MODE_WEB; // If it's a browser edit field and auto correct is not ON explicitly, then // disable auto correction, but keep suggestions on. - if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) { + if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) { mInputTypeNoAutoCorrect = true; } } else { @@ -567,16 +605,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } // If NO_SUGGESTIONS is set, don't do prediction. - if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) { + if ((inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) { mIsSettingsSuggestionStripOn = false; mInputTypeNoAutoCorrect = true; } // If it's not multiline and the autoCorrect flag is not set, then don't correct - if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 && - (attribute.inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == 0) { + if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 && + (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == 0) { mInputTypeNoAutoCorrect = true; } - if ((attribute.inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) { + if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) { mIsSettingsSuggestionStripOn = false; mApplicationSpecifiedCompletionOn = isFullscreenMode(); } @@ -585,40 +623,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mode = KeyboardId.MODE_TEXT; break; } - inputView.closing(); - mComposing.setLength(0); - mHasValidSuggestions = false; - mDeleteCount = 0; - mJustAddedAutoSpace = false; - - loadSettings(attribute); - if (mSubtypeSwitcher.isKeyboardMode()) { - switcher.loadKeyboard(mode, attribute.imeOptions, - mVoiceConnector.isVoiceButtonEnabled(), - mVoiceConnector.isVoiceButtonOnPrimary()); - switcher.updateShiftState(); - } - - setCandidatesViewShownInternal(isCandidateStripVisible(), - false /* needsInputViewShown */ ); - // Delay updating suggestions because keyboard input view may not be shown at this point. - mHandler.postUpdateSuggestions(); - - // If the dictionary is not big enough, don't auto correct - mHasDictionary = mSuggest.hasMainDictionary(); - - updateCorrectionMode(); - - inputView.setPreviewEnabled(mPopupOn); - inputView.setProximityCorrectionEnabled(true); - mIsSettingsSuggestionStripOn &= (mCorrectionMode > 0 || isShowingSuggestionsStrip()); - // If we just entered a text field, maybe it has some old text that requires correction - checkReCorrectionOnStart(); - inputView.setForeground(true); - - mVoiceConnector.onStartInputView(inputView.getWindowToken()); - - if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); + return mode; } private void checkReCorrectionOnStart() { @@ -1387,7 +1392,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } private boolean isSuggestionsRequested() { - return mIsSettingsSuggestionStripOn; + return mIsSettingsSuggestionStripOn + && (mCorrectionMode > 0 || isShowingSuggestionsStrip()); } private boolean isShowingPunctuationList() { @@ -1855,9 +1861,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return mWord.isFirstCharCapitalized(); } - // Notify that Language has been changed and toggleLanguage will update KeyboaredID according - // to new Language. - public void onKeyboardLanguageChanged() { + // Notify that language or mode have been changed and toggleLanguage will update KeyboaredID + // according to new language or mode. + public void onRefreshKeyboard() { toggleLanguage(true, true); } @@ -1868,8 +1874,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } // Reload keyboard because the current language has been changed. KeyboardSwitcher switcher = mKeyboardSwitcher; - final int mode = switcher.getKeyboardMode(); final EditorInfo attribute = getCurrentInputEditorInfo(); + final int mode = initializeInputAttributesAndGetMode((attribute != null) + ? attribute.inputType : 0); final int imeOptions = (attribute != null) ? attribute.imeOptions : 0; switcher.loadKeyboard(mode, imeOptions, mVoiceConnector.isVoiceButtonEnabled(), mVoiceConnector.isVoiceButtonOnPrimary()); diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index 21c99fe09..2c82a800a 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -186,7 +186,7 @@ public class SubtypeSwitcher { // fallback to the default locale and mode. Log.w(TAG, "Couldn't get the current subtype."); newLocale = "en_US"; - newMode =KEYBOARD_MODE; + newMode = KEYBOARD_MODE; } else { newLocale = newSubtype.getLocale(); newMode = newSubtype.getMode(); @@ -216,8 +216,8 @@ public class SubtypeSwitcher { mVoiceInput.cancel(); } } - if (languageChanged) { - mService.onKeyboardLanguageChanged(); + if (modeChanged || languageChanged) { + mService.onRefreshKeyboard(); } } else if (isVoiceMode()) { // If needsToShowWarningDialog is true, voice input need to show warning before From cff6d095956106bac8c9af43a314c4923df11e2d Mon Sep 17 00:00:00 2001 From: satok Date: Tue, 18 Jan 2011 22:07:58 +0900 Subject: [PATCH 22/28] Disable auto-correct when previous suggestion candidates are shown Change-Id: I16717f0c67950297a077a15b2b6492180c0bc54b --- java/src/com/android/inputmethod/latin/SuggestedWords.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index 5398b77b2..0fbbcdd91 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -124,7 +124,7 @@ public class SuggestedWords { addWord(previousSuggestions.getWord(pos)); mIsCompletions = false; mTypedWordValid = false; - mHasMinimalSuggestion = (previousSize > 1); + mHasMinimalSuggestion = false; return this; } From bbd651a00898dabf6b2ae0e715d99953ea81063f Mon Sep 17 00:00:00 2001 From: Luca Zanolin Date: Tue, 18 Jan 2011 15:49:17 +0000 Subject: [PATCH 23/28] Change the UI of Voice IME to be more like Voice Search. There has been a bit of refactoring in RecognitionView in particular to fix the portrait layout. The main issues found were: - the size of the keyboard is specified in inches, and (cm)(inches + inches) != ((cm) inches) + ((cm) inches)) - the height of keyboard background is high as the landscape keyboard, but it higher than the portrait keyboard. This is not an issue on LatinKeyboard, as it overwrite the onMeasure method. However, if I use the same image background in RelativeLayout the Relative layout height is set to the height of the background, thus higher than the keyboard - the change configuration was not propageted correctly Change-Id: Id5dca425826997c573ccae7a085d5ddc9719733b --- .../drawable-xlarge/btn_center_default.9.png | Bin 0 -> 182 bytes .../drawable-xlarge/btn_center_pressed.9.png | Bin 0 -> 200 bytes .../drawable-xlarge/btn_center_selected.9.png | Bin 0 -> 200 bytes java/res/drawable-xlarge/caution.png | Bin 0 -> 1100 bytes java/res/drawable-xlarge/mic_base.png | Bin 0 -> 2957 bytes java/res/drawable-xlarge/mic_full.png | Bin 0 -> 2935 bytes java/res/drawable-xlarge/mic_slash.png | Bin 0 -> 3766 bytes java/res/drawable-xlarge/vs_dialog_blue.9.png | Bin 0 -> 8275 bytes java/res/drawable-xlarge/vs_dialog_red.9.png | Bin 0 -> 8607 bytes .../drawable-xlarge/vs_dialog_yellow.9.png | Bin 0 -> 8151 bytes .../res/drawable-xlarge/vs_popup_mic_edge.png | Bin 0 -> 3685 bytes java/res/drawable/background_voice.xml | 25 ++ java/res/drawable/btn_center.xml | 40 ++++ java/res/drawable/btn_center_default.9.png | Bin 0 -> 182 bytes java/res/drawable/btn_center_pressed.9.png | Bin 0 -> 200 bytes java/res/drawable/btn_center_selected.9.png | Bin 0 -> 200 bytes java/res/drawable/caution.png | Bin 0 -> 1100 bytes java/res/drawable/mic_base.png | Bin 0 -> 2957 bytes java/res/drawable/mic_full.png | Bin 0 -> 2935 bytes java/res/drawable/mic_slash.png | Bin 0 -> 3766 bytes java/res/drawable/vs_dialog_blue.9.png | Bin 0 -> 8275 bytes java/res/drawable/vs_dialog_red.9.png | Bin 0 -> 8607 bytes java/res/drawable/vs_dialog_yellow.9.png | Bin 0 -> 8151 bytes java/res/drawable/vs_popup_mic_edge.png | Bin 0 -> 3685 bytes java/res/layout/recognition_status.xml | 141 +++++------ .../android/inputmethod/latin/LatinIME.java | 2 +- .../inputmethod/latin/SubtypeSwitcher.java | 2 +- .../inputmethod/voice/RecognitionView.java | 221 +++++++++--------- .../inputmethod/voice/SoundIndicator.java | 155 ++++++++++++ .../inputmethod/voice/VoiceIMEConnector.java | 54 +++-- .../android/inputmethod/voice/VoiceInput.java | 13 +- 31 files changed, 446 insertions(+), 207 deletions(-) create mode 100755 java/res/drawable-xlarge/btn_center_default.9.png create mode 100755 java/res/drawable-xlarge/btn_center_pressed.9.png create mode 100644 java/res/drawable-xlarge/btn_center_selected.9.png create mode 100755 java/res/drawable-xlarge/caution.png create mode 100644 java/res/drawable-xlarge/mic_base.png create mode 100644 java/res/drawable-xlarge/mic_full.png create mode 100644 java/res/drawable-xlarge/mic_slash.png create mode 100644 java/res/drawable-xlarge/vs_dialog_blue.9.png create mode 100644 java/res/drawable-xlarge/vs_dialog_red.9.png create mode 100644 java/res/drawable-xlarge/vs_dialog_yellow.9.png create mode 100644 java/res/drawable-xlarge/vs_popup_mic_edge.png create mode 100644 java/res/drawable/background_voice.xml create mode 100644 java/res/drawable/btn_center.xml create mode 100755 java/res/drawable/btn_center_default.9.png create mode 100755 java/res/drawable/btn_center_pressed.9.png create mode 100644 java/res/drawable/btn_center_selected.9.png create mode 100755 java/res/drawable/caution.png create mode 100644 java/res/drawable/mic_base.png create mode 100644 java/res/drawable/mic_full.png create mode 100644 java/res/drawable/mic_slash.png create mode 100644 java/res/drawable/vs_dialog_blue.9.png create mode 100644 java/res/drawable/vs_dialog_red.9.png create mode 100644 java/res/drawable/vs_dialog_yellow.9.png create mode 100644 java/res/drawable/vs_popup_mic_edge.png create mode 100644 java/src/com/android/inputmethod/voice/SoundIndicator.java diff --git a/java/res/drawable-xlarge/btn_center_default.9.png b/java/res/drawable-xlarge/btn_center_default.9.png new file mode 100755 index 0000000000000000000000000000000000000000..d5ec36ba49b91d6573ea1e21a70abc4ef572b619 GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eQ!3HG1Sky`ZDaPU;cPEB*=VV?2Ic!PZ?k)^R z84fc1PrZ3w4=BP};1OBOz`!jG!i)^F=12eq*-JcqUDRmBA3NNTy}&j>Wurg>3xl#0 VrzFR_`hK7Z44$rjF6*2Ung9+rF-QOa literal 0 HcmV?d00001 diff --git a/java/res/drawable-xlarge/btn_center_pressed.9.png b/java/res/drawable-xlarge/btn_center_pressed.9.png new file mode 100755 index 0000000000000000000000000000000000000000..593a679d01b516b59c7478570a8e698a9ef51f6f GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eQ!3HG1Sky`ZDaPU;cPEB*=VV?2Ic!PZ?k)^R z84fc1PrZ3w4=BP};1OBOz`!jG!i)^F=12eq*-JcqUDmdKI;Vst08;BYrvLx| literal 0 HcmV?d00001 diff --git a/java/res/drawable-xlarge/btn_center_selected.9.png b/java/res/drawable-xlarge/btn_center_selected.9.png new file mode 100644 index 0000000000000000000000000000000000000000..f1914a8864f4dd60d259ef5c7b94880b97608834 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eQ!3HG1Sky`ZDaPU;cPEB*=VV?2Ic!PZ?k)^R z84fc1PrZ3w4=BP};1OBOz`!jG!i)^F=12eq*-JcqUDZLMI!dq-+CrCK5LlR*x2~+#lipYj%aM#mVW1;%PL;wu*3C1 orUrd%+FMO8XfjU>;4olf*bu=jS8HBT05p@q)78&qol`;+0NYeJasU7T literal 0 HcmV?d00001 diff --git a/java/res/drawable-xlarge/caution.png b/java/res/drawable-xlarge/caution.png new file mode 100755 index 0000000000000000000000000000000000000000..eaef534254f1b5feef517949b559f5653b81fcba GIT binary patch literal 1100 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 literal 0 HcmV?d00001 diff --git a/java/res/drawable-xlarge/mic_slash.png b/java/res/drawable-xlarge/mic_slash.png new file mode 100644 index 0000000000000000000000000000000000000000..1dd05c5b44500013703f8e8f55356d7f92f66f93 GIT binary patch literal 3766 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 literal 0 HcmV?d00001 diff --git a/java/res/drawable-xlarge/vs_dialog_yellow.9.png b/java/res/drawable-xlarge/vs_dialog_yellow.9.png new file mode 100644 index 0000000000000000000000000000000000000000..2fb06c263647a1b9f38608fe03ea5675ed2aea94 GIT binary patch literal 8151 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 literal 0 HcmV?d00001 diff --git a/java/res/drawable-xlarge/vs_popup_mic_edge.png b/java/res/drawable-xlarge/vs_popup_mic_edge.png new file mode 100644 index 0000000000000000000000000000000000000000..4ff6337a2c0b4458cb2fe3ca26c19695c2847302 GIT binary patch literal 3685 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 DBcAU~ literal 0 HcmV?d00001 diff --git a/java/res/drawable/background_voice.xml b/java/res/drawable/background_voice.xml new file mode 100644 index 000000000..3b6137df3 --- /dev/null +++ b/java/res/drawable/background_voice.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/java/res/drawable/btn_center.xml b/java/res/drawable/btn_center.xml new file mode 100644 index 000000000..9998b56e2 --- /dev/null +++ b/java/res/drawable/btn_center.xml @@ -0,0 +1,40 @@ + + + + + + + + + + \ No newline at end of file diff --git a/java/res/drawable/btn_center_default.9.png b/java/res/drawable/btn_center_default.9.png new file mode 100755 index 0000000000000000000000000000000000000000..d5ec36ba49b91d6573ea1e21a70abc4ef572b619 GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eQ!3HG1Sky`ZDaPU;cPEB*=VV?2Ic!PZ?k)^R z84fc1PrZ3w4=BP};1OBOz`!jG!i)^F=12eq*-JcqUDRmBA3NNTy}&j>Wurg>3xl#0 VrzFR_`hK7Z44$rjF6*2Ung9+rF-QOa literal 0 HcmV?d00001 diff --git a/java/res/drawable/btn_center_pressed.9.png b/java/res/drawable/btn_center_pressed.9.png new file mode 100755 index 0000000000000000000000000000000000000000..593a679d01b516b59c7478570a8e698a9ef51f6f GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eQ!3HG1Sky`ZDaPU;cPEB*=VV?2Ic!PZ?k)^R z84fc1PrZ3w4=BP};1OBOz`!jG!i)^F=12eq*-JcqUDmdKI;Vst08;BYrvLx| literal 0 HcmV?d00001 diff --git a/java/res/drawable/btn_center_selected.9.png b/java/res/drawable/btn_center_selected.9.png new file mode 100644 index 0000000000000000000000000000000000000000..f1914a8864f4dd60d259ef5c7b94880b97608834 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eQ!3HG1Sky`ZDaPU;cPEB*=VV?2Ic!PZ?k)^R z84fc1PrZ3w4=BP};1OBOz`!jG!i)^F=12eq*-JcqUDZLMI!dq-+CrCK5LlR*x2~+#lipYj%aM#mVW1;%PL;wu*3C1 orUrd%+FMO8XfjU>;4olf*bu=jS8HBT05p@q)78&qol`;+0NYeJasU7T literal 0 HcmV?d00001 diff --git a/java/res/drawable/caution.png b/java/res/drawable/caution.png new file mode 100755 index 0000000000000000000000000000000000000000..eaef534254f1b5feef517949b559f5653b81fcba GIT binary patch literal 1100 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 literal 0 HcmV?d00001 diff --git a/java/res/drawable/mic_slash.png b/java/res/drawable/mic_slash.png new file mode 100644 index 0000000000000000000000000000000000000000..1dd05c5b44500013703f8e8f55356d7f92f66f93 GIT binary patch literal 3766 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 literal 0 HcmV?d00001 diff --git a/java/res/drawable/vs_dialog_yellow.9.png b/java/res/drawable/vs_dialog_yellow.9.png new file mode 100644 index 0000000000000000000000000000000000000000..2fb06c263647a1b9f38608fe03ea5675ed2aea94 GIT binary patch literal 8151 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 literal 0 HcmV?d00001 diff --git a/java/res/drawable/vs_popup_mic_edge.png b/java/res/drawable/vs_popup_mic_edge.png new file mode 100644 index 0000000000000000000000000000000000000000..4ff6337a2c0b4458cb2fe3ca26c19695c2847302 GIT binary patch literal 3685 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 DBcAU~ literal 0 HcmV?d00001 diff --git a/java/res/layout/recognition_status.xml b/java/res/layout/recognition_status.xml index ea2d9eefe..b2c9f4a51 100644 --- a/java/res/layout/recognition_status.xml +++ b/java/res/layout/recognition_status.xml @@ -16,83 +16,70 @@ ** See the License for the specific language governing permissions and ** limitations under the License. */ ---> - - - - - - - + - - - - - - - - - - - - + android:background="@drawable/background_voice"> + + + + + + + +