diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml index de4ac610c..e0eecfc7d 100644 --- a/java/AndroidManifest.xml +++ b/java/AndroidManifest.xml @@ -2,6 +2,7 @@ package="com.android.inputmethod.latin"> + diff --git a/java/res/drawable-hdpi/sym_bkeyboard_mic_disabled.png b/java/res/drawable-hdpi/sym_bkeyboard_mic_disabled.png new file mode 100644 index 000000000..512f46080 Binary files /dev/null and b/java/res/drawable-hdpi/sym_bkeyboard_mic_disabled.png differ diff --git a/java/res/drawable-hdpi/sym_keyboard_mic_disabled.png b/java/res/drawable-hdpi/sym_keyboard_mic_disabled.png new file mode 100644 index 000000000..c8dca62a0 Binary files /dev/null and b/java/res/drawable-hdpi/sym_keyboard_mic_disabled.png differ diff --git a/java/res/drawable-mdpi/sym_bkeyboard_mic_disabled.png b/java/res/drawable-mdpi/sym_bkeyboard_mic_disabled.png new file mode 100644 index 000000000..a6cb1cc01 Binary files /dev/null and b/java/res/drawable-mdpi/sym_bkeyboard_mic_disabled.png differ diff --git a/java/res/drawable-mdpi/sym_keyboard_mic_disabled.png b/java/res/drawable-mdpi/sym_keyboard_mic_disabled.png new file mode 100644 index 000000000..e926b3fa6 Binary files /dev/null and b/java/res/drawable-mdpi/sym_keyboard_mic_disabled.png differ diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml index 3bff3fccd..b1f737903 100644 --- a/java/res/xml/method.xml +++ b/java/res/xml/method.xml @@ -38,7 +38,7 @@ android:label="@string/subtype_mode_en_voice" android:imeSubtypeLocale="en" android:imeSubtypeMode="voice" - android:imeSubtypeExtraValue="excludeFromLastInputMethod" + android:imeSubtypeExtraValue="excludeFromLastInputMethod,requireNetworkConnectivity" /> diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index 35bafea80..23886ad97 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -95,6 +95,8 @@ public class Key { public boolean mPressed; /** If this is a sticky key, is it on? */ public boolean mOn; + /** Key is enabled or not. */ + public boolean mEnabled = true; private final static int[] KEY_STATE_NORMAL_ON = { android.R.attr.state_checkable, @@ -385,8 +387,9 @@ public class Key { * @see android.graphics.drawable.StateListDrawable#setState(int[]) */ public int[] getCurrentDrawableState() { + final boolean pressed = mEnabled && mPressed; if (isFunctionalKey()) { - if (mPressed) { + if (pressed) { return KEY_STATE_FUNCTIONAL_PRESSED; } else { return KEY_STATE_FUNCTIONAL_NORMAL; @@ -396,20 +399,20 @@ public class Key { int[] states = KEY_STATE_NORMAL; if (mOn) { - if (mPressed) { + if (pressed) { states = KEY_STATE_PRESSED_ON; } else { states = KEY_STATE_NORMAL_ON; } } else { if (mSticky) { - if (mPressed) { + if (pressed) { states = KEY_STATE_PRESSED_OFF; } else { states = KEY_STATE_NORMAL_OFF; } } else { - if (mPressed) { + if (pressed) { states = KEY_STATE_PRESSED; } } diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 863421f18..3a0bf53ab 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -107,11 +107,6 @@ public class Keyboard { private final HashSet mShiftLockEnabled = new HashSet(); private final KeyboardShiftState mShiftState = new KeyboardShiftState(); - /** Space key and its icons */ - protected Key mSpaceKey; - protected Drawable mSpaceIcon; - protected Drawable mSpacePreviewIcon; - /** Total height of the keyboard, including the padding and keys */ private int mTotalHeight; @@ -350,12 +345,6 @@ public class Keyboard { return mId != null && mId.isNumberKeyboard(); } - public void setSpaceKey(Key space) { - mSpaceKey = space; - mSpaceIcon = space.getIcon(); - mSpacePreviewIcon = space.getPreviewIcon(); - } - private void computeNearestNeighbors() { // Round-up so we don't have any pixels outside the grid mCellWidth = (getMinWidth() + GRID_WIDTH - 1) / GRID_WIDTH; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java index c41d57075..e8324e5fd 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java @@ -286,8 +286,6 @@ public class KeyboardParser { keys.add(key); if (key.mCode == Keyboard.CODE_SHIFT) mKeyboard.getShiftKeys().add(key); - if (key.mCode == Keyboard.CODE_SPACE) - mKeyboard.setSpaceKey(key); endKey(key); } } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 558de66a4..2648ff3d4 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -17,11 +17,11 @@ package com.android.inputmethod.keyboard; import com.android.inputmethod.latin.LatinIME; -import com.android.inputmethod.latin.Settings; -import com.android.inputmethod.latin.Utils; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.Settings; import com.android.inputmethod.latin.SubtypeSwitcher; +import com.android.inputmethod.latin.Utils; import android.content.Context; import android.content.SharedPreferences; @@ -222,8 +222,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha 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. + // we should reset the text fade factor. It is also applicable to shortcut key. keyboard.setSpacebarTextFadeFactor(0.0f, null); + keyboard.updateShortcutKey(mSubtypeSwitcher.isShortcutAvailable(), null); return keyboard; } diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java index 1977f5fae..dc134d6be 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java @@ -45,18 +45,30 @@ public class LatinKeyboard extends Keyboard { public static final int OPACITY_FULLY_OPAQUE = 255; private static final int SPACE_LED_LENGTH_PERCENT = 80; + private final Context mContext; + + /* Space key and its icons, drawables and colors. */ + private final Key mSpaceKey; + private final Drawable mSpaceIcon; + private final Drawable mSpacePreviewIcon; + private final int[] mSpaceKeyIndexArray; private final Drawable mSpaceAutoCorrectionIndicator; private final Drawable mButtonArrowLeftIcon; private final Drawable mButtonArrowRightIcon; private final int mSpacebarTextColor; private final int mSpacebarTextShadowColor; + private final int mSpacebarVerticalCorrection; private float mSpacebarTextFadeFactor = 0.0f; - private final int[] mSpaceKeyIndexArray; private int mSpaceDragStartX; private int mSpaceDragLastDiff; - private final Context mContext; private boolean mCurrentlyInSpace; private SlidingLocaleDrawable mSlidingLocaleIcon; + + /* Shortcut key and its icons if available */ + private final Key mShortcutKey; + private final Drawable mEnabledShortcutIcon; + private final Drawable mDisabledShortcutIcon; + private int[] mPrefLetterFrequencies; private int mPrefLetter; private int mPrefLetterX; @@ -74,8 +86,6 @@ public class LatinKeyboard extends Keyboard { // its short language name will be used instead. private static final float MINIMUM_SCALE_OF_LANGUAGE_NAME = 0.8f; - private static int sSpacebarVerticalCorrection; - private static final String SMALL_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "small"; private static final String MEDIUM_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "medium"; @@ -83,21 +93,47 @@ public class LatinKeyboard extends Keyboard { super(context, id.getXmlId(), id); final Resources res = context.getResources(); mContext = context; + + final List keys = getKeys(); + int spaceKeyIndex = -1; + int shortcutKeyIndex = -1; + final int keyCount = keys.size(); + for (int index = 0; index < keyCount; index++) { + // For now, assuming there are up to one space key and one shortcut key respectively. + switch (keys.get(index).mCode) { + case CODE_SPACE: + spaceKeyIndex = index; + break; + case CODE_VOICE: + shortcutKeyIndex = index; + break; + } + } + + // The index of space key is available only after Keyboard constructor has finished. + mSpaceKey = (spaceKeyIndex >= 0) ? keys.get(spaceKeyIndex) : null; + mSpaceIcon = (mSpaceKey != null) ? mSpaceKey.getIcon() : null; + mSpacePreviewIcon = (mSpaceKey != null) ? mSpaceKey.getPreviewIcon() : null; + mSpaceKeyIndexArray = new int[] { spaceKeyIndex }; + + mShortcutKey = (shortcutKeyIndex >= 0) ? keys.get(shortcutKeyIndex) : null; + mEnabledShortcutIcon = (mShortcutKey != null) ? mShortcutKey.getIcon() : null; + mSpacebarTextColor = res.getColor(R.color.latinkeyboard_bar_language_text); if (id.mColorScheme == KeyboardView.COLOR_SCHEME_BLACK) { mSpacebarTextShadowColor = res.getColor( R.color.latinkeyboard_bar_language_shadow_black); + mDisabledShortcutIcon = res.getDrawable(R.drawable.sym_keyboard_mic_disabled); } else { // default color scheme is KeyboardView.COLOR_SCHEME_WHITE mSpacebarTextShadowColor = res.getColor( R.color.latinkeyboard_bar_language_shadow_white); + mDisabledShortcutIcon = res.getDrawable(R.drawable.sym_bkeyboard_mic_disabled); } mSpaceAutoCorrectionIndicator = res.getDrawable(R.drawable.sym_keyboard_space_led); mButtonArrowLeftIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_left); mButtonArrowRightIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_right); - sSpacebarVerticalCorrection = res.getDimensionPixelOffset( + mSpacebarVerticalCorrection = res.getDimensionPixelOffset( R.dimen.spacebar_vertical_correction); - // The index of space key is available only after Keyboard constructor has finished. - mSpaceKeyIndexArray = new int[] { indexOf(CODE_SPACE) }; } public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboardView view) { @@ -113,6 +149,15 @@ public class LatinKeyboard extends Keyboard { return newColor; } + public void updateShortcutKey(boolean available, LatinKeyboardView view) { + if (mShortcutKey == null) + return; + mShortcutKey.mEnabled = available; + mShortcutKey.setIcon(available ? mEnabledShortcutIcon : mDisabledShortcutIcon); + if (view != null) + view.invalidateKey(mShortcutKey); + } + /** * @return a key which should be invalidated. */ @@ -316,7 +361,7 @@ public class LatinKeyboard extends Keyboard { int y = pointY; final int code = key.mCode; if (code == CODE_SPACE) { - y += LatinKeyboard.sSpacebarVerticalCorrection; + y += mSpacebarVerticalCorrection; if (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher() && SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() > 1) { if (mCurrentlyInSpace) { @@ -442,15 +487,6 @@ public class LatinKeyboard extends Keyboard { } } - private int indexOf(int code) { - List keys = getKeys(); - int count = keys.size(); - for (int i = 0; i < count; i++) { - if (keys.get(i).mCode == code) return i; - } - return -1; - } - private int getTextSizeFromTheme(int style, int defValue) { TypedArray array = mContext.getTheme().obtainStyledAttributes( style, new int[] { android.R.attr.textSize }); diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 49f29f923..cf379f0bf 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -561,7 +561,8 @@ public class PointerTracker { codes[1] = codes[0]; codes[0] = code; } - callListenerOnCodeInput(code, codes, x, y); + if (key.mEnabled) + callListenerOnCodeInput(code, codes, x, y); callListenerOnRelease(code); } } diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index c1e14ad18..67ca9aaad 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -17,16 +17,23 @@ package com.android.inputmethod.latin; import com.android.inputmethod.keyboard.KeyboardSwitcher; +import com.android.inputmethod.keyboard.LatinKeyboard; +import com.android.inputmethod.keyboard.LatinKeyboardView; import com.android.inputmethod.voice.SettingsUtil; import com.android.inputmethod.voice.VoiceIMEConnector; import com.android.inputmethod.voice.VoiceInput; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.drawable.Drawable; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; import android.os.IBinder; import android.text.TextUtils; import android.util.Log; @@ -47,6 +54,8 @@ public class SubtypeSwitcher { private static final char LOCALE_SEPARATER = '_'; private static final String KEYBOARD_MODE = "keyboard"; private static final String VOICE_MODE = "voice"; + private static final String SUBTYPE_EXTRAVALUE_REQUIRE_NETWORK_CONNECTIVITY = + "requireNetworkConnectivity"; private final TextUtils.SimpleStringSplitter mLocaleSplitter = new TextUtils.SimpleStringSplitter(LOCALE_SEPARATER); @@ -55,17 +64,17 @@ public class SubtypeSwitcher { private /* final */ SharedPreferences mPrefs; private /* final */ InputMethodManager mImm; private /* final */ Resources mResources; + private /* final */ ConnectivityManager mConnectivityManager; + private /* final */ boolean mConfigUseSpacebarLanguageSwitcher; private final ArrayList mEnabledKeyboardSubtypesOfCurrentInputMethod = new ArrayList(); private final ArrayList mEnabledLanguagesOfCurrentInputMethod = new ArrayList(); - private boolean mConfigUseSpacebarLanguageSwitcher; - /*-----------------------------------------------------------*/ // Variants which should be changed only by reload functions. private boolean mNeedsToDisplayLanguage; private boolean mIsSystemLanguageSameAsInputLanguage; - private InputMethodInfo mShortcutInfo; + private InputMethodInfo mShortcutInputMethodInfo; private InputMethodSubtype mShortcutSubtype; private List mAllEnabledSubtypesOfCurrentInputMethod; private Locale mSystemLocale; @@ -75,6 +84,8 @@ public class SubtypeSwitcher { private VoiceInput mVoiceInput; /*-----------------------------------------------------------*/ + private boolean mIsNetworkConnected; + public static SubtypeSwitcher getInstance() { return sInstance; } @@ -95,6 +106,8 @@ public class SubtypeSwitcher { mService = service; mResources = service.getResources(); mImm = (InputMethodManager) service.getSystemService(Context.INPUT_METHOD_SERVICE); + mConnectivityManager = (ConnectivityManager) service.getSystemService( + Context.CONNECTIVITY_SERVICE); mEnabledKeyboardSubtypesOfCurrentInputMethod.clear(); mEnabledLanguagesOfCurrentInputMethod.clear(); mSystemLocale = null; @@ -109,6 +122,17 @@ public class SubtypeSwitcher { R.bool.config_use_spacebar_language_switcher); if (mConfigUseSpacebarLanguageSwitcher) initLanguageSwitcher(service); + + final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo(); + mIsNetworkConnected = (info != null && info.isConnected()); + final BroadcastReceiver receiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + onNetworkStateChanged(intent); + } + }; + service.registerReceiver(receiver, + new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } // Update all parameters stored in SubtypeSwitcher. @@ -165,7 +189,8 @@ public class SubtypeSwitcher { private void updateShortcutIME() { if (DBG) { Log.d(TAG, "Update shortcut IME from : " - + (mShortcutInfo == null ? "" : mShortcutInfo.getId()) + ", " + + (mShortcutInputMethodInfo == null + ? "" : mShortcutInputMethodInfo.getId()) + ", " + (mShortcutSubtype == null ? "" : (mShortcutSubtype.getLocale() + ", " + mShortcutSubtype.getMode()))); } @@ -176,7 +201,7 @@ public class SubtypeSwitcher { List subtypes = shortcuts.get(imi); // TODO: Returns the first found IMI for now. Should handle all shortcuts as // appropriate. - mShortcutInfo = imi; + mShortcutInputMethodInfo = imi; // TODO: Pick up the first found subtype for now. Should handle all subtypes // as appropriate. mShortcutSubtype = subtypes.size() > 0 ? subtypes.get(0) : null; @@ -184,7 +209,8 @@ public class SubtypeSwitcher { } if (DBG) { Log.d(TAG, "Update shortcut IME to : " - + (mShortcutInfo == null ? "" : mShortcutInfo.getId()) + ", " + + (mShortcutInputMethodInfo == null + ? "" : mShortcutInputMethodInfo.getId()) + ", " + (mShortcutSubtype == null ? "" : (mShortcutSubtype.getLocale() + ", " + mShortcutSubtype.getMode()))); } @@ -289,10 +315,10 @@ public class SubtypeSwitcher { public void switchToShortcutIME() { final IBinder token = mService.getWindow().getWindow().getAttributes().token; - if (token == null || mShortcutInfo == null) { + if (token == null || mShortcutInputMethodInfo == null) { return; } - final String imiId = mShortcutInfo.getId(); + final String imiId = mShortcutInputMethodInfo.getId(); final InputMethodSubtype subtype = mShortcutSubtype; new Thread("SwitchToShortcutIME") { @Override @@ -303,7 +329,7 @@ public class SubtypeSwitcher { } public Drawable getShortcutIcon() { - return getSubtypeIcon(mShortcutInfo, mShortcutSubtype); + return getSubtypeIcon(mShortcutInputMethodInfo, mShortcutSubtype); } private Drawable getSubtypeIcon(InputMethodInfo imi, InputMethodSubtype subtype) { @@ -332,6 +358,38 @@ public class SubtypeSwitcher { return null; } + private static boolean contains(String[] hay, String needle) { + for (String element : hay) { + if (element.equals(needle)) + return true; + } + return false; + } + + public boolean isShortcutAvailable() { + if (mShortcutInputMethodInfo == null) + return false; + if (mShortcutSubtype != null && contains(mShortcutSubtype.getExtraValue().split(","), + SUBTYPE_EXTRAVALUE_REQUIRE_NETWORK_CONNECTIVITY)) { + return mIsNetworkConnected; + } + return true; + } + + private void onNetworkStateChanged(Intent intent) { + final boolean noConnection = intent.getBooleanExtra( + ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); + mIsNetworkConnected = !noConnection; + + final LatinKeyboardView inputView = KeyboardSwitcher.getInstance().getInputView(); + if (inputView != null) { + final LatinKeyboard keyboard = inputView.getLatinKeyboard(); + if (keyboard != null) { + keyboard.updateShortcutKey(isShortcutAvailable(), inputView); + } + } + } + ////////////////////////////////// // Language Switching functions // //////////////////////////////////